Browse Source

Added structure to test directory, Fully tested filters.js (#1393)

* added tests for filter.js, Added structure to test-directory

In the gulpfile I changed some of the karma execution to ensure templates.js exists before the tests
Also removed some StandardJS errors from filters.js

* added tests to create at least 50% coverage for filters.js

* Added test for full coverage of filters.js

* fixed 2 side-cases

* Removed duplicate test, improved test-titles and added outcome clarification for dateOrTimeFilter

* Added test-init

While running ``gulp test`` there were a lot of warnings concerning i18n: key not found
This was because init.js was not run.
Because some parts of init.js were not relevant, I created test-init.js, only containing the part concerning localization.
Now the log is a lot cleaner when running ``gulp test``

* added 'use strict' to testing files

* changed local vars to this.

* improved clarity of mistery numbers

* improved in-test structure

* Improved shortUrl tests

* removed unnecessary code

* added cleanup to single test
master
Bart 8 years ago committed by Igor Zhukov
parent
commit
82957f1b91
  1. 31
      app/js/filters.js
  2. 4
      gulpfile.js
  3. 78
      karma.conf.js
  4. 42
      test/test-init.js
  5. 1
      test/unit/controllers/AppFooterControllerSpec.js
  6. 1
      test/unit/controllers/AppImPanelControllerSpec.js
  7. 1
      test/unit/controllers/AppLangSelectControllerSpec.js
  8. 1
      test/unit/controllers/AppWelcomeControllerSpec.js
  9. 1
      test/unit/controllers/ChangelogModalControlelerSpec.js
  10. 1
      test/unit/controllers/DocumentModalControllerSpec.js
  11. 1
      test/unit/controllers/EmbedModalController.js
  12. 1
      test/unit/controllers/PeerSelectControllerSpec.js
  13. 1
      test/unit/controllers/VideoModalControllerSpec.js
  14. 1
      test/unit/directives/myHeadDirective.js
  15. 1
      test/unit/directives/myLangFooterDirective.js
  16. 15
      test/unit/filters/chatTitleFilterSpec.js
  17. 72
      test/unit/filters/dateOrTimeFilterSpec.js
  18. 60
      test/unit/filters/durationFilterSpec.js
  19. 25
      test/unit/filters/durationRemainsFilterSpec.js
  20. 75
      test/unit/filters/formatShortNumberFilterSpec.js
  21. 76
      test/unit/filters/formatSizeFilterSpec.js
  22. 41
      test/unit/filters/formatSizeProgressFilterSpec.js
  23. 34
      test/unit/filters/myDateFilterSpec.js
  24. 38
      test/unit/filters/nl2brFilterSpec.js
  25. 49
      test/unit/filters/phoneNumberFilterSpec.js
  26. 62
      test/unit/filters/realtiveTimeFilterSpec.js
  27. 31
      test/unit/filters/richTextFilterSpec.js
  28. 81
      test/unit/filters/shortUrlFilterSpec.js
  29. 64
      test/unit/filters/timeFilterSpec.js
  30. 17
      test/unit/filters/userFirstNameFilterSpec.js
  31. 27
      test/unit/filters/userNameFilterSpec.js
  32. 141
      test/unit/filters/userStatusFilterSpec.js
  33. 1
      test/unit/services/PhonebookContactsServiceSpec.js

31
app/js/filters.js

@ -6,6 +6,7 @@
*/ */
'use strict' 'use strict'
/* global Config, tsNow */
/* Filters */ /* Filters */
@ -16,7 +17,7 @@ angular.module('myApp.filters', ['myApp.i18n'])
if (!user || !user.first_name && !user.last_name) { if (!user || !user.first_name && !user.last_name) {
return _('user_name_deleted') return _('user_name_deleted')
} }
return user.first_name + (user.last_name ? ' ' + user.last_name : '') return user.first_name ? (user.first_name + (user.last_name ? ' ' + user.last_name : '')) : user.last_name
} }
}) })
@ -32,8 +33,8 @@ angular.module('myApp.filters', ['myApp.i18n'])
.filter('userStatus', function ($filter, _) { .filter('userStatus', function ($filter, _) {
var relativeTimeFilter = $filter('relativeTime') var relativeTimeFilter = $filter('relativeTime')
return function (user, botChatPrivacy) { return function (user, botChatPrivacy) {
if (!(user.id % 1000)) { if (user && !(user.id % 1000)) {
if (user.id == 777000) { if (user.id === 777000) {
return _('user_status_service_notifications') return _('user_status_service_notifications')
} }
return _('user_status_support') return _('user_status_support')
@ -97,8 +98,7 @@ angular.module('myApp.filters', ['myApp.i18n'])
if (diff > 518400000) { // 6 days if (diff > 518400000) { // 6 days
format = extended ? 'mediumDate' : 'shortDate' format = extended ? 'mediumDate' : 'shortDate'
} } else if (diff > 43200000) { // 12 hours
else if (diff > 43200000) { // 12 hours
format = extended ? 'EEEE' : 'EEE' format = extended ? 'EEEE' : 'EEE'
} }
@ -163,7 +163,7 @@ angular.module('myApp.filters', ['myApp.i18n'])
return function (phoneRaw) { return function (phoneRaw) {
var nbsp = ' ' var nbsp = ' '
phoneRaw = (phoneRaw || '').replace(/\D/g, '') phoneRaw = (phoneRaw || '').replace(/\D/g, '')
if (phoneRaw.charAt(0) == '7' && phoneRaw.length == 11) { if (phoneRaw.charAt(0) === '7' && phoneRaw.length === 11) {
return '+' + phoneRaw.charAt(0) + nbsp + '(' + phoneRaw.substr(1, 3) + ')' + nbsp + phoneRaw.substr(4, 3) + '-' + phoneRaw.substr(7, 2) + '-' + phoneRaw.substr(9, 2) return '+' + phoneRaw.charAt(0) + nbsp + '(' + phoneRaw.substr(1, 3) + ')' + nbsp + phoneRaw.substr(4, 3) + '-' + phoneRaw.substr(7, 2) + '-' + phoneRaw.substr(9, 2)
} }
return '+' + phoneRaw return '+' + phoneRaw
@ -174,11 +174,9 @@ angular.module('myApp.filters', ['myApp.i18n'])
return function (size, progressing) { return function (size, progressing) {
if (!size) { if (!size) {
return '0' return '0'
} } else if (size < 1024) {
else if (size < 1024) {
return size + ' b' return size + ' b'
} } else if (size < 1048576) {
else if (size < 1048576) {
return Math.round(size / 1024) + ' KB' return Math.round(size / 1024) + ' KB'
} }
var mbs = size / 1048576 var mbs = size / 1048576
@ -203,7 +201,7 @@ angular.module('myApp.filters', ['myApp.i18n'])
var totalParts = total.split(' ') var totalParts = total.split(' ')
if (totalParts[1] === doneParts[1]) { if (totalParts[1] === doneParts[1]) {
return _('format_size_progress_mulitple', {done: doneParts[0], total: totalParts[0], parts: (doneParts[1] || '')}) return _('format_size_progress_mulitple', {done: doneParts[0], total: totalParts[0], parts: doneParts[1]})
} }
return _('format_size_progress', {done: done, total: total}) return _('format_size_progress', {done: done, total: total})
} }
@ -211,17 +209,16 @@ angular.module('myApp.filters', ['myApp.i18n'])
.filter('formatShortNumber', [function () { .filter('formatShortNumber', [function () {
return function (num) { return function (num) {
var mult
if (!num) { if (!num) {
return '0' return '0'
} } else if (num < 1000) {
else if (num < 1000) {
return num.toString() return num.toString()
} } else if (num < 900000) {
else if (num < 900000) { mult = num > 10000 ? 1 : 10
var mult = num > 10000 ? 1 : 10
return (Math.round(num / 1000 * mult) / mult) + 'K' return (Math.round(num / 1000 * mult) / mult) + 'K'
} }
var mult = num > 10000000 ? 1 : 10 mult = num > 10000000 ? 1 : 10
return (Math.round(num / 1000000 * mult) / mult) + 'M' return (Math.round(num / 1000000 * mult) / mult) + 'M'
} }
}]) }])

4
gulpfile.js

@ -293,14 +293,14 @@ gulp.task('karma-tdd', function (done) {
gulp.task('test', function (callback) { gulp.task('test', function (callback) {
runSequence( runSequence(
['templates', 'karma-single'], 'templates', 'karma-single', 'clean-templates',
callback callback
) )
}) })
gulp.task('tdd', function (callback) { gulp.task('tdd', function (callback) {
runSequence( runSequence(
['templates', 'karma-tdd'], 'templates', 'karma-tdd',
callback callback
) )
}) })

78
karma.conf.js

@ -1,7 +1,7 @@
// Karma configuration // Karma configuration
// Generated on Thu Dec 15 2016 21:12:39 GMT+0100 (CET) // Generated on Thu Dec 15 2016 21:12:39 GMT+0100 (CET)
module.exports = function(config) { module.exports = function (config) {
config.set({ config.set({
// base path that will be used to resolve all patterns (eg. files, exclude) // base path that will be used to resolve all patterns (eg. files, exclude)
@ -16,53 +16,55 @@ module.exports = function(config) {
// list of files / patterns to load in the browser // list of files / patterns to load in the browser
// Load files to access global variables // Load files to access global variables
files: [ files: [
{pattern: 'js/lib/polyfill.js', watched: false}, {pattern: 'js/lib/polyfill.js', watched: false},
{pattern: 'vendor/jquery/jquery.min.js', watched: false}, {pattern: 'vendor/jquery/jquery.min.js', watched: false},
{pattern: 'js/lib/config.js', watched: false}, {pattern: 'js/lib/config.js', watched: false},
{pattern: 'vendor/jquery.nanoscroller/nanoscroller.js', watched: false}, {pattern: 'vendor/jquery.nanoscroller/nanoscroller.js', watched: false},
{pattern: 'vendor/angular/angular.js', watched: false}, {pattern: 'vendor/angular/angular.js', watched: false},
{pattern: 'vendor/angular/angular-mocks.js', watched: false}, {pattern: 'vendor/angular/angular-mocks.js', watched: false},
{pattern: 'vendor/angular/angular-route.js', watched: false}, {pattern: 'vendor/angular/angular-route.js', watched: false},
{pattern: 'vendor/angular/angular-animate.js', watched: false}, {pattern: 'vendor/angular/angular-animate.js', watched: false},
{pattern: 'vendor/angular/angular-sanitize.js', watched: false}, {pattern: 'vendor/angular/angular-sanitize.js', watched: false},
{pattern: 'vendor/angular/angular-touch.js', watched: false}, {pattern: 'vendor/angular/angular-touch.js', watched: false},
{pattern: 'vendor/ui-bootstrap/ui-bootstrap-custom-tpls-0.12.0.js', watched: false}, {pattern: 'vendor/ui-bootstrap/ui-bootstrap-custom-tpls-0.12.0.js', watched: false},
{pattern: 'vendor/angular-media-player/angular-media-player.js', watched: false}, {pattern: 'vendor/angular-media-player/angular-media-player.js', watched: false},
{pattern: 'vendor/jsbn/jsbn_combined.js', watched: false}, {pattern: 'vendor/jsbn/jsbn_combined.js', watched: false},
{pattern: 'vendor/cryptoJS/crypto.js', watched: false}, {pattern: 'vendor/cryptoJS/crypto.js', watched: false},
{pattern: 'vendor/rusha/rusha.js', watched: false}, {pattern: 'vendor/rusha/rusha.js', watched: false},
{pattern: 'vendor/zlib/gunzip.min.js', watched: false}, {pattern: 'vendor/zlib/gunzip.min.js', watched: false},
{pattern: 'vendor/closure/long.js', watched: false}, {pattern: 'vendor/closure/long.js', watched: false},
{pattern: 'vendor/leemon_bigint/bigint.js', watched: false}, {pattern: 'vendor/leemon_bigint/bigint.js', watched: false},
{pattern: 'vendor/libwebpjs/libwebp-0.2.0.js', watched: false}, {pattern: 'vendor/libwebpjs/libwebp-0.2.0.js', watched: false},
{pattern: 'vendor/angularjs-toaster/toaster.js', watched: false}, {pattern: 'vendor/angularjs-toaster/toaster.js', watched: false},
{pattern: 'vendor/clipboard/clipboard.js', watched: false}, {pattern: 'vendor/clipboard/clipboard.js', watched: false},
{pattern: 'js/lib/utils.js', watched: false}, {pattern: 'js/lib/utils.js', watched: false},
{pattern: 'js/lib/bin_utils.js', watched: false}, {pattern: 'js/lib/bin_utils.js', watched: false},
{pattern: 'js/lib/tl_utils.js', watched: false}, {pattern: 'js/lib/tl_utils.js', watched: false},
{pattern: 'js/lib/ng_utils.js', watched: false}, {pattern: 'js/lib/ng_utils.js', watched: false},
{pattern: 'js/lib/i18n.js', watched: false}, {pattern: 'js/lib/i18n.js', watched: false},
{pattern: 'js/lib/mtproto.js', watched: false}, {pattern: 'js/lib/mtproto.js', watched: false},
{pattern: 'js/lib/mtproto_wrapper.js', watched: false}, {pattern: 'js/lib/mtproto_wrapper.js', watched: false},
'js/templates.js', // Generated by `gulp templates` {pattern: 'js/locales/*.json', watched: false, served: true, included: false},
'js/services.js', {pattern: '../test/test-init.js', watched: false},
'js/filters.js', 'js/templates.js', // Generated by `gulp templates`
'js/controllers.js', 'js/services.js',
'js/directives.js', 'js/filters.js',
'../test/unit/*.js' 'js/controllers.js',
'js/directives.js',
'../test/unit/**/*.js'
], ],
// list of files to exclude // list of files to exclude
exclude: [ exclude: [
'js/background.js' 'js/background.js'
], ],
// preprocess matching files before serving them to the browser // preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: { preprocessors: {
'js/*.js': ['coverage'], 'js/*.js': ['coverage']
}, },
@ -106,6 +108,6 @@ module.exports = function(config) {
// Concurrency level // Concurrency level
// how many browser should be started simultaneous // how many browser should be started simultaneous
concurrency: Infinity, concurrency: Infinity
}) })
} }

42
test/test-init.js

@ -0,0 +1,42 @@
'use strict'
/* global ConfigStorage, Config */
;(function initTestApplication () {
ConfigStorage.get('layout_selected', 'i18n_locale', function (params) {
var locale = params[1]
var defaultLocale = 'en-us'
var bootReady = {
dom: false,
i18n_ng: false,
i18n_messages: false,
i18n_fallback: false
}
if (!locale) {
locale = (navigator.language || '').toLowerCase()
locale = Config.I18n.aliases[locale] || locale
}
for (var i = 0; i < Config.I18n.supported.length; i++) {
if (Config.I18n.supported[i] === locale) {
Config.I18n.locale = locale
break
}
}
bootReady.i18n_ng = Config.I18n.locale === defaultLocale // Already included
$.getJSON('base/js/locales/' + Config.I18n.locale + '.json').success(function (json) {
Config.I18n.messages = json
bootReady.i18n_messages = true
if (Config.I18n.locale === defaultLocale) { // No fallback, leave empty object
bootReady.i18n_fallback = true
}
})
if (Config.I18n.locale !== defaultLocale) {
$.getJSON('base/js/locales/' + defaultLocale + '.json').success(function (json) {
Config.I18n.fallback_messages = json
bootReady.i18n_fallback = true
})
}
})
})()

1
test/unit/AppFooterControllerSpec.js → test/unit/controllers/AppFooterControllerSpec.js

@ -1,3 +1,4 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */ /* global describe, it, inject, expect, beforeEach */
describe('AppFooterController', function () { describe('AppFooterController', function () {

1
test/unit/AppImPanelControllerSpec.js → test/unit/controllers/AppImPanelControllerSpec.js

@ -1,3 +1,4 @@
'use strict'
/* global describe, it, inject, expect, beforeEach, jasmine */ /* global describe, it, inject, expect, beforeEach, jasmine */
describe('AppImPanelController', function () { describe('AppImPanelController', function () {

1
test/unit/AppLangSelectControllerSpec.js → test/unit/controllers/AppLangSelectControllerSpec.js

@ -1,3 +1,4 @@
'use strict'
/* global describe, it, inject, expect, beforeEach, xit */ /* global describe, it, inject, expect, beforeEach, xit */
describe('AppLangSelectController', function () { describe('AppLangSelectController', function () {

1
test/unit/AppWelcomeControllerSpec.js → test/unit/controllers/AppWelcomeControllerSpec.js

@ -1,3 +1,4 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */ /* global describe, it, inject, expect, beforeEach */
describe('AppWelcomeController', function () { describe('AppWelcomeController', function () {

1
test/unit/ChangelogModalControlelerSpec.js → test/unit/controllers/ChangelogModalControlelerSpec.js

@ -1,3 +1,4 @@
'use strict'
/* global describe, it, inject, expect, beforeEach, Config */ /* global describe, it, inject, expect, beforeEach, Config */
describe('ChangeLogModalController', function () { describe('ChangeLogModalController', function () {

1
test/unit/DocumentModalControllerSpec.js → test/unit/controllers/DocumentModalControllerSpec.js

@ -1,3 +1,4 @@
'use strict'
/* global describe, it, inject, expect, beforeEach, jasmine */ /* global describe, it, inject, expect, beforeEach, jasmine */
describe('DocumentModalController', function () { describe('DocumentModalController', function () {

1
test/unit/EmbedModalController.js → test/unit/controllers/EmbedModalController.js

@ -1,3 +1,4 @@
'use strict'
/* global describe, it, inject, expect, beforeEach, jasmine */ /* global describe, it, inject, expect, beforeEach, jasmine */
describe('EmbedModalController', function () { describe('EmbedModalController', function () {

1
test/unit/PeerSelectControllerSpec.js → test/unit/controllers/PeerSelectControllerSpec.js

@ -1,3 +1,4 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */ /* global describe, it, inject, expect, beforeEach */
describe('PeerSelectController', function () { describe('PeerSelectController', function () {

1
test/unit/VideoModalControllerSpec.js → test/unit/controllers/VideoModalControllerSpec.js

@ -1,3 +1,4 @@
'use strict'
/* global describe, it, inject, expect, beforeEach, jasmine */ /* global describe, it, inject, expect, beforeEach, jasmine */
describe('VideoModalController', function () { describe('VideoModalController', function () {

1
test/unit/myHeadDirective.js → test/unit/directives/myHeadDirective.js

@ -1,3 +1,4 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */ /* global describe, it, inject, expect, beforeEach */
describe('myHead directive', function () { describe('myHead directive', function () {

1
test/unit/myLangFooterDirective.js → test/unit/directives/myLangFooterDirective.js

@ -1,3 +1,4 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */ /* global describe, it, inject, expect, beforeEach */
describe('myLangFooter directive', function () { describe('myLangFooter directive', function () {

15
test/unit/chatTitleFilterSpec.js → test/unit/filters/chatTitleFilterSpec.js

@ -1,22 +1,21 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */ /* global describe, it, inject, expect, beforeEach */
describe('chatTitle filter', function () { describe('chatTitle filter', function () {
var $filter, _, chatTitleFilter
beforeEach(module('myApp.filters')) beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_, ___) { beforeEach(inject(function (_$filter_, ___) {
$filter = _$filter_ this.$filter = _$filter_
_ = ___ this._ = ___
})) }))
beforeEach(function () { beforeEach(function () {
chatTitleFilter = $filter('chatTitle') this.chatTitleFilter = this.$filter('chatTitle')
}) })
it('displays chat title deleted', function () { it('displays chat title deleted', function () {
var expected = _('chat_title_deleted') var expected = this._('chat_title_deleted')
var actual = chatTitleFilter(null) var actual = this.chatTitleFilter(null)
expect(actual).toEqual(expected) expect(actual).toEqual(expected)
}) })
@ -26,7 +25,7 @@ describe('chatTitle filter', function () {
title: 'Telegraph is hot!' title: 'Telegraph is hot!'
} }
var expected = chat.title var expected = chat.title
var actual = chatTitleFilter(chat) var actual = this.chatTitleFilter(chat)
expect(actual).toEqual(expected) expect(actual).toEqual(expected)
}) })

72
test/unit/filters/dateOrTimeFilterSpec.js

@ -0,0 +1,72 @@
'use strict'
/* global describe, it, inject, expect, beforeEach, tsNow*/
describe('dateOrTime filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_) {
this.$filter = _$filter_
}))
beforeEach(function () {
this.dateOrTimeFilter = this.$filter('dateOrTime')
// https://stackoverflow.com/questions/4676195/why-do-i-need-to-multiply-unix-timestamps-by-1000-in-javascript
this.miliSecondsToSeconds = 1000
this.sevenDaysAgo = -3600 * 24 * 7
this.thirteenHoursAgo = -3600 * 13
})
it('can handle "zero"-values', function () {
var input = 0
var expected = ''
var result = this.dateOrTimeFilter(input, false)
expect(result).toBe(expected)
})
it('can display the time based on timestamp', function () {
var input = tsNow(true)
// Outcome format expected: HH:MM AM/PM
var expected = this.$filter('date')(input * this.miliSecondsToSeconds, 'shortTime')
var result = this.dateOrTimeFilter(input, false)
expect(result).toBe(expected)
})
it('can display the short date based on timestamp', function () {
var input = tsNow(true)
// Outcome format expected: (M or MM)/(D or DD)/YY
var expected = this.$filter('date')((input + this.sevenDaysAgo) * this.miliSecondsToSeconds, 'shortDate')
var result = this.dateOrTimeFilter(input + this.sevenDaysAgo, false)
expect(result).toBe(expected)
})
it('can display the medium-size date based on timestamp', function () {
var input = tsNow(true)
// Outcome format expected: Month(3 letters) Day, Year
var expected = this.$filter('date')((input + this.sevenDaysAgo) * this.miliSecondsToSeconds, 'mediumDate')
var result = this.dateOrTimeFilter(input + this.sevenDaysAgo, true)
expect(result).toBe(expected)
})
it('can display the day of the week (in short) based on timestamp', function () {
var input = tsNow(true)
// Outcome format expcected: Day of week in three letters (Mon, Tue, etc.)
var expected = this.$filter('date')((input + this.thirteenHoursAgo) * this.miliSecondsToSeconds, 'EEE')
var result = this.dateOrTimeFilter(input + this.thirteenHoursAgo, false)
expect(result).toBe(expected)
})
it('can display the day of the week based on timestamp', function () {
var input = tsNow(true)
// Outcome format expcected: Day of week (Monday, Tuesday, etc.)
var expected = this.$filter('date')((input + this.thirteenHoursAgo) * this.miliSecondsToSeconds, 'EEEE')
var result = this.dateOrTimeFilter(input + this.thirteenHoursAgo, true)
expect(result).toBe(expected)
})
})

60
test/unit/filters/durationFilterSpec.js

@ -0,0 +1,60 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */
describe('duration filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_) {
this.$filter = _$filter_
}))
beforeEach(function () {
this.durationFilter = this.$filter('duration')
})
it('converts duration in seconds to a readable string', function () {
var input = 55
var expected = '0:55'
var result = this.durationFilter(input)
expect(result).toBe(expected)
input = 147
expected = '2:27'
result = this.durationFilter(input)
expect(result).toBe(expected)
})
it('converts hours in seconds to readable string', function () {
var input = 7282
var expected = '2:01:22'
var result = this.durationFilter(input)
expect(result).toBe(expected)
input = 4201
expected = '1:10:01'
result = this.durationFilter(input)
expect(result).toBe(expected)
})
it('returns "zero" when not a valid input was given', function () {
var input = 'not a number'
var expected = '0:00'
var result = this.durationFilter(input)
expect(result).toBe(expected)
input = {}
result = this.durationFilter(input)
expect(result).toBe(expected)
input = []
result = this.durationFilter(input)
expect(result).toBe(expected)
})
})

25
test/unit/filters/durationRemainsFilterSpec.js

@ -0,0 +1,25 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */
describe('durationRemains filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_) {
this.$filter = _$filter_
}))
beforeEach(function () {
this.durationRemainsFilter = this.$filter('durationRemains')
})
it('creates a readable string based on time and total time', function () {
var totalTime = 120 // two minutes
var currentTime = 100
var expected = '-0:20'
var result = this.durationRemainsFilter(currentTime, totalTime)
expect(result).toBe(expected)
})
// Other behaviour is tested in durationFilterSpec.js
})

75
test/unit/filters/formatShortNumberFilterSpec.js

@ -0,0 +1,75 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */
describe('formatShortNumber filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_) {
this.$filter = _$filter_
}))
beforeEach(function () {
this.formatShortNumberFilter = this.$filter('formatShortNumber')
})
it('converts zero or undefined', function () {
var input = 0
var expected = '0'
var result = this.formatShortNumberFilter(input)
expect(result).toBe(expected)
input = undefined
result = this.formatShortNumberFilter(input)
expect(result).toBe(expected)
})
it('converts numbers below 1000 to string with same value', function () {
var input = 127
var expected = '127'
var result = this.formatShortNumberFilter(input)
expect(result).toBe(expected)
input = 999
expected = '999'
result = this.formatShortNumberFilter(input)
expect(result).toBe(expected)
})
it('converts numbers between 1000 and 900000 to string with shortened value', function () {
var input = 1276
var expected = '1.3K'
var result = this.formatShortNumberFilter(input)
expect(result).toBe(expected)
input = 35444
expected = '35K'
result = this.formatShortNumberFilter(input)
expect(result).toBe(expected)
input = 899999
expected = '900K'
result = this.formatShortNumberFilter(input)
expect(result).toBe(expected)
})
it('converts numbers above 900000 to string with shortened value', function () {
var input = 900000
var expected = '0.9M'
var result = this.formatShortNumberFilter(input)
expect(result).toBe(expected)
input = 76785646867
expected = '76786M'
result = this.formatShortNumberFilter(input)
expect(result).toBe(expected)
})
})

76
test/unit/filters/formatSizeFilterSpec.js

@ -0,0 +1,76 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */
describe('formatSize filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_) {
this.$filter = _$filter_
}))
beforeEach(function () {
this.formatSizeFilter = this.$filter('formatSize')
})
it('converts zero', function () {
var input = 0
var expected = '0'
var result = this.formatSizeFilter(input, false)
expect(result).toBe(expected)
})
it('converts sizes below 1024 to byte', function () {
var input = 234
var expected = '234 b'
var result = this.formatSizeFilter(input, false)
expect(result).toBe(expected)
input = 1023
expected = '1023 b'
result = this.formatSizeFilter(input, false)
expect(result).toBe(expected)
})
it('converts sizes between 1024 and 1048576 to KB', function () {
var input = 238994
var expected = '233 KB'
var result = this.formatSizeFilter(input, false)
expect(result).toBe(expected)
input = 1048575
expected = '1024 KB'
result = this.formatSizeFilter(input, false)
expect(result).toBe(expected)
})
it('converts sizes above 1048576 to MB', function () {
var input = 10485726
var expected = '10 MB'
var result = this.formatSizeFilter(input, false)
expect(result).toBe(expected)
input = 1048572676967876
expected = '999996830.9 MB'
result = this.formatSizeFilter(input, false)
expect(result).toBe(expected)
input = 10485726
expected = '10.0 MB'
result = this.formatSizeFilter(input, true)
expect(result).toBe(expected)
input = 1048572676967876
expected = '999996830.9 MB'
result = this.formatSizeFilter(input, true)
expect(result).toBe(expected)
})
})

41
test/unit/filters/formatSizeProgressFilterSpec.js

@ -0,0 +1,41 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */
describe('formatSizeProgress filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_, ___) {
this.$filter = _$filter_
this._ = ___
}))
beforeEach(function () {
this.formatSizeProgressFilter = this.$filter('formatSizeProgress')
})
it('can handle "zero"-input', function () {
var input = { total: 0 }
var expected = ''
var result = this.formatSizeProgressFilter(input)
expect(result).toBe(expected)
})
it('can format progress with different scale of magnitude', function () {
var input = { total: 1024, done: 1023 }
var expected = this._('format_size_progress', {done: '1023 b', total: '1 KB'})
var result = this.formatSizeProgressFilter(input)
expect(result).toBe(expected)
})
it('can format progress with the same scale of size', function () {
var input = { total: 2048, done: 1024 }
var expected = this._('format_size_progress_mulitple', {done: '1', total: '2', parts: 'KB'})
var result = this.formatSizeProgressFilter(input)
expect(result).toBe(expected)
})
// Further testing for options is done in formatSizeFilterSpec.js
})

34
test/unit/filters/myDateFilterSpec.js

@ -0,0 +1,34 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */
describe('myDate filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_) {
this.$filter = _$filter_
}))
beforeEach(function () {
this.myDateFilter = this.$filter('myDate')
})
it('can create a date based on timestamp', function () {
var input = 1222222222
var expected = 'Wednesday, September 24, 2008'
var result = this.myDateFilter(input)
expect(result).toBe(expected)
})
it('can recollect a date based on timestamp', function () {
var input = 12111114111
var expected = 'Thursday, October 15, 2353'
var result1 = this.myDateFilter(input)
expect(result1).toBe(expected)
var result2 = this.myDateFilter(input)
expect(result2).toBe(expected)
})
})

38
test/unit/filters/nl2brFilterSpec.js

@ -0,0 +1,38 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */
describe('nl2br filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_, ___) {
this.$filter = _$filter_
}))
beforeEach(function () {
this.nl2brFilter = this.$filter('nl2br')
})
it('replaces an enter by a break-tag', function () {
var input = 'Line one \n Line 2'
var expected = 'Line one <br/> Line 2'
var result = this.nl2brFilter(input)
expect(result).toBe(expected)
})
it('replaces enters by break-tags', function () {
var input = 'Line one \n Line 2 \n Line 3'
var expected = 'Line one <br/> Line 2 <br/> Line 3'
var result = this.nl2brFilter(input)
expect(result).toBe(expected)
})
it('does not change the text if no enter is present', function () {
var input, expected
input = expected = 'Some random line with no enters'
var result = this.nl2brFilter(input)
expect(result).toBe(expected)
})
})

49
test/unit/filters/phoneNumberFilterSpec.js

@ -0,0 +1,49 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */
describe('phoneNumber filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_) {
this.$filter = _$filter_
}))
beforeEach(function () {
this.phoneNumberFilter = this.$filter('phoneNumber')
})
it('can handle "zero" values', function () {
var input
var expected = '+'
var result = this.phoneNumberFilter(input)
expect(result).toBe(expected)
input = null
result = this.phoneNumberFilter(input)
expect(result).toBe(expected)
input = 0
result = this.phoneNumberFilter(input)
expect(result).toBe(expected)
})
it('removes all non-digits from a phoneNumber', function () {
var input = '123nonnumber333333e3'
var expected = '+1233333333'
var result = this.phoneNumberFilter(input)
expect(result).toBe(expected)
})
it('converts phone number to a readable phone number (for Russia)', function () {
// 7 is for russian Country calling code (https://en.wikipedia.org/wiki/Telephone_numbers_in_Europe)
var input = '71234567890'
var expected = '+7 (123) 456-78-90'
var result = this.phoneNumberFilter(input)
expect(result).toBe(expected)
})
})

62
test/unit/filters/realtiveTimeFilterSpec.js

@ -0,0 +1,62 @@
'use strict'
/* global describe, it, inject, expect, beforeEach, jasmine, tsNow*/
describe('relativeTime filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_, ___) {
this.$filter = _$filter_
this._ = ___
}))
beforeEach(function () {
this.minuteSpy = jasmine.createSpy()
this.hourSpy = jasmine.createSpy()
// local vars are used to prevent scoping problems
var ms = this.minuteSpy
var hs = this.hourSpy
this._.pluralize = function (msgid) {
if (msgid === 'relative_time_pluralize_minutes_ago') {
return ms
} else if (msgid === 'relative_time_pluralize_hours_ago') {
return hs
}
}
this.relativeTimeFilter = this.$filter('relativeTime', {$filter: this.$filter, _: this._})
})
it('can mark time as "just now"', function () {
var input = tsNow(true)
var expected = this._('relative_time_just_now')
var result = this.relativeTimeFilter(input)
expect(result).toBe(expected)
})
// because the exact of tsNow in hard to estimate, a Spy is used instead of checking the return value
it('can convert time that is max. 1 hour away', function () {
var input = tsNow(true) - 3500
this.relativeTimeFilter(input)
expect(this.minuteSpy).toHaveBeenCalled()
})
// because the exact of tsNow in hard to estimate, a Spy is used instead of checking the return value
it('can convert time that is max. 24 hours away', function () {
var input = tsNow(true) - 86000
this.relativeTimeFilter(input)
expect(this.hourSpy).toHaveBeenCalled()
})
it('can convert time after 24 hours based on timestamp', function () {
var input = tsNow(true) - 1000000
var expected = this.$filter('dateOrTime')(input, true)
var result = this.relativeTimeFilter(input)
expect(result).toBe(expected)
})
// Further testing on the dateOrTimeFilter is present in dateOrTimeFilterSpec.js
})

31
test/unit/filters/richTextFilterSpec.js

@ -0,0 +1,31 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */
describe('richText filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(module('ngSanitize')) // necessary for linky filter
beforeEach(inject(function (_$filter_) {
this.$filter = _$filter_
}))
beforeEach(function () {
this.richTextFilter = this.$filter('richText')
})
it('changes url to actual link', function () {
var input = 'a text that links to https://www.github.com'
var expected = 'a text that links to <a target="_blank" href="https://www.github.com">https://www.github.com</a>'
var result = this.richTextFilter(input)
expect(result).toBe(expected)
})
it('changes urls to actual links', function () {
var input = 'a text that links to https://www.github.com and https://www.github.com/zhukov/webogram'
var expected = 'a text that links to <a target="_blank" href="https://www.github.com">https://www.github.com</a> and <a target="_blank" href="https://www.github.com/zhukov/webogram">https://www.github.com/zhukov/webogram</a>'
var result = this.richTextFilter(input)
expect(result).toBe(expected)
})
})

81
test/unit/filters/shortUrlFilterSpec.js

@ -0,0 +1,81 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */
describe('shortUrl filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_) {
this.$filter = _$filter_
}))
beforeEach(function () {
this.shortUrlFilter = this.$filter('shortUrl')
})
it('does not do anything if the input is not a string', function () {
var input = {}
var expected = input
var result = this.shortUrlFilter(input)
expect(result).toBe(expected)
input = []
expected = input
result = this.shortUrlFilter(input)
expect(result).toBe(expected)
input = 11
expected = input
result = this.shortUrlFilter(input)
expect(result).toBe(expected)
})
it('removes "http(s)" from a Url', function () {
var input = 'https://github.com'
var expected = 'github.com'
var result = this.shortUrlFilter(input)
expect(result).toBe(expected)
input = 'http://github.com'
result = this.shortUrlFilter(input)
expect(result).toBe(expected)
})
it('does not remove other protocols from a Url', function () {
var input, expected
input = expected = 'ftp://github.com'
var result = this.shortUrlFilter(input)
expect(result).toBe(expected)
input = expected = 'irc://github.com'
result = this.shortUrlFilter(input)
expect(result).toBe(expected)
input = expected = 'tg://github.com'
result = this.shortUrlFilter(input)
expect(result).toBe(expected)
})
it('removes "www." from a Url', function () {
var input = 'www.github.com'
var expected = 'github.com'
var result = this.shortUrlFilter(input)
expect(result).toBe(expected)
})
it('removes "https://" and "www." from a Url', function () {
var input = 'https://www.github.com'
var expected = 'github.com'
var result = this.shortUrlFilter(input)
expect(result).toBe(expected)
})
})

64
test/unit/filters/timeFilterSpec.js

@ -0,0 +1,64 @@
'use strict'
/* global describe, it, inject, expect, beforeEach, Config */
describe('time filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_) {
this.$filter = _$filter_
}))
describe('on the mobile website', function () {
beforeEach(function () {
Config.Mobile = true
this.timeFilter = this.$filter('time')
})
it('can create a short time based on timestamp', function () {
var input = 1222
var expected = '1:20 AM'
var result = this.timeFilter(input)
expect(result).toBe(expected)
})
it('can recollect a short time based on timestamp', function () {
var input = 121155
var expected = '10:39 AM'
var result1 = this.timeFilter(input)
expect(result1).toBe(expected)
var result2 = this.timeFilter(input)
expect(result2).toBe(expected)
})
})
describe('on the desktop website', function () {
beforeEach(function () {
Config.Mobile = false
this.timeFilter = this.$filter('time')
})
it('can create a medium-size time based on timestamp', function () {
var input = 1222
var expected = '1:20:22 AM'
var result = this.timeFilter(input)
expect(result).toBe(expected)
})
it('can recollect a medium-size time on timestamp', function () {
var input = 121155
var expected = '10:39:15 AM'
var result1 = this.timeFilter(input)
expect(result1).toBe(expected)
var result2 = this.timeFilter(input)
expect(result2).toBe(expected)
})
})
})

17
test/unit/userFirstNameFilterSpec.js → test/unit/filters/userFirstNameFilterSpec.js

@ -1,22 +1,21 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */ /* global describe, it, inject, expect, beforeEach */
describe('userFirstName filter', function () { describe('userFirstName filter', function () {
var $filter, _, userFirstNameFilter
beforeEach(module('myApp.filters')) beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_, ___) { beforeEach(inject(function (_$filter_, ___) {
$filter = _$filter_ this.$filter = _$filter_
_ = ___ this._ = ___
})) }))
beforeEach(function () { beforeEach(function () {
userFirstNameFilter = $filter('userFirstName') this.userFirstNameFilter = this.$filter('userFirstName')
}) })
it('displays user first name deleted', function () { it('displays user first name deleted', function () {
var expected = _('user_first_name_deleted') var expected = this._('user_first_name_deleted')
var actual = userFirstNameFilter(null) var actual = this.userFirstNameFilter(null)
expect(actual).toEqual(expected) expect(actual).toEqual(expected)
}) })
@ -26,7 +25,7 @@ describe('userFirstName filter', function () {
first_name: 'John' first_name: 'John'
} }
var expected = user.first_name var expected = user.first_name
var actual = userFirstNameFilter(user) var actual = this.userFirstNameFilter(user)
expect(actual).toEqual(expected) expect(actual).toEqual(expected)
}) })
@ -36,7 +35,7 @@ describe('userFirstName filter', function () {
last_name: 'Doe' last_name: 'Doe'
} }
var expected = user.last_name var expected = user.last_name
var actual = userFirstNameFilter(user) var actual = this.userFirstNameFilter(user)
expect(actual).toEqual(expected) expect(actual).toEqual(expected)
}) })

