"use strict";

const specHelper = require("../../support/specHelper"),
      stripeController = require("../../../controllers/stripeController"),
      models = specHelper.models,
      Invoice = models.Invoice,
      sinon = specHelper.sinon,
      Q = specHelper.Q,
      logger = specHelper.logger,
      moment = require('moment');

var invoiceService = require("../../../services/invoiceService");

describe('invoiceService', () => {

  describe("createInvoice", () => {

    let invoiceStub, loggerStub,
        newInvoice, expectedNewInvoice,
        invoicePromise;

    beforeEach(() => {
        invoiceStub = sinon.stub(models.Invoice, 'create');
        loggerStub = sinon.stub(logger, 'logNewInvoiceEvent');

        newInvoice = {
          memberEmail: "sherlock@holmes.co.uk",
          totalAmount: 60,
          paymentType: 'deposit',
        };

        expectedNewInvoice = {
          memberEmail: "sherlock@holmes.co.uk",
          totalAmountInCents: 6000,
          paymentDate: moment().format('L'),
          paymentType: 'deposit',
          reference: ''
        };

        invoicePromise = Q.defer();
        invoiceStub.returns(invoicePromise.promise);
    });

    afterEach(() => {
        models.Invoice.create.restore();
        loggerStub.restore();
    });

    it("creates a new invoice", (done) => {
        invoicePromise.resolve();

        invoiceService.createInvoice(newInvoice)
            .then(() => {
                expect(Invoice.create).toHaveBeenCalledWith(expectedNewInvoice);
            }).nodeify(done);
    });

    it("logs the invoice creation event", (done) => {
        invoicePromise.resolve();

        invoiceService.createInvoice(newInvoice)
            .then(() => {
                expect(logger.logNewInvoiceEvent).toHaveBeenCalledWith(newInvoice);
            }).nodeify(done);
    });

    describe("an error when saving the invoice to the database", () => {
        it("rejects the promise", (done) => {
            let errorMessage = "Seriously, we still don't have any damn bananas.";
            invoicePromise.reject(errorMessage);

            let promise = invoiceService.createInvoice(newInvoice);

            promise.finally(() => {
                expect(promise.isRejected()).toBe(true);
                done();
            });
        });
    });
  });

    describe("Charge card", () => {
        let stripeControllerStub, stripeChargePromise,
            stripeToken="47", totalAmount = 123,
            loggerStub;

        beforeEach(() => {
            stripeControllerStub = sinon.stub(stripeController, "chargeCard");
            stripeChargePromise = Q.defer();
            stripeControllerStub.returns(stripeChargePromise.promise);

            loggerStub = sinon.stub(logger, 'logNewChargeEvent');
        });

        afterEach(() => {
            stripeController.chargeCard.restore();
            loggerStub.restore();
        });

        it("After charge, logger should log", (done) => {
            stripeChargePromise.resolve();

            let promise = invoiceService.chargeCard(stripeToken, totalAmount);

            promise.finally(() => {
                expect(logger.logNewChargeEvent).toHaveBeenCalledWith(stripeToken);
                done();
            });
        });

        it("If charge card fails, logger should still log", (done) => {
            stripeChargePromise.reject();

            let promise = invoiceService.chargeCard(stripeToken, totalAmount);

            promise.finally(() => {
                expect(logger.logNewChargeEvent).toHaveBeenCalledWith(stripeToken);
                done();
            });
        });
    });
});

@@ -433,16 +433,1624 @@
 ) =%3E %7B%0A%0A
+    describe(%22Stripe%22, () =%3E %7B%0A%0A      let loggerStub, createStub,%0A          stripeToken, totalAmount,%0A          expectedNewCharge, createPromise,%0A          stripe;%0A%0A      beforeEach(() =%3E %7B%0A        createStub = sinon.stub();%0A%0A        stripe = require(%22stripe%22);%0A        sinon.stub(stripe, 'Stripe')%0A            .returns(%7Bcharges: %7Bcreate: createStub%7D%7D);%0A%0A        loggerStub = sinon.stub(logger, 'logNewChargeEvent');%0A%0A        //re-load invoice service to using the stubs above.%0A        invoiceService = require(%22../../../services/invoiceService%22);%0A%0A        stripeToken = %22stripe_token%22;%0A        totalAmount = 60;%0A        expectedNewCharge = %7B%0A              amount: 6000,%0A              currency: %22aud%22,%0A              source: %22stripe_token%22,%0A              description: %22Example charge%22%0A            %7D%0A%0A        createPromise = Q.defer();%0A        createStub.returns(createPromise.promise);%0A      %7D);%0A%0A      afterEach(() =%3E %7B%0A          stripe.Stripe.restore();%0A          loggerStub.restore();%0A      %7D);%0A%0A      it(%22Charge Credit Card%22, (done) =%3E %7B%0A          createPromise.resolve();%0A%0A          invoiceService.chargeCard(stripeToken, totalAmount)%0A              .then(() =%3E %7B%0A                  expect(createStub).toHaveBeenCalledWith(expectedNewCharge);%0A              %7D).nodeify(done);%0A      %7D);%0A%0A      it(%22logs the invoice creation event%22, (done) =%3E %7B%0A          createPromise.resolve();%0A%0A          invoiceService.chargeCard(stripeToken, totalAmount)%0A              .then(() =%3E %7B%0A                  expect(logger.logNewChargeEvent).toHaveBeenCalledWith(stripeToken);%0A              %7D).nodeify(done);%0A      %7D);%0A%0A    %7D);%0A%0A
   descri

add unit test for charge card service