Need help completing unit test for angular $modal - angularjs

I am trying to get the "make sure modalInstance.result.then is executed" test in my code to pass. Right now it says Expected [ undefined, 'http://www.link1.com', 'http://www.link2.com', 'http://www.link3.com' ] to contain 'http://www.pressboardmedia.com' I believe this has something to do with the promise needing to be mocked so it passes along the campaignLink but I am unsure if this is the problem and cannot seem to get it to work regardless. please let know if you have any ideas.
Thanks!
Controller File
angular.module('pb.campaignLinks.controllers')
.controller('CampaignLinksController', ['$scope', '$timeout', '$modal', '$stateParams', 'global', 'campaignLinkService', function ($scope, $timeout, $modal, $stateParams, global, campaignLinkService) {
$scope.init = function (currentView) {
$scope.partialViews = {
campaignLinkList: "/app/campaignLinks/views/_list.html",
};
$scope.currentView = currentView;
$scope.getCampaignLinks(currentView, 10);
};
$scope.getCampaignLinks = function (currentView, length, continuationToken) {
// When loading list items, display loading image
if ($scope.campaignLinks) $scope.campaignLinks.loading = true;
var promiseObj = null;
if (currentView.campaignId && currentView.campaignId !== 0 && !currentView.buyRequestId) {
promiseObj = campaignLinkService.getCampaignLinks(global.activeOrganizationId, currentView.campaignId, length, continuationToken)
} else if (currentView.campaignId && currentView.buyRequestId && currentView.campaignId !== 0 && currentView.buyRequestId !== '') {
promiseObj = campaignLinkService.getCampaignBuyRequestLinks(global.activeOrganizationId, currentView.campaignId, currentView.buyRequestId, length, continuationToken);
} else if (currentView.webSiteId && currentView.buyRequestId && currentView.webSiteId !== 0 && currentView.buyRequestId !== '') {
promiseObj = campaignLinkService.getWebSiteBuyRequestLinks(global.activeOrganizationId, currentView.webSiteId, currentView.buyRequestId, length, continuationToken);
}
if (promiseObj) {
promiseObj.then(function (data) {
// If there are already some campaign links being displayed, add newly loaded list to the end
if ($scope.campaignLinks) {
$scope.campaignLinks.continuationToken = data.continuationToken;
$scope.campaignLinks.total += data.total;
$.each(data.items, function (index) {
$scope.campaignLinks.items.push(data.items[index]);
});
} else {
// Otherwise add loaded list to scope
$scope.campaignLinks = data;
}
// When done loading, hide loading image
$scope.campaignLinks.loading = false;
});
}
};
$scope.openAddCampaignLink = function (campaignId) {
var modalOptions = {
templateUrl: '/app/campaignLinks/views/_add.html',
controller: 'AddCampaignLinksModalController',
resolve: {
campaignId: function () {
return campaignId;
}
}
};
var modalInstance = $modal.open(modalOptions);
modalInstance.result.then(function (campaignLink) {
// Add new item to list, otherwise wait for it to be loaded manually.
$scope.campaignLinks.items.unshift(campaignLink);
$scope.campaignLinks.total += 1;
}, function () {
console.log('Modal dismissed at: ' + new Date());
});
};
$scope.openRemoveCampaignLink = function (campaignId, campaignLink, index) {
var modalOptions = {
templateUrl: '/app/campaignLinks/views/_delete.html',
controller: 'RemoveCampaignLinksModalController',
resolve: {
campaignId: function () {
return campaignId;
},
campaignLink: function () {
return campaignLink;
}
}
};
var modalInstance = $modal.open(modalOptions);
modalInstance.result.then(function () {
// Splice the deleted item from the list without reloading all
$scope.campaignLinks.items.splice(index, 1);
$scope.campaignLinks.total -= 1;
}, function () {
console.log('Modal dismissed at: ' + new Date());
});
};
// Once everything is loaded, initialize controller
// init();
}]);
Test file:
describe('CampaignLinksController', function () {
//make module avalible to tests
beforeEach(module('pb.campaignLinks.controllers'));
beforeEach(module('ui.router'));
beforeEach(module('ui.bootstrap'));
var $controller;
var mockPromiseObj;
var length = 200;
var mockModal = {};
var mockCampaignLinks = {
total: 3,
items: ['http://www.link1.com', 'http://www.link2.com', 'http://www.link3.com']
};
var mockCurrentView = {};
var mockGlobal = { activeOrganizationId: 54 };
var continuationToken = {
nextRowKey: 'fdsf2',
nextPartitionKey: '5432gee'
};
var campaignDetails = {
campaignId: 453,
campaignLink: 'http://www.pressboardmedia.com',
index: 1
};
var mockCampaignLinkService = {
//move campaignDetails here
campaignLinks: {
total: 3,
//length here
items: ['http://www.link1.com', 'http://www.link2.com', 'http://www.link3.com']
},
//all but delete must return a promiseObj
getCampaignLinks: jasmine.createSpy('mockCampaignLinkService.getCampaignLinks').and.returnValue(mockPromiseObj),
getCampaignBuyRequestLinks: jasmine.createSpy('mockCampaignLinkService.getCampaignBuyRequestLinks').and.returnValue(mockPromiseObj),
getWebSiteBuyRequestLinks: jasmine.createSpy('mockCampaignLinkService.getWebSiteBuyRequestLinks').and.returnValue(mockPromiseObj),
deleteCampaignLink: jasmine.createSpy('mockCampaignLinkService.deleteCampaignLinks')
};
beforeEach(inject(function (_$controller_) {
$controller = _$controller_;
}));
beforeEach(inject(function ($rootScope) {
controller = $controller('CampaignLinksController',
{
$scope: scope,
$modal: mockModal,
//$stateParams: mockStateParams,
global: mockGlobal,
campaignLinks: mockCampaignLinks,
campaignLinkService: mockCampaignLinkService,
currentVeiw: mockCurrentView,
//promiseObj: mockPromiseObj
});
}));
describe('openAddCampaignLink()', function () {
var actualOptions;
var modalOptions = {
templateUrl: '/app/campaignLinks/views/_add.html',
controller: 'AddCampaignLinksModalController',
resolve: {
campaignId: jasmine.any(Function)
}
};
beforeEach(inject(function ($q) {
mockModal.open = function (options) {
actualOptions = options;
var defer = $q.defer();
defer.resolve();
return { result: defer.promise };
}
}));
it("make sure modalInstance.result.then is executed", function () {
scope.campaignLinks = mockCampaignLinkService.campaignLinks;
scope.openAddCampaignLink(campaignDetails.campaignId, campaignDetails.campaignLink, campaignDetails.index);
scope.$digest();
expect(scope.campaignLinks.total).toEqual(4);
expect(scope.campaignLinks.items).toContain(campaignDetails.campaignLink);
});
});

I think your problem is that the argument "campaignLink" that is supplied to your modalInstance.result.then function will always be undefined when you test this. The code that calls the modal close should be tested that it is supplying the campaignLink correctly. You only want to test that the proper code gets executed when the modal is closed. We do that by supplying a function that can be tested on it's own to the modalInstance.result.then call instead of doing an inline function so it can be tested easier.
Here's an example:
Here's the code that opens the modal:
$scope.editGradeClick = function () {
var modalInstance = $modal.open({
templateUrl: templateSrv.templateUrl('/Templates/App/Courses/CourseLessonGradeModal.html'),
controller: courseLessonGradeModalBootstrap,
backdrop: 'static',
keyboard: false,
resolve: {
data: $scope.editGradeModalResolve
}
});
modalInstance.result.then(
null,
$scope.editGradeModalDismissCallback
);
};
Notice how we supply a function $scope.editGradeModalDismissCallback instead of writting an inline function there for a modal dismiss. This allows us to test that logic in it's own test.
Now here is the test. We only care that the above function was called since we will be testing the specific function in it's own test. That happens at the last line in the test.
var $controllerConstructor, $scope, $q;
beforeEach(function () {
module('appModule');
inject(function ($controller, $rootScope, _$q_) {
$controllerConstructor = $controller;
$scope = $rootScope.$new();
$q = _$q_;
});
});
it('should execute $scope.editGradeModalDismissCallback when modal is dismissed', inject(function (templateSrv) {
var $modal = {};
$modal.open = function () {
var queryPromise = $q.defer();
queryPromise.reject();
return { result: queryPromise.promise };
};
$controllerConstructor('CourseLessonGradeListCtrl', { $scope: $scope, $modal: $modal, templateSrv: templateSrv});
spyOn($modal, "open").andCallThrough();
spyOn($scope, "editGradeModalDismissCallback");
$scope.editGradeClick();
$scope.$root.$digest();
expect($scope.editGradeModalDismissCallback).toHaveBeenCalled();
}));
I hope this helps you. In this example we are rejecting the promise because we are testing the modal dismiss not close, fyi...

Related

How to call MVC Web API Controller after AngularJS popup completes

I have an AngularJS module with code that calls a modal popup. I also have code that calls an MVC Web API controller method. Both of these functions work independently of one another right now. What I would like to happen is after the user clicks the OK button on the modal, I want to get the value of the modal text box and send it to the API controller as a parameter. The code I have so far is below:
app.js:
(function () {
'use strict';
var app = angular.module("CRNApp", ['ui.bootstrap','trNgGrid']);
var MainController = function ($scope, $http, $log, $uibModal) {
$scope.showGrid = false;
$scope.showPolicyScreen = false;
$scope.CRNViewModel = {
policyId: 0
};
$scope.openPolicyId = function () {
$uibModal.open({
templateUrl: 'templates/popupGetPolicy.cshtml',
backdrop: false,
windowClass: 'modal',
controller: function ($scope, $uibModalInstance, $log, CRNViewModel) {
$scope.CRNViewModel = CRNViewModel;
$scope.submit = function () {
}
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
},
resolve: { CRNViewModel: function () { return $scope.CRNViewModel; } }
});//end of modal.open
}; // end of scope.open fu
$scope.policyLookup = function (policyNumber) {
$scope.loading = true;
$scope.CRNViewModel.policyId = policyNumber; //"WCZ25999"
$http.post("/api/Policy"
, $scope.CRNViewModel
, { header: { 'Content-Type': 'application/json' } })
.then(function (response) {
$scope.policy = response.data;
$scope.loading = false;
$scope.showGrid = false;
$scope.showPolicyScreen = true;
})
.catch(function (error) {
console.log(error);
$scope.loading = false;
$scope.showGrid = false;
});
};
};
app.controller("MainController", MainController);
}());
The MVC API Controller method:
// POST: api/Policy
public IHttpActionResult Post([FromBody]CRNViewModel policy)
{
CRNViewModel _crnVM = new CRNViewModel();
IConditionalRenewalNotices _crn = new ConditionalRenewalNoticesRepository();
_crnVM = _crn.GetPolicyByPolicyId(policy.PolicyId);
return Json(_crnVM);
}
Return the textbox value when you close the $uibModalInstance instance and then add a callback for the modal result:
var modal = $uibModal.open({
templateUrl: 'templates/popupGetPolicy.cshtml',
backdrop: false,
windowClass: 'modal',
controller: function($scope, $uibModalInstance, $log, CRNViewModel) {
$scope.CRNViewModel = CRNViewModel;
$scope.submit = function () {
// pass in the value you want to return
$uibModalInstance.close('WCZ25999');
}
$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
},
resolve: { CRNViewModel: function() { return $scope.CRNViewModel; } }
});
modal.result.then(function (value) {
$scope.policyLookup(value);
});

adding several functions to one controller angular

Im trying to add another function to my controller but it keeps breaking the controller.
here is my code:
.controller('ClimbController', [
'$scope', '$stateParams', 'Climbs', function(
$scope, $stateParams, Climbs) {
var climb_id = $stateParams.climbId;
var areaId = $stateParams.areaId;
if (!isNaN(climb_id)) {
climb_id = parseInt(climb_id);
}
if (!isNaN(areaId)) {
areaId = parseInt(areaId);
}
$scope.selected_ = {};
$scope.items = [];
$scope.details = true;
// looping though all data and get particular product
$scope.selectClimb = function(areas){
areas.forEach(function(data) {
if(data._id == climb_id){
$scope.selected_ = data;
}
});
}
// get all posts // try some function to get a single produt from server
$scope.getPosts = function(){
Climbs.getPosts()
.success(function (data) {
// data = feed.json file
var climbs = [];
data.areas.map(function(area) {
if (area._id === areaId) {
climbs = area.climbs;
}
});
$scope.selectClimb(climbs);
})
.error(function (error) {
$scope.items = [];
});
}
$scope.getPosts();
}
])
And I ned to add this to it:
.controller('MyCtrl', function($scope, $ionicModal) {
$ionicModal.fromTemplateUrl('test-modal.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.openModal = function() {
$scope.modal.show();
};
$scope.closeModal = function() {
$scope.modal.hide();
};
//Cleanup the modal when we're done with it!
$scope.$on('$destroy', function() {
$scope.modal.remove();
});
// Execute action on hide modal
$scope.$on('modal.hidden', function() {
// Execute action
});
// Execute action on remove modal
$scope.$on('modal.removed', function() {
// Execute action
});
});
When I try to add this to the code it breaks it. I nee to either add it as another function or whatever is needed to add it to the code.
Thanks so much
Assuming that you want to merge 'MyCtrl functions into ClimbController then
.controller('ClimbController', ['$scope', '$stateParams', 'Climbs','$ionicModal', function($scope, $stateParams, Climbs,$ionicModal) {
var climb_id = $stateParams.climbId;
var areaId = $stateParams.areaId;
if (!isNaN(climb_id)) {
climb_id = parseInt(climb_id);
}
if (!isNaN(areaId)) {
areaId = parseInt(areaId);
}
$scope.selected_ = {};
$scope.items = [];
$scope.details = true;
// looping though all data and get particular product
$scope.selectClimb = function(areas){
areas.forEach(function(data) {
if(data._id == climb_id){
$scope.selected_ = data;
}
});
}
// get all posts // try some function to get a single produt from server
$scope.getPosts = function(){
Climbs.getPosts()
.success(function (data) {
// data = feed.json file
var climbs = [];
data.areas.map(function(area) {
if (area._id === areaId) {
climbs = area.climbs;
}
});
$scope.selectClimb(climbs);
})
.error(function (error) {
$scope.items = [];
});
}
$scope.getPosts();
$ionicModal.fromTemplateUrl('test-modal.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.openModal = function() {
$scope.modal.show();
};
$scope.closeModal = function() {
$scope.modal.hide();
};
//Cleanup the modal when we're done with it!
$scope.$on('$destroy', function() {
$scope.modal.remove();
});
// Execute action on hide modal
$scope.$on('modal.hidden', function() {
// Execute action
});
// Execute action on remove modal
$scope.$on('modal.removed', function() {
// Execute action
});
}])

karma test returning validateAmount is not a function

I'm trying to test scope function which will check due amount, but while running the test I'm getting validateAmount is not a function.
app.js
var ManagmentApp = angular.module("ManagemntApp", ['ngRoute', 'angularModalService', 'ng-fusioncharts']);
ManagmentApp.config(['$routeProvider', function ($routeProvider){
$routeProvider.when('/', {
templateUrl: 'templates/CandidateForm.html',
controller: 'cntrlrCandidate'
}).when('/CandidateList',{
templateUrl: 'templates/CandidateList.html',
controller: 'cntrlrCandidateList'
}).when('/CandidatesProfile', {
templateUrl: 'templates/CandidateProfiles.html',
controller: 'cntrlrCandidateProfile'
}).when('/HostelStatistics', {
templateUrl: 'templates/HostelStatistics.html',
controller: 'cntrlHostelStatistics'
}).when('/:id', {
templateUrl: 'templates/CandidateForm.html',
controller: 'cntrlrCandidate'
});
}]);
cntrlrCandidate.js
ManagmentApp.controller("cntrlrCandidate", ["$scope", "$routeParams", "HostelManagementService", "$filter","HostelManagementIndexDBService", function ($scope, $routeParams, HostelManagementService, $filter,HostelManagementIndexDBService) {
$scope.validateAmount = function () {
var vrAmount = $scope.Candidate.Amount;
var vrTotalAmount = $scope.PerMonthCharge;
if (+vrAmount < +vrTotalAmount) {
$scope.IsValidAmount = false;
$scope.Candidate.DueAmount = (+vrTotalAmount - +vrAmount);
} else {
$scope.IsValidAmount = true;
$scope.Candidate.DueAmount = 0;
}
}
}]);
test.js
describe("ManagemntApp ", function() {
beforeEach(module('ManagemntApp'));
var scope;
var cntrlrCandidate,
$location;
beforeEach(inject(function ($controller,$rootScope){
scope = $rootScope.$new();
cntrlrCandidate = function() {
return $controller('cntrlrCandidate', {
'$scope': scope
});
};;
}));
it('test amount', function() {
scope.Candidate={};
scope.Candidate.Amount=2000;
scope.validateAmount();
expect(scope.IsValidAmount).toEqual(true);
});
});
I couldn't figure out what making notice.
This is the error I'm getting.
Update1:
When I wrote like this the error message is below.
beforeEach(inject(function ($controller,$rootScope){
scope = $rootScope.$new();
// cntrlrCandidate = function() {
cntrlrCandidate= $controller('cntrlrCandidate', {
'$scope': scope
});
// };;
}));
Please check this error:
Update 2:
I tried this way, please correct me if I did anything wrong.
describe("ManagemntApp ", function() {
var HostelManagementIndexDBService,HostelManagementService;
beforeEach(module('ManagemntApp'));
var scope;
var cntrlrCandidate,
$location;
beforeEach(inject(function ($controller,$rootScope){
scope = $rootScope.$new();
// cntrlrCandidate = function() {
HostelManagementService = {};
HostelManagementIndexDBService = {};
module(function($provide) {
$provide.value('HostelManagementService', HostelManagementService);
$provide.value('HostelManagementIndexDBService', HostelManagementIndexDBService);
});
cntrlrCandidate= $controller('cntrlrCandidate', {
'$scope': scope
});
// };;
}));
it('return will pass the Amount', function() {
scope.Candidate={};
scope.Candidate.Amount=2000;
scope.validateAmount();
expect(scope.IsValidAmount).toEqual(true);
});
});
cntrlrCandidate = function() {
return $controller('cntrlrCandidate', {
'$scope': scope
});
};
You have defined the function cntrlrCandidate but not calling anywhere.
You need to call it first then you will get your controller;
Add this line after the cntrlrCandidate defination;
var ctrlCandidate =cntrlrCandidate ();
OR
better if you define like this instead of defining above function.
cntrlrCandidate = $controller('cntrlrCandidate', {'$scope': scope});
EDIT :
Your controller required following Dependency HostelManagementService and HostelManagementIndexDBService which you not provided.So,you need to mock up it.
Add the following script.
var HostelManagementIndexDBService,HostelManagementService; //declare at top
// add in beforeEach
HostelManagementIndexDBService = {};
HostelManagementIndexDBService = {};
module(function($provide) {
$provide.value('HostelManagementService', HostelManagementService);
$provide.value('HostelManagementIndexDBService', HostelManagementIndexDBService);
});
UPDATE :
describe("ManagemntApp ", function() {
var HostelManagementIndexDBService, HostelManagementService;
beforeEach(module('ManagemntApp'));
var scope;
var cntrlrCandidate,
$location;
beforeEach(function() {
HostelManagementService = {};
HostelManagementIndexDBService = {};
module(function($provide) {
$provide.value('HostelManagementService', HostelManagementService);
$provide.value('HostelManagementIndexDBService', HostelManagementIndexDBService);
});
inject(function($controller, $rootScope) {
scope = $rootScope.$new();
cntrlrCandidate = $controller('cntrlrCandidate', { '$scope': scope });
})
});
it('return will pass the Amount', function() {
scope.Candidate = {};
scope.Candidate.Amount = 2000;
scope.validateAmount();
expect(scope.IsValidAmount).toEqual(true);
});
});

angular modal ui bootstrap unit test - undefined is not a function

APP
(function() {
'use strict';
function ArticlesController($templateCache, $modal, articlesData, Articles, $state) {
var articles = this;
articles.data = articlesData.data;
console.log($modal);//Give me LOG: Object{open: function () { ... }}
articles.open = function (article) {
var modalInstance = $modal.open({ // The unit test point to this line
template: $templateCache.get('articles/templates/modalDestroy.html'),
controller: 'ArticleDestroyController',
controllerAs: 'article',
size: 'sm',
resolve: {
articleData: function(){
return article;
}
}
});
modalInstance.result.then(function (article) {
Articles.destroy(article._id).then(function(response) {
var data = [];
angular.forEach(articles.data, function(value, key) {
if( value._id !== article._id){
this.push(value);
}
}, data);
articles.data = data;
})
.catch(function(response) {
console.log(response);
});
});
};
}
function ArticleDestroyController($modalInstance, articleData, Articles) {
var article = this;
article.data = articleData;
article.ok = function () {
$modalInstance.close(articleData);
};
article.cancel = function () {
$modalInstance.dismiss('cancel');
};
}
angular.module('articles.controllers', [])
.controller('ArticlesController', ArticlesController)
.controller('ArticleDestroyController', ArticleDestroyController);
})();
TEST
'use strict';
/* global describe, beforeEach, it, before, after, afterEach, inject, expect, spyOn */
describe('Unit: ArticlesController', function() {
var $rootScope, $scope, $controller;
beforeEach(function() {
module('articles');
});
var fakeModal = {
result: {
then: function(confirmCallback, cancelCallback) {
//Store the callbacks for later when the user clicks on the OK or Cancel button of the dialog
this.confirmCallBack = confirmCallback;
this.cancelCallback = cancelCallback;
}
},
close: function( item ) {
//The user clicked OK on the modal dialog, call the stored confirm callback with the selected item
this.result.confirmCallBack( item );
},
dismiss: function( type ) {
//The user clicked cancel on the modal dialog, call the stored cancel callback
this.result.cancelCallback( type );
}
};
beforeEach(inject(function($modal) {
spyOn($modal, 'open').and.callFake(fakeModal);
}));
beforeEach(inject(function(_$rootScope_,_$controller_, $modal){
$rootScope = _$rootScope_;
$scope = $rootScope.$new();
$controller = _$controller_;
var articlesData = {data:[{title:'my title',content:'my content'}]};
$controller('ArticlesController as articles', {$scope: $scope, $modal: $modal, articlesData:articlesData});
}));
it('articles.data should create an array with at least one article object ', function() {
expect($scope.articles.data.length).toBe(1);
$scope.articles.open($scope.articles.data[0]);
});
});
When I run gulp unit
I've got
TypeError: undefined is not a function
at ArticlesController.articles.open
point to line 9
var modalInstance = $modal.open
but if I try to check $modal it gives me
console.log($modal);//Give me LOG: Object{open: function () { ... }}
Do you see what's the problem ?
spyOn($modal, "open").and.callFake(function() {
return fakeModal;
});
Ran into this exact issue at work and resolved it in this way based on the documentation for Jasmine 2.0(http://jasmine.github.io/2.0/introduction.html).

testing controller containing $scope.$on

I am looking to test these two functions in my modal controller but Im not sure how to test $scope.$on functions. does anyone have any ideas?
$scope.$on("filesUploaded", function (e, files) {
for (var i = 0; i < files.length; i++) {
$scope.images.items.unshift(files[i]);
}
$scope.images.total += files.length;
});
$scope.$on("filesUploadCompleted", function () {
if (!$scope.$$phase) $scope.$apply();
});
my full test set up so far is:
describe('pbImagePickerModalController', function () {
beforeEach(module('pb.campaigns.controllers'));
beforeEach(module('ui.router'));
beforeEach(module('ui.bootstrap'));
//var mockWindow = {};
//var mockDocument = {};
var mockState = {};
var mockModal = {};
var mockGlobal = {};
var mockStateParams = {};
var mockAccountFileService = {};
var continuationToken = {};
beforeEach(inject(function ($q) {
mockStateParams = {
accountId: 543,
length: 12
};
mockGlobal = {
setFormSubmitInProgress: function (boolean) {
this.formProgress = boolean;
},
formProgress: false,
activeOrganizationId: 0
};
mockModalInstance = {
close: jasmine.createSpy('mockModalInstance.close'),
dismiss: jasmine.createSpy('mockModalInstance.dismiss'),
result: {
then: jasmine.createSpy('mockModalInstance.result.then')
}
};
mockAccountFileService = {
getFiles: function (activeOrganizationId, accountId, length, continuationToken) {
var defer = $q.defer();
defer.resolve(images);
return defer.promise;
}
};
}));
beforeEach(inject(function ($rootScope, _$controller_) {
scope = $rootScope.$new();
$controller = _$controller_;
controller = $controller('pbImagePickerModalController', {
$scope: scope,
$state: mockState,
$stateParams: mockStateParams,
global: mockGlobal,
accountFileService: mockAccountFileService,
$modal: mockModal,
$modalInstance: mockModalInstance,
//$window: mockWindow,
//$document: mockDocument,
accountId: mockStateParams.accountId
//accountId: function () {
// return mockStateParams.accountId;
//}
});
}));
describe("init() function", function () {
it('should call getImages()', function () {
spyOn(scope, 'getImages');
expect(scope.getImages).toHaveBeenCalledWith(50);
});
});
describe("getImages() function", function () {
it('should call getFiles with proper params', function () {
spyOn(mockAccountFileService, 'getFiles').and.callThrough();
scope.getImages(mockStateParams.length, continuationToken);
scope.$digest();
expect(mockAccountFileService.getFiles).toHaveBeenCalledWith(mockGlobal.activeOrganizationId, mockStateParams.accountId, mockStateParams.length, continuationToken);
});
it('should assign scope.images to promise result if scope.images does not exist', function () {
scope.getImages(mockStateParams.length, continuationToken);
scope.$digest();
expect(scope.images).toEqual(mockAccountFileService.images);
});
describe('with existing images', function () {
beforeEach(function () {
var existingLinks = {
continuationToken: 0002,
total: 2,
items: ['sponser_image01.png', 'sponser_image02.png']
};
scope.images = existingLinks;
});
it('should assign promise continuationToken to scope.images.continuationToken if scope.images exists', function () {
scope.getImages(mockStateParams.length, continuationToken);
scope.$digest();
expect(scope.images.continuationToken).toEqual(mockAccountFileService.images.continuationToken);
});
it('should assign promise data and existing images to scope if scope.images exists', function () {
scope.getImages(mockStateParams.length, continuationToken);
scope.$digest();
expect(scope.images.total).toEqual(4);
});
it('should push exisiting campaign links to link Array', function () {
scope.getImages(mockStateParams.length, continuationToken);
scope.$digest();
expect(scope.images.items).toEqual(['sponser_image01.png', 'sponser_image02.png', 'sponser_image03.png', 'sponser_image04.png']);
});
});
});
describe("cancel() function", function () {
it("changes formProgress from true to false", function () {
mockGlobal.setFormSubmitInProgress.formProgress = true;
scope.cancel();
expect(mockModalInstance.dismiss).toHaveBeenCalled();
expect(mockGlobal.formProgress).toEqual(false);
});
});
});
and my full controller is:
angular.module('pb.campaigns.controllers')
.controller('pbImagePickerModalController', ['$window', '$scope', '$document', '$modal', '$modalInstance', 'global', 'accountId', 'accountFileService', function ($window, $scope, $document, $modal, $modalInstance, global, accountId, accountFileService) {
$scope.currentAccountId = accountId;
var init = function () {
$scope.getImages(50);
};
$scope.getImages = function (length, continuationToken) {
// show all existing images
accountFileService.getFiles(global.activeOrganizationId, accountId, length, continuationToken).then(function (data) {
if ($scope.images) {
$scope.images.continuationToken = data.continuationToken;
$scope.images.total += data.total;
angular.forEach(data.items, function (value, key) {
$scope.images.items.push(data.items[key]);
});
} else {
$scope.images = data;
}
});
};
init();
$scope.$on("filesUploaded", function (e, files) {
for (var i = 0; i < files.length; i++) {
$scope.images.items.unshift(files[i]);
}
$scope.images.total += files.length;
});
$scope.$on("filesUploadCompleted", function () {
if (!$scope.$$phase) $scope.$apply();
});
//$scope.add = function (accountId, file) {
// global.setFormSubmitInProgress(true);
// accountFileService.createFile(global.activeOrganizationId, accountId, file).then(function () {
// global.setFormSubmitInProgress(false);
// $modalInstance.close();
// },
// function (errorData) {
// global.setFormSubmitInProgress(false);
// });
//};
$scope.select = function (image) {
$modalInstance.close(image);
};
$scope.cancel = function () {
global.setFormSubmitInProgress(false);
$modalInstance.dismiss('cancel');
};
}]);
You could test it with rootScope itself.
Example:-
$rootScope.$broadcast('filesUploaded', fileListStub); //broadcast the event with stub data
scope.$digest(); //Triger digest cycle to invoke on handler
expect(scope.images.total).toEqual(fileListStub.length+whateverinitialcount);
Demo

Resources