27
test/unit/userNameFilterSpec.js → test/unit/filters/userNameFilterSpec.js

@ -1,22 +1,21 @@
'use strict'
/* global describe, it, inject, expect, beforeEach */ /* global describe, it, inject, expect, beforeEach */
describe('userName filter', function () { describe('userName filter', function () {
var $filter, _, userNameFilter
beforeEach(module('myApp.filters')) beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_, ___) { beforeEach(inject(function (_$filter_, ___) {
$filter = _$filter_ this.$filter = _$filter_
_ = ___ this._ = ___
})) }))
beforeEach(function () { beforeEach(function () {
userNameFilter = $filter('userName') this.userNameFilter = this.$filter('userName')
}) })
it('displays user name deleted', function () { it('displays user name deleted', function () {
var expected = _('user_name_deleted') var expected = this._('user_name_deleted')
var actual = userNameFilter(null) var actual = this.userNameFilter(null)
expect(actual).toEqual(expected) expect(actual).toEqual(expected)
}) })
@ -26,7 +25,17 @@ describe('userName filter', function () {
first_name: 'John' first_name: 'John'
} }
var expected = user.first_name var expected = user.first_name
var actual = userNameFilter(user) var actual = this.userNameFilter(user)
expect(actual).toEqual(expected)
})
it('displays the last name', function () {
var user = {
last_name: 'Doe'
}
var expected = user.last_name
var actual = this.userNameFilter(user)
expect(actual).toEqual(expected) expect(actual).toEqual(expected)
}) })
@ -37,7 +46,7 @@ describe('userName filter', function () {
last_name: 'Doe' last_name: 'Doe'
} }
var expected = user.first_name + ' ' + user.last_name var expected = user.first_name + ' ' + user.last_name
var actual = userNameFilter(user) var actual = this.userNameFilter(user)
expect(actual).toEqual(expected) expect(actual).toEqual(expected)
}) })

