"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));

var _chai = require("chai");

var _get = _interopRequireDefault(require("lodash/get"));

var _constants = require("@instructure/quiz-common/lib/constants");

var _callHandlers = require("../callHandlers");

var fakeQuizSession = {
  id: 3,
  quiz: {
    id: 2,
    title: 'Chem 101 Exam 2'
  },
  quiz_session_results: [{
    id: 1,
    points_possible: 2,
    quiz_session_id: '55'
  }],
  resume_data: [{
    position: 2,
    user_response: 'resp'
  }],
  start_at: null,
  end_at: null,
  session_items: [{
    position: 2,
    item: {
      id: '47.0',
      interaction_type: {
        id: '1.0'
      },
      title: 'First Publisher of Modern PTE',
      interaction_choices: [{
        id: '165.0'
      }]
    }
  }]
};

var getPersistenceActionsCalled = function getPersistenceActionsCalled(actionType, nestedActionType, handler, fakeData, expectedIds, payloadKey) {
  var schemaValues = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : null;
  var runSchemaCheck = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : true;
  describe('getPersistenceActions', function () {
    context("works for ".concat(actionType, " and nest action type ").concat(nestedActionType), function () {
      it('sends the correct nested action', function () {
        var actions = handler(fakeData);
        var selectedAction = actions.find(function (action) {
          return action.type === nestedActionType;
        });
        (0, _chai.expect)(selectedAction).to.exist();
      });
      it('adds the right payload of nested objects to the store', function () {
        var actions = handler(fakeData);
        var selectedAction = actions.find(function (action) {
          return action.type === nestedActionType;
        });
        (0, _chai.expect)(selectedAction.payload.map(function (i) {
          return i.id;
        })).to.deep.equal(expectedIds);
      });
      it('converts the nested object to an array of objects', function () {
        var actions = handler(fakeData);
        var selectedAction = actions.find(function (action) {
          return action.type === nestedActionType;
        });
        (0, _chai.expect)(selectedAction.payload.map(function (o) {
          return o.id;
        })).to.deep.equal(expectedIds);
      });

      if (runSchemaCheck) {
        it('converts nested items to expected schema', function () {
          var actions = handler(fakeData);
          var selectedAction = actions.find(function (action) {
            return action.type === actionType;
          });
          var expected = schemaValues || expectedIds;
          (0, _chai.expect)(selectedAction.payload[0][payloadKey]).to.deep.equal(expected);
        });
      }
    });
  });
};

