FromPromiseScenario is a Module Scenario that allows you to test all of the business requirements of a given module, function, or section of code. You should use this module when your entry point function returns a Promise. Any promise library following the standard A+ specification will work with Maddox.

We saw with the HttpRequestScenario, that it was able to test the response itself. This isn't possible with Module Scenarios. With the Module Scenarios, you will need to provide a function to test the results yourself. You do this by passing your function into the .test function. You can see an example of this below.

const Maddox = require("maddox");

const Scenario = Maddox.scenarios.FromPromiseScenario;

describe("When testing a function that uses a callback.", () => {

  let context;

  beforeEach(() => {
    context = {};

    context.setupEntryPoint = () => {
      context.entryPointObject = MyModule; // The entry point of our module.
      context.entryPointFunction = "entryPoint";
    };

    context.setupInputParams = () => {
      context.inputParams = {
        dataToSave: {foo: "foo"}
      };
    };

    context.setupDbProxy = () => {
      // When reusing parameters it is best practice to copy them to ensure the referenced data changes are not causing...
      // unexpected errors in your tests.  Maddox will do this for you, but it is good to make it obvious in your test.
      context.dbProxyParams = JSON.parse(JSON.stringify(context.inputParams));
      context.dbProxyResponse = {code: 200};
    };

    context.setupExpected = () => {
      context.expectedResponse = {success: true};
      context.expectedStatusCode = 200;
    };
  });

  it("it should send data to the database.", function (done) {

    context.setupEntryPoint();
    context.setupInputParams();
    context.setupDbProxy();
    context.setupExpected();

    new Scenario(this)
      .mockThisFunction("DbProxy", "save", DbProxy)

      .withEntryPoint(context.entryPointObject, context.entryPointFunction)
      .withInputParams([context.inputParams])

      .shouldBeCalledWith("DbProxy", "save", [context.dbProxyParams])
      .doesReturnWithPromise("DbProxy", "save", context.dbProxyResponse)
      
      .test(function (err, response) {
      	Maddox.compare.shouldEqual({actual: err, expected: undefined});
        Maddox.compare.shouldEqual({actual: response, expected: testContext.expectedResponse});
        done();
      }).catch(function (err) {
        done(err);
      });
  });

  it("it should process the error from the database.", function (done) {

    context.setupDbProxy = () => {
      const dbError = new Error("Failed to save data.");

      dbError.code = 12345;

      // When reusing parameters it is best practice to copy them to ensure the referenced data changes are not causing...
      // unexpected errors in your tests.  Maddox will do this for you, but it is good to make it obvious in your test.
      context.dbProxyParams = JSON.parse(JSON.stringify(context.inputParams));
      context.dbProxyResponse = dbError;
    };

    // Let's pretend that our code returns the error code from the db in our response when the database fails.
    context.setupExpected = () => {
      context.expectedResponse = {success: true, code: 12345};
      context.expectedStatusCode = 500;
    };

    context.setupEntryPoint();
    context.setupInputParams();
    context.setupDbProxy();
    context.setupExpected();

    new Scenario(this)
      .mockThisFunction("DbProxy", "save", DbProxy)

      .withEntryPoint(context.entryPointObject, context.entryPointFunction)
      .withInputParams([context.inputParams])

      // Notice that we have changed this to "doesErrorWithPromise" instead of "doesReturnWithPromise"...
      // since we are testing a scenario for the DbProxy to error.
      .shouldBeCalledWith("DbProxy", "save", [context.dbProxyParams])
      .doesErrorWithPromise("DbProxy", "save", context.dbProxyResponse)
      
      .test(function (err, response) {
      	Maddox.compare.shouldEqual({actual: err, expected: undefined});
        Maddox.compare.shouldEqual({actual: response, expected: testContext.expectedResponse});
        done();
      }).catch(function (err) {
        done(err);
      });
  });
});