diff options
Diffstat (limited to 'test/unit/specs/services')
7 files changed, 311 insertions, 45 deletions
diff --git a/test/unit/specs/services/date_utils/date_utils.spec.js b/test/unit/specs/services/date_utils/date_utils.spec.js new file mode 100644 index 00000000..2d61dbac --- /dev/null +++ b/test/unit/specs/services/date_utils/date_utils.spec.js @@ -0,0 +1,40 @@ +import * as DateUtils from 'src/services/date_utils/date_utils.js' + +describe('DateUtils', () => { + describe('relativeTime', () => { + it('returns now with low enough amount of seconds', () => { + const futureTime = Date.now() + 20 * DateUtils.SECOND + const pastTime = Date.now() - 20 * DateUtils.SECOND + expect(DateUtils.relativeTime(futureTime, 30)).to.eql({ num: 0, key: 'time.now' }) + expect(DateUtils.relativeTime(pastTime, 30)).to.eql({ num: 0, key: 'time.now' }) + }) + + it('rounds down for past', () => { + const time = Date.now() - 1.8 * DateUtils.HOUR + expect(DateUtils.relativeTime(time)).to.eql({ num: 1, key: 'time.hour' }) + }) + + it('rounds up for future', () => { + const time = Date.now() + 1.8 * DateUtils.HOUR + expect(DateUtils.relativeTime(time)).to.eql({ num: 2, key: 'time.hours' }) + }) + + it('uses plural when necessary', () => { + const time = Date.now() - 3.8 * DateUtils.WEEK + expect(DateUtils.relativeTime(time)).to.eql({ num: 3, key: 'time.weeks' }) + }) + + it('works with date string', () => { + const time = Date.now() - 4 * DateUtils.MONTH + const dateString = new Date(time).toISOString() + expect(DateUtils.relativeTime(dateString)).to.eql({ num: 4, key: 'time.months' }) + }) + }) + + describe('relativeTimeShort', () => { + it('returns the short version of the same relative time', () => { + const time = Date.now() + 2 * DateUtils.YEAR + expect(DateUtils.relativeTimeShort(time)).to.eql({ num: 2, key: 'time.years_short' }) + }) + }) +}) diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js index 6245361c..49f378e2 100644 --- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js +++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js @@ -1,4 +1,4 @@ -import { parseStatus, parseUser, parseNotification } from '../../../../../src/services/entity_normalizer/entity_normalizer.service.js' +import { parseStatus, parseUser, parseNotification, addEmojis } from '../../../../../src/services/entity_normalizer/entity_normalizer.service.js' import mastoapidata from '../../../../fixtures/mastoapi.json' import qvitterapidata from '../../../../fixtures/statuses.json' @@ -129,7 +129,10 @@ const makeMockStatusMasto = (overrides = {}) => { tags: [], uri: 'https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639', url: 'https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639', - visibility: 'public' + visibility: 'public', + pleroma: { + local: true + } }, overrides) } @@ -143,11 +146,22 @@ const makeMockNotificationQvitter = (overrides = {}) => { }, overrides) } -parseNotification -parseUser -parseStatus -makeMockStatusQvitter -makeMockUserQvitter +const makeMockEmojiMasto = (overrides = [{}]) => { + return [ + Object.assign({ + shortcode: 'image', + static_url: 'https://example.com/image.png', + url: 'https://example.com/image.png', + visible_in_picker: false + }, overrides[0]), + Object.assign({ + shortcode: 'thinking', + static_url: 'https://example.com/think.png', + url: 'https://example.com/think.png', + visible_in_picker: false + }, overrides[1]) + ] +} describe('API Entities normalizer', () => { describe('parseStatus', () => { @@ -186,15 +200,15 @@ describe('API Entities normalizer', () => { }) it('sets nsfw for statuses with the #nsfw tag', () => { - const safe = makeMockStatusQvitter({id: '1', text: 'Hello oniichan'}) - const nsfw = makeMockStatusQvitter({id: '1', text: 'Hello oniichan #nsfw'}) + const safe = makeMockStatusQvitter({ id: '1', text: 'Hello oniichan' }) + const nsfw = makeMockStatusQvitter({ id: '1', text: 'Hello oniichan #nsfw' }) expect(parseStatus(safe).nsfw).to.eq(false) expect(parseStatus(nsfw).nsfw).to.eq(true) }) it('leaves existing nsfw settings alone', () => { - const nsfw = makeMockStatusQvitter({id: '1', text: 'Hello oniichan #nsfw', nsfw: false}) + const nsfw = makeMockStatusQvitter({ id: '1', text: 'Hello oniichan #nsfw', nsfw: false }) expect(parseStatus(nsfw).nsfw).to.eq(false) }) @@ -218,6 +232,22 @@ describe('API Entities normalizer', () => { expect(parsedRepeat).to.have.property('retweeted_status') expect(parsedRepeat).to.have.deep.property('retweeted_status.id', 'deadbeef') }) + + it('adds emojis to post content', () => { + const post = makeMockStatusMasto({ emojis: makeMockEmojiMasto(), content: 'Makes you think :thinking:' }) + + const parsedPost = parseStatus(post) + + expect(parsedPost).to.have.property('statusnet_html').that.contains('<img') + }) + + it('adds emojis to subject line', () => { + const post = makeMockStatusMasto({ emojis: makeMockEmojiMasto(), spoiler_text: 'CW: 300 IQ :thinking:' }) + + const parsedPost = parseStatus(post) + + expect(parsedPost).to.have.property('summary_html').that.contains('<img') + }) }) }) @@ -230,6 +260,31 @@ describe('API Entities normalizer', () => { expect(parseUser(local)).to.have.property('is_local', true) expect(parseUser(remote)).to.have.property('is_local', false) }) + + it('adds emojis to user name', () => { + const user = makeMockUserMasto({ emojis: makeMockEmojiMasto(), display_name: 'The :thinking: thinker' }) + + const parsedUser = parseUser(user) + + expect(parsedUser).to.have.property('name_html').that.contains('<img') + }) + + it('adds emojis to user bio', () => { + const user = makeMockUserMasto({ emojis: makeMockEmojiMasto(), note: 'Hello i like to :thinking: a lot' }) + + const parsedUser = parseUser(user) + + expect(parsedUser).to.have.property('description_html').that.contains('<img') + }) + + it('adds hide_follows and hide_followers user settings', () => { + const user = makeMockUserMasto({ pleroma: { hide_followers: true, hide_follows: false, hide_followers_count: false, hide_follows_count: true } }) + + expect(parseUser(user)).to.have.property('hide_followers', true) + expect(parseUser(user)).to.have.property('hide_follows', false) + expect(parseUser(user)).to.have.property('hide_followers_count', false) + expect(parseUser(user)).to.have.property('hide_follows_count', true) + }) }) // We currently use QvitterAPI notifications only, and especially due to MastoAPI lacking is_seen, support for MastoAPI @@ -267,4 +322,39 @@ describe('API Entities normalizer', () => { expect(parseNotification(notif)).to.have.deep.property('from_profile.id', 'spurdo') }) }) + + describe('MastoAPI emoji adder', () => { + const emojis = makeMockEmojiMasto() + const imageHtml = '<img src="https://example.com/image.png" alt="image" title="image" class="emoji" />' + .replace(/"/g, '\'') + const thinkHtml = '<img src="https://example.com/think.png" alt="thinking" title="thinking" class="emoji" />' + .replace(/"/g, '\'') + + it('correctly replaces shortcodes in supplied string', () => { + const result = addEmojis('This post has :image: emoji and :thinking: emoji', emojis) + expect(result).to.include(thinkHtml) + expect(result).to.include(imageHtml) + }) + + it('handles consecutive emojis correctly', () => { + const result = addEmojis('Lelel emoji spam :thinking::thinking::thinking::thinking:', emojis) + expect(result).to.include(thinkHtml + thinkHtml + thinkHtml + thinkHtml) + }) + + it('Doesn\'t replace nonexistent emojis', () => { + const result = addEmojis('Admin add the :tenshi: emoji', emojis) + expect(result).to.equal('Admin add the :tenshi: emoji') + }) + + it('Doesn\'t blow up on regex special characters', () => { + const emojis = makeMockEmojiMasto([{ + shortcode: 'c++' + }, { + shortcode: '[a-z] {|}*' + }]) + const result = addEmojis('This post has :c++: emoji and :[a-z] {|}*: emoji', emojis) + expect(result).to.include('title=\'c++\'') + expect(result).to.include('title=\'[a-z] {|}*\'') + }) + }) }) diff --git a/test/unit/specs/services/file_size_format/file_size_format.spec.js b/test/unit/specs/services/file_size_format/file_size_format.spec.js index 0a5a82b7..e02ac379 100644 --- a/test/unit/specs/services/file_size_format/file_size_format.spec.js +++ b/test/unit/specs/services/file_size_format/file_size_format.spec.js @@ -1,34 +1,34 @@ - import fileSizeFormatService from '../../../../../src/services/file_size_format/file_size_format.js' - describe('fileSizeFormat', () => { - it('Formats file size', () => { - const values = [1, 1024, 1048576, 1073741824, 1099511627776] - const expected = [ - { - num: 1, - unit: 'B' - }, - { - num: 1, - unit: 'KiB' - }, - { - num: 1, - unit: 'MiB' - }, - { - num: 1, - unit: 'GiB' - }, - { - num: 1, - unit: 'TiB' - } - ] +import fileSizeFormatService from '../../../../../src/services/file_size_format/file_size_format.js' +describe('fileSizeFormat', () => { + it('Formats file size', () => { + const values = [1, 1024, 1048576, 1073741824, 1099511627776] + const expected = [ + { + num: 1, + unit: 'B' + }, + { + num: 1, + unit: 'KiB' + }, + { + num: 1, + unit: 'MiB' + }, + { + num: 1, + unit: 'GiB' + }, + { + num: 1, + unit: 'TiB' + } + ] - var res = [] - for (var value in values) { - res.push(fileSizeFormatService.fileSizeFormat(values[value])) - } - expect(res).to.eql(expected) - }) - }) + var res = [] + for (var value in values) { + res.push(fileSizeFormatService.fileSizeFormat(values[value])) + } + expect(res).to.eql(expected) + }) +}) diff --git a/test/unit/specs/services/gesture_service/gesture_service.spec.js b/test/unit/specs/services/gesture_service/gesture_service.spec.js new file mode 100644 index 00000000..a91f95db --- /dev/null +++ b/test/unit/specs/services/gesture_service/gesture_service.spec.js @@ -0,0 +1,120 @@ +import GestureService from 'src/services/gesture_service/gesture_service.js' + +const mockTouchEvent = (x, y) => ({ + touches: [ + { + screenX: x, + screenY: y + } + ] +}) + +describe('GestureService', () => { + describe('swipeGesture', () => { + it('calls the callback on a successful swipe', () => { + let swiped = false + const callback = () => { swiped = true } + const gesture = GestureService.swipeGesture( + GestureService.DIRECTION_RIGHT, + callback + ) + + GestureService.beginSwipe(mockTouchEvent(100, 100), gesture) + GestureService.updateSwipe(mockTouchEvent(200, 100), gesture) + + expect(swiped).to.eql(true) + }) + + it('calls the callback only once per begin', () => { + let hits = 0 + const callback = () => { hits += 1 } + const gesture = GestureService.swipeGesture( + GestureService.DIRECTION_RIGHT, + callback + ) + + GestureService.beginSwipe(mockTouchEvent(100, 100), gesture) + GestureService.updateSwipe(mockTouchEvent(150, 100), gesture) + GestureService.updateSwipe(mockTouchEvent(200, 100), gesture) + + expect(hits).to.eql(1) + }) + + it('doesn\'t call the callback on an opposite swipe', () => { + let swiped = false + const callback = () => { swiped = true } + const gesture = GestureService.swipeGesture( + GestureService.DIRECTION_RIGHT, + callback + ) + + GestureService.beginSwipe(mockTouchEvent(100, 100), gesture) + GestureService.updateSwipe(mockTouchEvent(0, 100), gesture) + + expect(swiped).to.eql(false) + }) + + it('doesn\'t call the callback on a swipe below threshold', () => { + let swiped = false + const callback = () => { swiped = true } + const gesture = GestureService.swipeGesture( + GestureService.DIRECTION_RIGHT, + callback, + 100 + ) + + GestureService.beginSwipe(mockTouchEvent(100, 100), gesture) + GestureService.updateSwipe(mockTouchEvent(150, 100), gesture) + + expect(swiped).to.eql(false) + }) + + it('doesn\'t call the callback on a perpendicular swipe', () => { + let swiped = false + const callback = () => { swiped = true } + const gesture = GestureService.swipeGesture( + GestureService.DIRECTION_RIGHT, + callback, + 30, + 0.5 + ) + + GestureService.beginSwipe(mockTouchEvent(100, 100), gesture) + GestureService.updateSwipe(mockTouchEvent(150, 200), gesture) + + expect(swiped).to.eql(false) + }) + + it('calls the callback on perpendicular swipe if within tolerance', () => { + let swiped = false + const callback = () => { swiped = true } + const gesture = GestureService.swipeGesture( + GestureService.DIRECTION_RIGHT, + callback, + 30, + 2.0 + ) + + GestureService.beginSwipe(mockTouchEvent(100, 100), gesture) + GestureService.updateSwipe(mockTouchEvent(150, 150), gesture) + + expect(swiped).to.eql(true) + }) + + it('works with any arbitrary 2d directions', () => { + let swiped = false + const callback = () => { swiped = true } + const gesture = GestureService.swipeGesture( + [-1, -1], + callback, + 30, + 0.1 + ) + + GestureService.beginSwipe(mockTouchEvent(100, 100), gesture) + GestureService.updateSwipe(mockTouchEvent(60, 60), gesture) + + expect(swiped).to.eql(true) + }) + }) +}) diff --git a/test/unit/specs/services/notification_utils/notification_utils.spec.js b/test/unit/specs/services/notification_utils/notification_utils.spec.js index e945459e..1baa5fc9 100644 --- a/test/unit/specs/services/notification_utils/notification_utils.spec.js +++ b/test/unit/specs/services/notification_utils/notification_utils.spec.js @@ -9,14 +9,17 @@ describe('NotificationUtils', () => { notifications: { data: [ { + id: 1, action: { id: '1' }, type: 'like' }, { + id: 2, action: { id: '2' }, type: 'mention' }, { + id: 3, action: { id: '3' }, type: 'repeat' } @@ -35,10 +38,12 @@ describe('NotificationUtils', () => { const expected = [ { action: { id: '3' }, + id: 3, type: 'repeat' }, { action: { id: '1' }, + id: 1, type: 'like' } ] diff --git a/test/unit/specs/services/status_parser/status_parses.spec.js b/test/unit/specs/services/status_parser/status_parses.spec.js index 65808d84..7afd5042 100644 --- a/test/unit/specs/services/status_parser/status_parses.spec.js +++ b/test/unit/specs/services/status_parser/status_parses.spec.js @@ -1,7 +1,7 @@ -const example = '<div class="status-content">@<a href="https://sealion.club/user/4" class="h-card mention" title="dewoo">dwmatiz</a> <a href="https://social.heldscal.la/file/3deb764ada10ce64a61b7a070b75dac45f86d2d5bf213bf18873da71d8714d86.png" title="https://social.heldscal.la/file/3deb764ada10ce64a61b7a070b75dac45f86d2d5bf213bf18873da71d8714d86.png" class="attachment" id="attachment-159853" rel="nofollow external">https://social.heldscal.la/attachment/159853</a></div>' - import { removeAttachmentLinks } from '../../../../../src/services/status_parser/status_parser.js' +const example = '<div class="status-content">@<a href="https://sealion.club/user/4" class="h-card mention" title="dewoo">dwmatiz</a> <a href="https://social.heldscal.la/file/3deb764ada10ce64a61b7a070b75dac45f86d2d5bf213bf18873da71d8714d86.png" title="https://social.heldscal.la/file/3deb764ada10ce64a61b7a070b75dac45f86d2d5bf213bf18873da71d8714d86.png" class="attachment" id="attachment-159853" rel="nofollow external">https://social.heldscal.la/attachment/159853</a></div>' + describe('statusParser.removeAttachmentLinks', () => { const exampleWithoutAttachmentLinks = '<div class="status-content">@<a href="https://sealion.club/user/4" class="h-card mention" title="dewoo">dwmatiz</a> </div>' diff --git a/test/unit/specs/services/version/version.service.spec.js b/test/unit/specs/services/version/version.service.spec.js new file mode 100644 index 00000000..519145ee --- /dev/null +++ b/test/unit/specs/services/version/version.service.spec.js @@ -0,0 +1,11 @@ +import { extractCommit } from 'src/services/version/version.service.js' + +describe('extractCommit', () => { + it('return short commit hash following "-g" characters', () => { + expect(extractCommit('1.0.0-45-g5e7aeebc')).to.eql('5e7aeebc') + }) + + it('return short commit hash without branch name', () => { + expect(extractCommit('1.0.0-45-g5e7aeebc-branch')).to.eql('5e7aeebc') + }) +}) |
