import './watcher.js'; import getModifiedData from '../lib/modified'; describe('Component vnWatcher', () => { let $componentController; let $scope; let $element; let $state; let $transitions; let $httpBackend; let vnApp; let $translate; beforeEach(() => { angular.mock.module('client'); }); beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$state_, _$transitions_, _$httpBackend_, _vnApp_, _$translate_) => { $componentController = _$componentController_; $scope = $rootScope.$new(); $element = angular.element('
'); $state = _$state_; vnApp = _vnApp_; $transitions = _$transitions_; $httpBackend = _$httpBackend_; $translate = _$translate_; })); describe('$onInit()', () => { it(`should call fetchData() if controllers get and url properties are defined`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); controller.get = () => {}; controller.url = 'test.com'; spyOn(controller, 'fetchData'); controller.$onInit(); expect(controller.fetchData).toHaveBeenCalledWith(); }); it(`should throw an error if $onInit is called without url defined`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); controller.get = () => {}; expect(function() { controller.$onInit(); }).toThrow(new Error('Error: Parameter url ommitted')); }); }); describe('$onChanges()', () => { it(`should call updateOriginalData() if controllers data is defined`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); controller.data = []; spyOn(controller, 'updateOriginalData'); controller.$onChanges(); expect(controller.updateOriginalData).toHaveBeenCalledWith(); }); }); describe('$onDestroy()', () => { it(`should call deregisterCallback()`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); spyOn(controller, 'deregisterCallback'); controller.$onDestroy(); expect(controller.deregisterCallback).toHaveBeenCalledWith(); }); }); describe('fetchData()', () => { it(`should perform a query then store the received data into controller.data and call updateOriginalData()`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); spyOn(controller, 'updateOriginalData'); let json = {data: 'some data'}; controller.data = [1]; controller.idField = 0; controller.url = 'test.com'; $httpBackend.whenGET('test.com/1').respond(json); $httpBackend.expectGET('test.com/1'); controller.fetchData(); $httpBackend.flush(); expect(controller.data).toEqual({data: 'some data'}); expect(controller.updateOriginalData).toHaveBeenCalledWith(); }); }); describe('submitBack()', () => { it(`should call controller.window.history.back() function after calling controllers submit() function`, done => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); spyOn(controller, 'submit').and.returnValue(Promise.resolve()); spyOn(controller.window.history, 'back'); controller.submitBack() .then(() => { expect(controller.submit).toHaveBeenCalledWith(); expect(controller.window.history.back).toHaveBeenCalledWith(); done(); }); }); }); describe('submitGo()', () => { it(`should call controller.$state.go() function after calling controllers submit() function`, done => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); spyOn(controller, 'submit').and.returnValue(Promise.resolve()); spyOn(controller.$state, 'go'); let state = 'the state'; controller.submitGo(state) .then(() => { expect(controller.submit).toHaveBeenCalledWith(); expect(controller.$state.go).toHaveBeenCalledWith(state); done(); }); }); }); describe('submit()', () => { describe('when controller.form', () => { it(`should call controller.form.setSubminted if controller.form is defined`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); controller.form = {$setSubmitted: () => {}}; spyOn(controller.form, '$setSubmitted'); controller.submit(); expect(controller.form.$setSubmitted).toHaveBeenCalledWith(); }); it(`should call controller.invalidForm if controller.form.$valid is not defined`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); controller.form = {$setSubmitted: () => {}}; spyOn(controller, 'invalidForm'); controller.submit(); expect(controller.invalidForm).toHaveBeenCalledWith(jasmine.any(Function)); }); }); describe('when !controller.dataChanged()', () => { it(`should call controller.noChanges()`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); spyOn(controller, 'noChanges'); controller.submit(); expect(controller.noChanges).toHaveBeenCalledWith(jasmine.any(Function)); }); }); describe('when controller.save()', () => { it(`should set controller.save.model property`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); controller.save = {}; controller.data = {originalInfo: 'original data', info: 'new data'}; controller.orgData = {originalInfo: 'original data'}; controller.submit(); expect(controller.save.model).toEqual({info: 'new data'}); }); it(`should call controller.save.accept() then controller.writeData`, done => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); controller.save = {accept: () => {}}; controller.data = {originalInfo: 'original data', info: 'new data'}; controller.orgData = {originalInfo: 'original data'}; spyOn(controller.save, 'accept').and.returnValue(Promise.resolve()); spyOn(controller, 'writeData').and.callThrough(); controller.submit() .then(() => { expect(controller.save.accept).toHaveBeenCalledWith(); expect(controller.writeData).toHaveBeenCalledWith(jasmine.any(Object), jasmine.any(Function)); done(); }); }); }); describe('when id is defined', () => { it(`should perform a query then call controller.writeData()`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}, {dataChanged: () => { return true; }}); controller.data = {id: 2}; controller.orgData = {id: 1}; let changedData = getModifiedData(controller.data, controller.orgData); controller.idField = 'id'; controller.url = 'test.com'; let json = {data: 'some data'}; spyOn(controller, 'writeData').and.callThrough(); $httpBackend.whenPATCH(`${controller.url}/1`, changedData).respond(json); $httpBackend.expectPATCH(`${controller.url}/1`); controller.submit() .then(() => { expect(controller.writeData).toHaveBeenCalledWith(jasmine.any(Object), jasmine.any(Function)); done(); }); $httpBackend.flush(); }); }); it(`should perform a POST query then call controller.writeData()`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}, {dataChanged: () => { return true; }}); controller.data = {id: 2}; controller.orgData = {id: 1}; controller.url = 'test.com'; let json = {data: 'some data'}; spyOn(controller, 'writeData').and.callThrough(); $httpBackend.whenPOST(`${controller.url}`, controller.data).respond(json); $httpBackend.expectPOST(`${controller.url}`, controller.data); controller.submit() .then(() => { expect(controller.writeData).toHaveBeenCalledWith(jasmine.any(Object), jasmine.any(Function)); done(); }); $httpBackend.flush(); }); }); describe('writeData()', () => { it(`should call Object.asssign() function over controllers.data with json.data, then call updateOriginalData function and finally call resolve() function`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); spyOn(controller, 'updateOriginalData'); controller.data = {}; let json = {data: 'some data'}; let resolve = jasmine.createSpy('resolve'); controller.writeData(json, resolve); expect(controller.updateOriginalData).toHaveBeenCalledWith(); expect(resolve).toHaveBeenCalledWith(json); }); }); describe('copyInNewObject()', () => { it(`should return newCopy object if data was an object`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); let data = {id: 1, Heroname: 'Batman', name: 'Bruce Wayne'}; let result = controller.copyInNewObject(data); expect(result).toEqual(data); }); }); describe('callback()', () => { describe(`when dataChanged() returns true and there's no state in the controller`, () => { it(`should define controller.state, call controller.$scope.confirm.show() and return false`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); $scope.confirm = {show: jasmine.createSpy('show')}; controller.dataChanged = () => { return true; }; controller.state = undefined; let transition = {to: () => { return {name: 'Batman'}; }}; let result = controller.callback(transition); expect(controller.state).toEqual('Batman'); expect(controller.$scope.confirm.show).toHaveBeenCalledWith(); expect(result).toBeFalsy(); }); }); describe(`when dataChanged() returns false and/or there's a state in the controller`, () => { it(`should return true`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); $scope.confirm = {show: jasmine.createSpy('show')}; controller.dataChanged = () => { return false; }; controller.state = 'the state'; let transition = {to: () => { return {name: 'Batman'}; }}; let result = controller.callback(transition); expect(result).toBeTruthy(); }); }); }); describe(`onConfirmResponse()`, () => { describe(`when response is ACCEPT`, () => { it(`should call Object.assing on controlle.data with controller.orgData then call go() on state`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); let response = 'ACCEPT'; controller.data = {}; controller.orgData = {name: 'Batman'}; controller.$state = {go: jasmine.createSpy('go')}; controller.state = 'Batman'; controller.onConfirmResponse(response); expect(controller.data).toEqual(controller.orgData); expect(controller.$state.go).toHaveBeenCalledWith(controller.state); }); }); describe(`when response is not ACCEPT`, () => { it(`should set controller.state to null`, () => { let controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate}); let response = 'anything but ACCEPT'; controller.state = 'Batman'; controller.onConfirmResponse(response); expect(controller.state).toBeFalsy(); }); }); }); });