describe('Call Handlers', function () {
  var fakeItemsForRes = [{
    id: '2',
    title: 'someItem',
    interaction_type: {
      id: '1.0'
    }
  }, {
    id: '3',
    title: 'someItem2',
    interaction_type: {
      id: '2.0'
    }
  }, {
    id: '4',
    title: 'someItem3',
    interaction_type: {
      id: '3.0'
    }
  }];
  describe('singleObject responses', function () {
    var handledAsSingleObject = function handledAsSingleObject(actionType, handler, fakeData, lookup, payloadVal) {
      context("works for ".concat(actionType), function () {
        it('sends the correct action', function () {
          var actions = handler(fakeData);
          var selectedAction = actions.find(function (action) {
            return action.type === actionType;
          });
          (0, _chai.expect)(selectedAction).to.exist();
        });
        it('has the correct payload in the action', function () {
          var actions = handler(fakeData);
          var selectedAction = actions.find(function (action) {
            return action.type === actionType;
          });
          (0, _chai.expect)((0, _get.default)(selectedAction.payload[0], lookup)).to.be.equal(payloadVal);
        });
      });
    };

    describe('handleQuizResponse', function () {
      var fakeQuizApiRes = {
        id: '1',
        title: 'fake quiz',
        items: fakeItemsForRes
      };
      handledAsSingleObject(_constants.ADD_QUIZZES, _callHandlers.handleQuizResponse, fakeQuizApiRes, ['title'], 'fake quiz');
      getPersistenceActionsCalled(_constants.ADD_QUIZZES, _constants.ADD_ITEMS, _callHandlers.handleQuizResponse, fakeQuizApiRes, ['2', '3', '4'], 'items');
    });
    describe('handleBankResponse', function () {
      var bankResponse = {
        id: 1,
        name: 'bank name'
      };
      handledAsSingleObject(_constants.ADD_BANKS, _callHandlers.handleBankResponse, bankResponse, ['name'], 'bank name');
    });
    describe('handleShareBankResponse', function () {
      var sharedBankResponse = {
        id: '1',
        uuid: '1',
        bankId: '1',
        permission: _constants.CAN_EDIT
      };
      handledAsSingleObject(_constants.ADD_SHARED_BANKS, _callHandlers.handleShareBankResponse, sharedBankResponse, ['bankId'], '1');
    });
    describe('handleStimuliResponse', function () {
      var fakeStimuliForRes = [{
        id: '2',
        title: 'hello'
      }, {
        id: '3',
        title: 'there'
      }, {
        id: '4',
        title: 'world'
      }];
      it('adds a stimulus from a stimulus api response', function () {
        var actions = (0, _callHandlers.handleStimuliResponse)(fakeStimuliForRes);
        var selectedAction = actions.filter(function (action) {
          return action.type === _constants.ADD_STIMULI;
        })[0];
        (0, _chai.expect)(selectedAction.type).to.be.equal(_constants.ADD_STIMULI);
        (0, _chai.expect)(selectedAction.payload[0].title).to.be.equal('hello');
      });
    });
    describe('handleBankEntryResponse', function () {
      var bankEntryResponse = {
        id: 1,
        entry: {
          itemBody: 'nsjfan'
        }
      };
      handledAsSingleObject(_constants.ADD_BANK_ENTRIES, _callHandlers.handleBankEntryResponse, bankEntryResponse, ['entry', 'itemBody'], 'nsjfan');
    });
    describe('handleQuizSessionResponse', function () {
      handledAsSingleObject(_constants.ADD_QUIZ_SESSIONS, _callHandlers.handleQuizSessionResponse, fakeQuizSession, ['id'], 3);
      getPersistenceActionsCalled(_constants.ADD_QUIZ_SESSIONS, _constants.ADD_QUIZ_SESSION_RESULTS, _callHandlers.handleQuizSessionResponse, fakeQuizSession, [1], 'quizSessionResults');
      getPersistenceActionsCalled(_constants.ADD_QUIZ_SESSIONS, _constants.ADD_QUIZZES, _callHandlers.handleQuizSessionResponse, fakeQuizSession, [2], 'quiz', 2);
      it('excludes deprecated keys', function () {
        var actions = (0, _callHandlers.handleQuizSessionResponse)(fakeQuizSession);
        var selectedAction = actions.find(function (action) {
          return action.type === _constants.ADD_QUIZ_SESSIONS;
        });
        var deprecatedKeys = ['resumeData', 'sessionItems', 'sessionItemResponses'];
        deprecatedKeys.forEach(function (key) {
          (0, _chai.expect)(Object.keys(selectedAction.payload[0])).not.to.include(key);
        });
      });
    });
    describe('handleQuizEntryResponse', function () {
      var fakeQuizEntry = {
        entry: {
          id: '12'
        },
        entry_editable: true,
        entry_type: 'Item',
        id: '38',
        points_possible: 4,
        position: 2,
        properties: {},
        status: 'mutable',
        stimulus_quiz_entry_id: ''
      };
      handledAsSingleObject(_constants.ADD_QUIZ_ENTRY, _callHandlers.handleQuizEntryResponse, fakeQuizEntry, ['id'], '38');
      getPersistenceActionsCalled(_constants.ADD_QUIZ_ENTRY, _constants.ADD_ITEMS, _callHandlers.handleQuizEntryResponse, fakeQuizEntry, ['12'], null, null, false);
    });
  });
  describe('array responses', function () {
    var handledAsArrayResponse = function handledAsArrayResponse(actionType, handler, responseData, // this should be an array since some handlers take multiple params (payload always first)
    lookup, payloadVal) {
      it("creates an ".concat(actionType, " action"), function () {
        var actions = handler.apply(void 0, (0, _toConsumableArray2.default)(responseData));
        var selectedAction = actions.find(function (action) {
          return action.type === actionType;
        });
        (0, _chai.expect)(selectedAction).to.exist();
      });
      it("".concat(actionType, " has correct payload"), function () {
        var actions = handler.apply(void 0, (0, _toConsumableArray2.default)(responseData));
        var selectedAction = actions.find(function (action) {
          return action.type === actionType;
        });
        (0, _chai.expect)((0, _get.default)(selectedAction.payload[0], lookup)).to.equal(payloadVal);
      });
      it("".concat(actionType, " has correct number of objects in payload"), function () {
        var actions = handler.apply(void 0, (0, _toConsumableArray2.default)(responseData));
        var selectedAction = actions.find(function (action) {
          return action.type === actionType;
        });
        (0, _chai.expect)(selectedAction.payload.length).to.equal(responseData[0].length);
      });
    };

    describe('handleQtiImportsResponse', function () {
      var qtiResponse = [{
        id: 1,
        status: 'complete',
        parent_id: '2',
        parent_type: 'Quiz',
        message: 'some_msg'
      }];
      handledAsArrayResponse(_constants.ADD_QTI_IMPORTS, _callHandlers.handleQtiImportsResponse, [qtiResponse], ['message'], 'some_msg');
    });
    describe('handleInteractionTypesResponse', function () {
      var interactionTypesObjects = [{
        id: '2',
        hello: 'there'
      }, {
        id: '3'
      }];
      handledAsArrayResponse(_constants.ADD_INTERACTION_TYPES, _callHandlers.handleInteractionTypesResponse, [interactionTypesObjects], ['hello'], 'there');
    });
    describe('handleItemsResponse', function () {
      handledAsArrayResponse(_constants.ADD_ITEMS, _callHandlers.handleItemsResponse, [fakeItemsForRes], ['title'], 'someItem');
      getPersistenceActionsCalled(_constants.ADD_ITEMS, _constants.ADD_INTERACTION_TYPES, _callHandlers.handleItemsResponse, fakeItemsForRes, ['1.0', '2.0', '3.0'], 'interactionType', '1.0');
    });
    describe('sessionItem* responses', function () {
      var handledAsSessionItemType = function handledAsSessionItemType(actionType, handler, quizSessionId, requestData, expectedIds) {
        context('acts as a sessionItem* request', function () {
          it('adds quizSessionId and an id to each session item', function () {
            var actionsToDispatch = handler(requestData, quizSessionId);
            var action = actionsToDispatch.find(function (a) {
              return a.type === actionType;
            });
            var mappedIds = action.payload.map(function (si) {
              return si.id;
            });
            (0, _chai.expect)(mappedIds).to.deep.equal(expectedIds);
          });
          it('adds quiz_session_id to each session item', function () {
            var actionsToDispatch = handler(requestData, quizSessionId);
            var action = actionsToDispatch.find(function (a) {
              return a.type === actionType;
            });
            action.payload.forEach(function (si) {
              return (0, _chai.expect)(si.quizSessionId).to.eq(quizSessionId);
            });
          });
        });
      };

      var quizSessionId = '34';
      describe('handleSessionItemsResponse', function () {
        var sessionItemsData = [{
          position: 1,
          item: {
            id: '2',
            title: 'someItem',
            interaction_type: {
              id: '1.0'
            }
          }
        }, {
          position: 2,
          item: {
            id: '3',
            title: 'someItem',
            interaction_type: {
              id: '12.0'
            }
          }
        }];
        handledAsArrayResponse(_constants.ADD_SESSION_ITEMS, _callHandlers.handleSessionItemsResponse, [sessionItemsData, quizSessionId], ['position'], 1);
        getPersistenceActionsCalled(_constants.ADD_SESSION_ITEMS, _constants.ADD_INTERACTION_TYPES, _callHandlers.handleSessionItemsResponse, sessionItemsData, ['1.0', '12.0'], 'interactionType', null, false);
        handledAsSessionItemType(_constants.ADD_SESSION_ITEMS, _callHandlers.handleSessionItemsResponse, quizSessionId, sessionItemsData, ['34_1', '34_2']);
      });
      describe('handleSessionItemResultsResponse', function () {
        var sirResponseData = [{
          attempt: 1,
          position: 1,
          itemId: '2',
          gradedAt: 'Some Date',
          gradingMethod: 'Autograde',
          pointsPossible: 1
        }, {
          attempt: 1,
          position: 2,
          itemId: '3',
          gradedAt: 'Some Date',
          gradingMethod: 'Autograde',
          pointsPossible: 1
        }];
        handledAsArrayResponse(_constants.ADD_SESSION_ITEM_RESULTS, _callHandlers.handleSessionItemResultsResponse, [sirResponseData, quizSessionId], ['position'], 1);
        handledAsSessionItemType(_constants.ADD_SESSION_ITEM_RESULTS, _callHandlers.handleSessionItemResultsResponse, quizSessionId, sirResponseData, ['34_1', '34_2']);
      });
      describe('handleResumeDataResponse', function () {
        var resumeData = [{
          position: 1,
          itemId: '2',
          userResponse: {
            response: 'this is a response'
          }
        }, {
          position: 2,
          itemId: '3',
          userResponse: {
            response: 'this is a response2'
          }
        }];
        handledAsArrayResponse(_constants.LOAD_RESUME_DATA, _callHandlers.handleResumeDataResponse, [resumeData, quizSessionId], ['position'], 1);
        handledAsSessionItemType(_constants.LOAD_RESUME_DATA, _callHandlers.handleResumeDataResponse, quizSessionId, resumeData, ['34_1', '34_2']);
      });
    }); // TODO: use the shared examples on these tests below

    describe('handleQuizSessionResultsResponse', function () {
      var fakeAuthoritativeResultRes = {
        id: 1,
        pointsPossible: 2,
        quizSessionId: '55'
      };
      it('adds the authoritative result', function () {
        var actions = (0, _callHandlers.handleQuizSessionResultsResponse)(fakeQuizSession.quiz_session_results);
        var resultToPersist = actions[0].payload[0];
        (0, _chai.expect)(resultToPersist).to.be.deep.equal(fakeAuthoritativeResultRes);
      });
    });
    describe('handleBanksResponse', function () {
      var banksResponse = [{
        id: 1,
        name: 'bank name'
      }];
      it('adds banks from response', function () {
        var actions = (0, _callHandlers.handleBanksResponse)(banksResponse);
        (0, _chai.expect)(actions[0].type).to.be.equal(_constants.ADD_BANKS);
        (0, _chai.expect)(actions[0].payload[0].name).to.be.equal('bank name');
      });
    });
    describe('handleBankEntriesResponse', function () {
      var bankEntriesResponse = [{
        id: 1,
        entry: {
          itemBody: 'nsjfan'
        }
      }];
      it('adds entries from response', function () {
        var actions = (0, _callHandlers.handleBankEntriesResponse)(bankEntriesResponse);
        (0, _chai.expect)(actions[0].type).to.be.equal(_constants.ADD_BANK_ENTRIES);
        (0, _chai.expect)(actions[0].payload[0].entry.itemBody).to.be.equal('nsjfan');
      });
    });
    describe('handleQuizSessionEventsResponse', function () {
      it('parses event data properly', function () {
        var quizSessionEventsRes = [{
          created_at: '2016-09-28T18:45:27.700Z|232982772',
          event_type: 'RESPONSE',
          event_data: {
            item_id: '46',
            position: '1.0',
            user_response: {
              value: '460202cc-feb7-4cf6-b000-34d9ee6535f2'
            }
          },
          quiz_session_id: '12'
        }, {
          created_at: '2016-09-28T18:45:28.104Z|636885914',
          event_type: 'RESPONSE',
          event_data: {
            item_id: '46',
            position: '1.0',
            user_response: {
              value: '5f68cc77-5d8a-4807-a85a-4080616b3acc'
            }
          },
          quiz_session_id: '12'
        }];
        var actions = (0, _callHandlers.handleQuizSessionEventsResponse)(quizSessionEventsRes);
        (0, _chai.expect)(actions[0].type).to.be.equal(_constants.ADD_QUIZ_SESSION_EVENTS);
        (0, _chai.expect)(actions[0].payload[0].eventType).to.be.equal('RESPONSE');
      });
    });
  });
});