Skip to content

Commit

Permalink
Added tests to improve Controller test coverage to over 10% (zhukov#1428
Browse files Browse the repository at this point in the history
)

* fully tested CountrySelectModal Controller

* Added test CountrySelectModal Controller for forgotten scenarios

* fully tested ImportContactModal Controller

* fully tested ProfileEditModal Controller and cleanup style of tests

* fully tested PasswordRecoveryModal Controller

* tested most of UsernameEditModal Controller

* Improved readability, refactored beforeEach ImportContactModalControllerSpec

* Tried to make the code more DRY

* removed unnecessary 'this.'
  • Loading branch information
bartist authored and zhukov committed Jun 28, 2017
1 parent cd3979a commit aea8530
Show file tree
Hide file tree
Showing 6 changed files with 716 additions and 6 deletions.
14 changes: 8 additions & 6 deletions app/js/controllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -4455,9 +4455,11 @@ angular.module('myApp.controllers', ['myApp.i18n'])
AppUsersManager.saveApiUser(user)
$modalInstance.close()
}, function (error) {
if (error.type == 'USERNAME_NOT_MODIFIED') {
error.handled = true
$modalInstance.close()
switch (error.type) {
case 'USERNAME_NOT_MODIFIED':
error.handled = true
$modalInstance.close()
break
}
})['finally'](function () {
delete $scope.profile.updating
Expand All @@ -4470,9 +4472,9 @@ angular.module('myApp.controllers', ['myApp.i18n'])
return
}
MtpApiManager.invokeApi('account.checkUsername', {
username: newVal || ''
username: newVal
}).then(function (valid) {
if ($scope.profile.username != newVal) {
if ($scope.profile.username !== newVal) {
return
}
if (valid) {
Expand All @@ -4481,7 +4483,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.checked = {error: true}
}
}, function (error) {
if ($scope.profile.username != newVal) {
if ($scope.profile.username !== newVal) {
return
}
switch (error.type) {
Expand Down
181 changes: 181 additions & 0 deletions test/unit/controllers/CountrySelectModalControllerSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
'use strict'
/* global describe, it, inject, expect, beforeEach, afterEach, spyOn, jasmine, Config, SearchIndexManager */

describe('CountrySelectModalController', function () {
beforeEach(module('myApp.controllers'))

beforeEach(inject(function (_$controller_, _$rootScope_, ___) {
this.$controller = _$controller_
this.$rootScope = _$rootScope_
this._ = ___

this.$scope = _$rootScope_.$new()
this.createController = function () {
this.$controller('CountrySelectModalController', {
$scope: this.$scope,
$modalInstance: {},
$rootScope: this.$rootScope,
_: this._
})
}

spyOn(SearchIndexManager, 'indexObject').and.callThrough()
}))

beforeEach(function () {
this.ConfigCountryCodes = Config.CountryCodes
this.testData = {
singleCode: {
countryCode: ['NL', 'country_select_modal_country_nl', '+31'],
countryCode_full: 'NL Netherlands +31',
countryPhoneSets: [{ name: 'Netherlands', code: '+31' }]
},
multipleCode: {
countryCode: ['VA', 'country_select_modal_country_va', '+39 06 698', '+379'],
countryCode_full: 'VA Vatican City +39 06 698 +379',
countryPhoneSets: [{ name: 'Vatican City', code: '+39 06 698' }, { name: 'Vatican City', code: '+379' }]
},
multipleCode2: {
countryCode: ['AB', 'country_select_modal_country_ab', '+7 840', '+7 940', '+995 44'],
countryCode_full: 'AB Abkhazia +7 840 +7 940 +995 44',
countryPhoneSets: [{ name: 'Abkhazia', code: '+7 840' }, { name: 'Abkhazia', code: '+7 940' }, { name: 'Abkhazia', code: '+995 44' }]
},
allSetsSorted: function () {
return [].concat(this.multipleCode2.countryPhoneSets, this.singleCode.countryPhoneSets, this.multipleCode.countryPhoneSets)
},
allSetsUnsorted: function () {
return [].concat(this.singleCode.countryPhoneSets, this.multipleCode2.countryPhoneSets, this.multipleCode.countryPhoneSets)
}
}
})

afterEach(function () {
Config.CountryCodes = this.ConfigCountryCodes
})

// The tests before controller initiation.
// In order to mock Config data

it('initiates Country to select', function (done) {
Config.CountryCodes = [this.testData.singleCode.countryCode]
var expected = this.testData.singleCode.countryCode_full

this.createController()

expect(SearchIndexManager.indexObject).toHaveBeenCalledWith(0, expected, jasmine.any(Object))
done()
})

it('initiates Countriy to select with 2 (or more) country codes', function (done) {
Config.CountryCodes = [this.testData.multipleCode.countryCode]
var expected = this.testData.multipleCode.countryCode_full

this.createController()

expect(SearchIndexManager.indexObject).toHaveBeenCalledWith(0, expected, jasmine.any(Object))
done()
})

it('initiates Countries to select', function (done) {
Config.CountryCodes = [this.testData.singleCode.countryCode, this.testData.multipleCode.countryCode]
var expected1 = this.testData.singleCode.countryCode_full
var expected2 = this.testData.multipleCode.countryCode_full

this.createController()

expect(SearchIndexManager.indexObject).toHaveBeenCalledWith(0, expected1, jasmine.any(Object))
expect(SearchIndexManager.indexObject).toHaveBeenCalledWith(1, expected2, jasmine.any(Object))
done()
})

describe('(after initiation)', function () {
beforeEach(function () {
Config.CountryCodes = [this.testData.singleCode.countryCode, this.testData.multipleCode2.countryCode, this.testData.multipleCode.countryCode]
this.createController()
})

it('initiates the right values', function (done) {
expect(this.$scope.search).toEqual({})
expect(this.$scope.slice).toEqual({limit: 20, limitDelta: 20})
done()
})

it('creates a sorted list of all selectable countries', function (done) {
this.$rootScope.$digest()
var expected = this.testData.allSetsSorted()

expect(this.$scope.countries).toEqual(expected)
done()
})

it('creates a sorted list of all selectable countries for an empty string-input', function (done) {
this.$rootScope.$digest()
this.$scope.search.query = ''
this.$rootScope.$digest()
var expected = this.testData.allSetsSorted()

expect(this.$scope.countries).toEqual(expected)
done()
})

describe(', when an input is given,', function () {
beforeEach(function () {
this.$rootScope.$digest()
this.$scope.search.query = 'A'
})

it('creates a sorted list of all countries containing the input', function (done) {
var expected = this.testData.allSetsSorted()

expect(this.$scope.countries).toEqual(expected)

this.$rootScope.$digest()
expected = this.testData.multipleCode2.countryPhoneSets

expect(this.$scope.countries).toEqual(expected)
done()
})

it('restore the original list when the input is deleted', function (done) {
this.$rootScope.$digest()
this.$scope.search.query = ''
this.$rootScope.$digest()

var expected = this.testData.allSetsSorted()

expect(this.$scope.countries).toEqual(expected)
done()
})

it('restore the original list when the input is changed', function (done) {
this.$rootScope.$digest()
this.$scope.search.query = 'Ne'
this.$rootScope.$digest()

var expected = this.testData.singleCode.countryPhoneSets

expect(this.$scope.countries).toEqual(expected)
done()
})
})

describe(', when no sorting is available,', function () {
beforeEach(function () {
this.StringCompare = String.prototype.localeCompare
String.prototype.localeCompare = null
})

afterEach(function () {
String.prototype.localeCompare = this.StringCompare
})

it('creates a list of all selectable countries', function (done) {
this.$rootScope.$digest()
var expected = this.testData.allSetsUnsorted()

expect(this.$scope.countries).toEqual(expected)
done()
})
})
})
})
160 changes: 160 additions & 0 deletions test/unit/controllers/ImportContactModalControllerSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
'use strict'
/* global describe, it, inject, expect, beforeEach, jasmine */

describe('ImportContactModalController', function () {
beforeEach(module('myApp.controllers'))

beforeEach(function () {
this.modalInstance = {
close: jasmine.createSpy('close'),
dismiss: jasmine.createSpy('dismiss')
}

this.randomID = 123456852

function thenFinallyFactory (input) {
return {
then: function (callback) {
callback(input)
return {
finally: function (callback) {
callback()
}
}
}
}
}

this.AppUsersManager = {
thenValue: null,
importContact: function (phone, first, last) {
this.input = {
phone: phone,
first: first,
last: last
}
return thenFinallyFactory(this.thenValue)
}
}

this.ErrorService = {
show: jasmine.createSpy('show')
}

this.PhonebookContactsService = {
thenValue: false,
isAvailable: function () {
return false
},
openPhonebookImport: function () {
var then = thenFinallyFactory(this.thenValue)
return {
result: then
}
}
}

inject(function (_$controller_, _$rootScope_) {
this.$controller = _$controller_
this.$rootScope = _$rootScope_

this.$scope = _$rootScope_.$new()
this.createController = function () {
this.$controller('ImportContactModalController', {
$scope: this.$scope,
$modalInstance: this.modalInstance,
$rootScope: this.$rootScope,
AppUsersManager: this.AppUsersManager,
ErrorService: this.ErrorService,
PhonebookContactsService: this.PhonebookContactsService
})
}
})
})

it('can create a controller when no imported contacts are defined', function (done) {
this.createController()

expect(this.$scope.importContact).toEqual({})
done()
})

it('can create a controller when imported contacts are defined', function (done) {
this.$scope.importContact = { non_empty: true }
this.createController()
var expected = { non_empty: true }

expect(this.$scope.importContact).toEqual(expected)
done()
})

describe('(when the controller is created), ', function () {
beforeEach(function () {
this.createController()
})

it('does nothing when no phonenumber was entered', function (done) {
this.$scope.doImport()

expect(this.$scope.progress).not.toBeDefined()

this.$scope.importContact = {
first_name: 'bob'
}
expect(this.$scope.progress).not.toBeDefined()
done()
})

describe('when contact-information is added, it', function () {
beforeEach(function () {
this.$scope.importContact = {
phone: '+316132465798'
}
})

it('can handle phoneNumber that are not telegram users', function (done) {
this.$scope.doImport()

expect(this.ErrorService.show).toHaveBeenCalledWith({ error: {code: 404, type: 'USER_NOT_USING_TELEGRAM'} })
expect(this.modalInstance.close).toHaveBeenCalledWith(null)
expect(this.$scope.progress.enabled).not.toBeDefined()
done()
})

it('can import contacts that are telegram users', function (done) {
this.AppUsersManager.thenValue = this.randomID
this.$scope.doImport()

expect(this.ErrorService.show).not.toHaveBeenCalled()
expect(this.modalInstance.close).toHaveBeenCalledWith(this.randomID)
expect(this.$scope.progress.enabled).not.toBeDefined()
expect(this.AppUsersManager.input).toEqual({phone: '+316132465798', first: '', last: ''})
done()
})

it('can handle contacts with first and last name', function (done) {
this.$scope.importContact.first_name = 'jan'
this.$scope.importContact.last_name = 'wandelaar'
this.$scope.doImport()

expect(this.AppUsersManager.input).toEqual({phone: '+316132465798', first: 'jan', last: 'wandelaar'})
done()
})
})

it('can not import contacts from a phonebook if none were found', function (done) {
this.$scope.importPhonebook()

expect(this.modalInstance.dismiss).toHaveBeenCalled()
done()
})

it('can import contacts from a phonebook', function (done) {
this.PhonebookContactsService.thenValue = {0: 'dummy'}
this.$scope.importPhonebook()

expect(this.modalInstance.close).toHaveBeenCalledWith('dummy')
done()
})
})
})
Loading

0 comments on commit aea8530

Please sign in to comment.