141
test/unit/filters/userStatusFilterSpec.js

@ -0,0 +1,141 @@
'use strict'
/* global describe, it, inject, expect, beforeEach , tsNow*/
describe('userStatus filter', function () {
beforeEach(module('myApp.filters'))
beforeEach(inject(function (_$filter_, ___) {
this.$filter = _$filter_
this._ = ___
}))
beforeEach(function () {
this.userStatusFilter = this.$filter('userStatus')
})
it('can recognize support users', function () {
var input = { id: 1000 }
var expected = this._('user_status_support')
var result = this.userStatusFilter(input)
expect(result).toBe(expected)
})
it('can recognize service notifications', function () {
// id 777000 is the id of the service notifications channel
var input = { id: 777000 }
var expected = this._('user_status_service_notifications')
var result = this.userStatusFilter(input)
expect(result).toBe(expected)
})
describe('when the user is not a bot, it', function () {
it('can handle empty user statuses', function () {
var input = null
var expected = this._('user_status_long_ago')
var result = this.userStatusFilter(input)
expect(result).toBe(expected)
input = { id: 12321 }
result = this.userStatusFilter(input)
expect(result).toBe(expected)
input = { id: 12321, status: {} }
result = this.userStatusFilter(input)
expect(result).toBe(expected)
input = { id: 12321, status: {_: null} }
result = this.userStatusFilter(input)
expect(result).toBe(expected)
input = { id: 12321, status: {_: null}, pFlag: {} }
result = this.userStatusFilter(input)
expect(result).toBe(expected)
input = { id: 12321, status: {_: null}, pFlags: {bot: false} }
result = this.userStatusFilter(input)
expect(result).toBe(expected)
})
it('can display an online status', function () {
var input = { id: 12321, status: {_: 'userStatusOnline'} }
var expected = this._('user_status_online')
var result = this.userStatusFilter(input)
expect(result).toBe(expected)
})
it('can display that the user was recently online', function () {
var input = { id: 12321, status: {_: 'userStatusRecently'} }
var expected = this._('user_status_recently')
var result = this.userStatusFilter(input)
expect(result).toBe(expected)
})
it('can display that the user was offline since a certain time', function () {
var time = tsNow(true) - 360000 // 100 hours ago
var relativeTimeFilter = this.$filter('relativeTime')
var input = { id: 12321, status: {_: 'userStatusOffline', was_online: time} }
var expected = this._('user_status_last_seen', relativeTimeFilter(time))
var result = this.userStatusFilter(input)
expect(result).toBe(expected)
})
// Further testing of relativeTimeFilter is done in relativeTimeFilterSpec.js
it('can display that the user was online last week', function () {
var input = { id: 12321, status: {_: 'userStatusLastWeek'} }
var expected = this._('user_status_last_week')
var result = this.userStatusFilter(input)
expect(result).toBe(expected)
})
it('can display that the user was online last month', function () {
var input = { id: 12321, status: {_: 'userStatusLastMonth'} }
var expected = this._('user_status_last_month')
var result = this.userStatusFilter(input)
expect(result).toBe(expected)
})
})
describe('when the user is a bot', function () {
beforeEach(function () {
this.input = { id: 12321, status: {_: null}, pFlags: {bot: true} }
})
it('it can tell that the user is a bot', function () {
var expected = this._('user_status_bot')
var result = this.userStatusFilter(this.input)
expect(result).toBe(expected)
})
describe('and the bot has privacy settings', function () {
beforeEach(function () {
this.privacySettings = true
})
it('it can tell that it is a bot with no acces to messages', function () {
var expected = this._('user_status_bot_privacy')
var result = this.userStatusFilter(this.input, this.privacySettings)
expect(result).toBe(expected)
})
it('it can tell that it is a bot with acces to messages', function () {
// Flags indicate true/false
this.input.pFlags.bot_chat_history = true
var expected = this._('user_status_bot_noprivacy')
var result = this.userStatusFilter(this.input, this.privacySettings)
expect(result).toBe(expected)
})
})
})
})

1
test/unit/PhonebookContactsServiceSpec.js → test/unit/services/PhonebookContactsServiceSpec.js

@ -1,3 +1,4 @@
'use strict'
/* global describe, it, inject, expect, beforeEach, jasmine, xit */ /* global describe, it, inject, expect, beforeEach, jasmine, xit */
describe('PhonebookContactsService', function () { describe('PhonebookContactsService', function () {
Loading…
Cancel
Save