Merge develop and fix conflict
This commit is contained in:
commit
0ab828bb30
25 changed files with 2489 additions and 312 deletions
1582
test/fixtures/mastoapi.json
vendored
Normal file
1582
test/fixtures/mastoapi.json
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,76 +1,31 @@
|
|||
import { cloneDeep } from 'lodash'
|
||||
import { defaultState, mutations, findMaxId, prepareStatus, statusType } from '../../../../src/modules/statuses.js'
|
||||
import { defaultState, mutations, prepareStatus } from '../../../../src/modules/statuses.js'
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
const makeMockStatus = ({id, text, is_post_verb = true}) => {
|
||||
const makeMockStatus = ({id, text, type = 'status'}) => {
|
||||
return {
|
||||
id,
|
||||
user: {id: 0},
|
||||
user: {id: '0'},
|
||||
name: 'status',
|
||||
text: text || `Text number ${id}`,
|
||||
fave_num: 0,
|
||||
uri: '',
|
||||
is_post_verb,
|
||||
type,
|
||||
attentions: []
|
||||
}
|
||||
}
|
||||
|
||||
describe('Statuses.statusType', () => {
|
||||
it('identifies favorites', () => {
|
||||
const fav = {
|
||||
uri: 'tag:soykaf.com,2016-08-21:fave:2558:note:339495:2016-08-21T16:54:04+00:00'
|
||||
}
|
||||
|
||||
const mastoFav = {
|
||||
uri: 'tag:mastodon.social,2016-11-27:objectId=73903:objectType=Favourite'
|
||||
}
|
||||
|
||||
expect(statusType(fav)).to.eql('favorite')
|
||||
expect(statusType(mastoFav)).to.eql('favorite')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Statuses.prepareStatus', () => {
|
||||
it('sets nsfw for statuses with the #nsfw tag', () => {
|
||||
const safe = makeMockStatus({id: 1, text: 'Hello oniichan'})
|
||||
const nsfw = makeMockStatus({id: 1, text: 'Hello oniichan #nsfw'})
|
||||
|
||||
expect(prepareStatus(safe).nsfw).to.eq(false)
|
||||
expect(prepareStatus(nsfw).nsfw).to.eq(true)
|
||||
})
|
||||
|
||||
it('leaves existing nsfw settings alone', () => {
|
||||
const nsfw = makeMockStatus({id: 1, text: 'Hello oniichan #nsfw'})
|
||||
nsfw.nsfw = false
|
||||
|
||||
expect(prepareStatus(nsfw).nsfw).to.eq(false)
|
||||
})
|
||||
|
||||
it('sets deleted flag to false', () => {
|
||||
const aStatus = makeMockStatus({id: 1, text: 'Hello oniichan'})
|
||||
const aStatus = makeMockStatus({id: '1', text: 'Hello oniichan'})
|
||||
expect(prepareStatus(aStatus).deleted).to.eq(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Statuses.findMaxId', () => {
|
||||
it('returns the largest id in any of the given arrays', () => {
|
||||
const statusesOne = [{ id: 100 }, { id: 2 }]
|
||||
const statusesTwo = [{ id: 3 }]
|
||||
|
||||
const maxId = findMaxId(statusesOne, statusesTwo)
|
||||
expect(maxId).to.eq(100)
|
||||
})
|
||||
|
||||
it('returns undefined for empty arrays', () => {
|
||||
const maxId = findMaxId([], [])
|
||||
expect(maxId).to.eq(undefined)
|
||||
})
|
||||
})
|
||||
|
||||
describe('The Statuses module', () => {
|
||||
it('adds the status to allStatuses and to the given timeline', () => {
|
||||
const state = cloneDeep(defaultState)
|
||||
const status = makeMockStatus({id: 1})
|
||||
const status = makeMockStatus({id: '1'})
|
||||
|
||||
mutations.addNewStatuses(state, { statuses: [status], timeline: 'public' })
|
||||
|
||||
|
@ -82,7 +37,7 @@ describe('The Statuses module', () => {
|
|||
|
||||
it('counts the status as new if it has not been seen on this timeline', () => {
|
||||
const state = cloneDeep(defaultState)
|
||||
const status = makeMockStatus({id: 1})
|
||||
const status = makeMockStatus({id: '1'})
|
||||
|
||||
mutations.addNewStatuses(state, { statuses: [status], timeline: 'public' })
|
||||
mutations.addNewStatuses(state, { statuses: [status], timeline: 'friends' })
|
||||
|
@ -100,7 +55,7 @@ describe('The Statuses module', () => {
|
|||
|
||||
it('add the statuses to allStatuses if no timeline is given', () => {
|
||||
const state = cloneDeep(defaultState)
|
||||
const status = makeMockStatus({id: 1})
|
||||
const status = makeMockStatus({id: '1'})
|
||||
|
||||
mutations.addNewStatuses(state, { statuses: [status] })
|
||||
|
||||
|
@ -112,7 +67,7 @@ describe('The Statuses module', () => {
|
|||
|
||||
it('adds the status to allStatuses and to the given timeline, directly visible', () => {
|
||||
const state = cloneDeep(defaultState)
|
||||
const status = makeMockStatus({id: 1})
|
||||
const status = makeMockStatus({id: '1'})
|
||||
|
||||
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
|
||||
|
||||
|
@ -124,10 +79,10 @@ describe('The Statuses module', () => {
|
|||
|
||||
it('removes statuses by tag on deletion', () => {
|
||||
const state = cloneDeep(defaultState)
|
||||
const status = makeMockStatus({id: 1})
|
||||
const otherStatus = makeMockStatus({id: 3})
|
||||
const status = makeMockStatus({id: '1'})
|
||||
const otherStatus = makeMockStatus({id: '3'})
|
||||
status.uri = 'xxx'
|
||||
const deletion = makeMockStatus({id: 2, is_post_verb: false})
|
||||
const deletion = makeMockStatus({id: '2', type: 'deletion'})
|
||||
deletion.text = 'Dolus deleted notice {{tag:gs.smuglo.li,2016-11-18:noticeId=1038007:objectType=note}}.'
|
||||
deletion.uri = 'xxx'
|
||||
|
||||
|
@ -137,36 +92,36 @@ describe('The Statuses module', () => {
|
|||
expect(state.allStatuses).to.eql([otherStatus])
|
||||
expect(state.timelines.public.statuses).to.eql([otherStatus])
|
||||
expect(state.timelines.public.visibleStatuses).to.eql([otherStatus])
|
||||
expect(state.timelines.public.maxId).to.eql(3)
|
||||
expect(state.timelines.public.maxId).to.eql('3')
|
||||
})
|
||||
|
||||
it('does not update the maxId when the noIdUpdate flag is set', () => {
|
||||
const state = cloneDeep(defaultState)
|
||||
const status = makeMockStatus({id: 1})
|
||||
const secondStatus = makeMockStatus({id: 2})
|
||||
const status = makeMockStatus({id: '1'})
|
||||
const secondStatus = makeMockStatus({id: '2'})
|
||||
|
||||
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
|
||||
expect(state.timelines.public.maxId).to.eql(1)
|
||||
expect(state.timelines.public.maxId).to.eql('1')
|
||||
|
||||
mutations.addNewStatuses(state, { statuses: [secondStatus], showImmediately: true, timeline: 'public', noIdUpdate: true })
|
||||
expect(state.timelines.public.statuses).to.eql([secondStatus, status])
|
||||
expect(state.timelines.public.visibleStatuses).to.eql([secondStatus, status])
|
||||
expect(state.timelines.public.maxId).to.eql(1)
|
||||
expect(state.timelines.public.maxId).to.eql('1')
|
||||
})
|
||||
|
||||
it('keeps a descending by id order in timeline.visibleStatuses and timeline.statuses', () => {
|
||||
const state = cloneDeep(defaultState)
|
||||
const nonVisibleStatus = makeMockStatus({id: 1})
|
||||
const status = makeMockStatus({id: 3})
|
||||
const statusTwo = makeMockStatus({id: 2})
|
||||
const statusThree = makeMockStatus({id: 4})
|
||||
const nonVisibleStatus = makeMockStatus({id: '1'})
|
||||
const status = makeMockStatus({id: '3'})
|
||||
const statusTwo = makeMockStatus({id: '2'})
|
||||
const statusThree = makeMockStatus({id: '4'})
|
||||
|
||||
mutations.addNewStatuses(state, { statuses: [nonVisibleStatus], showImmediately: false, timeline: 'public' })
|
||||
|
||||
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
|
||||
mutations.addNewStatuses(state, { statuses: [statusTwo], showImmediately: true, timeline: 'public' })
|
||||
|
||||
expect(state.timelines.public.minVisibleId).to.equal(2)
|
||||
expect(state.timelines.public.minVisibleId).to.equal('2')
|
||||
|
||||
mutations.addNewStatuses(state, { statuses: [statusThree], showImmediately: true, timeline: 'public' })
|
||||
|
||||
|
@ -176,9 +131,9 @@ describe('The Statuses module', () => {
|
|||
|
||||
it('splits retweets from their status and links them', () => {
|
||||
const state = cloneDeep(defaultState)
|
||||
const status = makeMockStatus({id: 1})
|
||||
const retweet = makeMockStatus({id: 2, is_post_verb: false})
|
||||
const modStatus = makeMockStatus({id: 1, text: 'something else'})
|
||||
const status = makeMockStatus({id: '1'})
|
||||
const retweet = makeMockStatus({id: '2', type: 'retweet'})
|
||||
const modStatus = makeMockStatus({id: '1', text: 'something else'})
|
||||
|
||||
retweet.retweeted_status = status
|
||||
|
||||
|
@ -187,22 +142,22 @@ describe('The Statuses module', () => {
|
|||
expect(state.timelines.public.visibleStatuses).to.have.length(1)
|
||||
expect(state.timelines.public.statuses).to.have.length(1)
|
||||
expect(state.allStatuses).to.have.length(2)
|
||||
expect(state.allStatuses[0].id).to.equal(1)
|
||||
expect(state.allStatuses[1].id).to.equal(2)
|
||||
expect(state.allStatuses[0].id).to.equal('1')
|
||||
expect(state.allStatuses[1].id).to.equal('2')
|
||||
|
||||
// It refers to the modified status.
|
||||
mutations.addNewStatuses(state, { statuses: [modStatus], timeline: 'public' })
|
||||
expect(state.allStatuses).to.have.length(2)
|
||||
expect(state.allStatuses[0].id).to.equal(1)
|
||||
expect(state.allStatuses[0].id).to.equal('1')
|
||||
expect(state.allStatuses[0].text).to.equal(modStatus.text)
|
||||
expect(state.allStatuses[1].id).to.equal(2)
|
||||
expect(state.allStatuses[1].id).to.equal('2')
|
||||
expect(retweet.retweeted_status.text).to.eql(modStatus.text)
|
||||
})
|
||||
|
||||
it('replaces existing statuses with the same id', () => {
|
||||
const state = cloneDeep(defaultState)
|
||||
const status = makeMockStatus({id: 1})
|
||||
const modStatus = makeMockStatus({id: 1, text: 'something else'})
|
||||
const status = makeMockStatus({id: '1'})
|
||||
const modStatus = makeMockStatus({id: '1', text: 'something else'})
|
||||
|
||||
// Add original status
|
||||
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
|
||||
|
@ -218,9 +173,9 @@ describe('The Statuses module', () => {
|
|||
|
||||
it('replaces existing statuses with the same id, coming from a retweet', () => {
|
||||
const state = cloneDeep(defaultState)
|
||||
const status = makeMockStatus({id: 1})
|
||||
const modStatus = makeMockStatus({id: 1, text: 'something else'})
|
||||
const retweet = makeMockStatus({id: 2, is_post_verb: false})
|
||||
const status = makeMockStatus({id: '1'})
|
||||
const modStatus = makeMockStatus({id: '1', text: 'something else'})
|
||||
const retweet = makeMockStatus({id: '2', type: 'retweet'})
|
||||
retweet.retweeted_status = modStatus
|
||||
|
||||
// Add original status
|
||||
|
@ -239,15 +194,15 @@ describe('The Statuses module', () => {
|
|||
|
||||
it('handles favorite actions', () => {
|
||||
const state = cloneDeep(defaultState)
|
||||
const status = makeMockStatus({id: 1})
|
||||
const status = makeMockStatus({id: '1'})
|
||||
|
||||
const favorite = {
|
||||
id: 2,
|
||||
is_post_verb: false,
|
||||
id: '2',
|
||||
type: 'favorite',
|
||||
in_reply_to_status_id: '1', // The API uses strings here...
|
||||
uri: 'tag:shitposter.club,2016-08-21:fave:3895:note:773501:2016-08-21T16:52:15+00:00',
|
||||
text: 'a favorited something by b',
|
||||
user: { id: 99 }
|
||||
user: { id: '99' }
|
||||
}
|
||||
|
||||
mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
|
||||
|
@ -266,12 +221,12 @@ describe('The Statuses module', () => {
|
|||
|
||||
// If something is favorited by the current user, it also sets the 'favorited' property but does not increment counter to avoid over-counting. Counter is incremented (updated, really) via response to the favorite request.
|
||||
const user = {
|
||||
id: 1
|
||||
id: '1'
|
||||
}
|
||||
|
||||
const ownFavorite = {
|
||||
id: 3,
|
||||
is_post_verb: false,
|
||||
id: '3',
|
||||
type: 'favorite',
|
||||
in_reply_to_status_id: '1', // The API uses strings here...
|
||||
uri: 'tag:shitposter.club,2016-08-21:fave:3895:note:773501:2016-08-21T16:52:15+00:00',
|
||||
text: 'a favorited something by b',
|
||||
|
@ -287,16 +242,16 @@ describe('The Statuses module', () => {
|
|||
|
||||
describe('notifications', () => {
|
||||
it('removes a notification when the notice gets removed', () => {
|
||||
const user = { id: 1 }
|
||||
const user = { id: '1' }
|
||||
const state = cloneDeep(defaultState)
|
||||
const status = makeMockStatus({id: 1})
|
||||
const otherStatus = makeMockStatus({id: 3})
|
||||
const mentionedStatus = makeMockStatus({id: 2})
|
||||
const status = makeMockStatus({id: '1'})
|
||||
const otherStatus = makeMockStatus({id: '3'})
|
||||
const mentionedStatus = makeMockStatus({id: '2'})
|
||||
mentionedStatus.attentions = [user]
|
||||
mentionedStatus.uri = 'xxx'
|
||||
otherStatus.attentions = [user]
|
||||
|
||||
const deletion = makeMockStatus({id: 4, is_post_verb: false})
|
||||
const deletion = makeMockStatus({id: '4', type: 'deletion'})
|
||||
deletion.text = 'Dolus deleted notice {{tag:gs.smuglo.li,2016-11-18:noticeId=1038007:objectType=note}}.'
|
||||
deletion.uri = 'xxx'
|
||||
|
||||
|
@ -305,10 +260,12 @@ describe('The Statuses module', () => {
|
|||
state,
|
||||
{
|
||||
notifications: [{
|
||||
ntype: 'mention',
|
||||
from_profile: { id: '2' },
|
||||
id: '998',
|
||||
type: 'mention',
|
||||
status: otherStatus,
|
||||
notice: otherStatus,
|
||||
is_seen: false
|
||||
action: otherStatus,
|
||||
seen: false
|
||||
}]
|
||||
})
|
||||
|
||||
|
@ -317,10 +274,12 @@ describe('The Statuses module', () => {
|
|||
state,
|
||||
{
|
||||
notifications: [{
|
||||
ntype: 'mention',
|
||||
from_profile: { id: '2' },
|
||||
id: '999',
|
||||
type: 'mention',
|
||||
status: mentionedStatus,
|
||||
notice: mentionedStatus,
|
||||
is_seen: false
|
||||
action: mentionedStatus,
|
||||
seen: false
|
||||
}]
|
||||
})
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ describe('The users module', () => {
|
|||
describe('mutations', () => {
|
||||
it('adds new users to the set, merging in new information for old users', () => {
|
||||
const state = cloneDeep(defaultState)
|
||||
const user = { id: 1, name: 'Guy' }
|
||||
const modUser = { id: 1, name: 'Dude' }
|
||||
const user = { id: '1', name: 'Guy' }
|
||||
const modUser = { id: '1', name: 'Dude' }
|
||||
|
||||
mutations.addNewUsers(state, [user])
|
||||
expect(state.users).to.have.length(1)
|
||||
|
@ -21,7 +21,7 @@ describe('The users module', () => {
|
|||
|
||||
it('sets a mute bit on users', () => {
|
||||
const state = cloneDeep(defaultState)
|
||||
const user = { id: 1, name: 'Guy' }
|
||||
const user = { id: '1', name: 'Guy' }
|
||||
|
||||
mutations.addNewUsers(state, [user])
|
||||
mutations.setMuted(state, {user, muted: true})
|
||||
|
@ -38,11 +38,11 @@ describe('The users module', () => {
|
|||
it('returns user with matching screen_name', () => {
|
||||
const state = {
|
||||
users: [
|
||||
{ screen_name: 'Guy', id: 1 }
|
||||
{ screen_name: 'Guy', id: '1' }
|
||||
]
|
||||
}
|
||||
const name = 'Guy'
|
||||
const expected = { screen_name: 'Guy', id: 1 }
|
||||
const expected = { screen_name: 'Guy', id: '1' }
|
||||
expect(getters.userByName(state)(name)).to.eql(expected)
|
||||
})
|
||||
})
|
||||
|
@ -51,11 +51,11 @@ describe('The users module', () => {
|
|||
it('returns user with matching id', () => {
|
||||
const state = {
|
||||
users: [
|
||||
{ screen_name: 'Guy', id: 1 }
|
||||
{ screen_name: 'Guy', id: '1' }
|
||||
]
|
||||
}
|
||||
const id = 1
|
||||
const expected = { screen_name: 'Guy', id: 1 }
|
||||
const id = '1'
|
||||
const expected = { screen_name: 'Guy', id: '1' }
|
||||
expect(getters.userById(state)(id)).to.eql(expected)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -0,0 +1,270 @@
|
|||
import { parseStatus, parseUser, parseNotification } from '../../../../../src/services/entity_normalizer/entity_normalizer.service.js'
|
||||
import mastoapidata from '../../../../fixtures/mastoapi.json'
|
||||
import qvitterapidata from '../../../../fixtures/statuses.json'
|
||||
|
||||
const makeMockStatusQvitter = (overrides = {}) => {
|
||||
return Object.assign({
|
||||
activity_type: 'post',
|
||||
attachments: [],
|
||||
attentions: [],
|
||||
created_at: 'Tue Jan 15 13:57:56 +0000 2019',
|
||||
external_url: 'https://ap.example/whatever',
|
||||
fave_num: 1,
|
||||
favorited: false,
|
||||
id: '10335970',
|
||||
in_reply_to_ostatus_uri: null,
|
||||
in_reply_to_profileurl: null,
|
||||
in_reply_to_screen_name: null,
|
||||
in_reply_to_status_id: null,
|
||||
in_reply_to_user_id: null,
|
||||
is_local: false,
|
||||
is_post_verb: true,
|
||||
possibly_sensitive: false,
|
||||
repeat_num: 0,
|
||||
repeated: false,
|
||||
statusnet_conversation_id: '16300488',
|
||||
statusnet_html: '<p>haha benis</p>',
|
||||
summary: null,
|
||||
tags: [],
|
||||
text: 'haha benis',
|
||||
uri: 'https://ap.example/whatever',
|
||||
user: makeMockUserQvitter(),
|
||||
visibility: 'public'
|
||||
}, overrides)
|
||||
}
|
||||
|
||||
const makeMockUserQvitter = (overrides = {}) => {
|
||||
return Object.assign({
|
||||
background_image: null,
|
||||
cover_photo: '',
|
||||
created_at: 'Mon Jan 14 13:56:51 +0000 2019',
|
||||
default_scope: 'public',
|
||||
description: 'ebin',
|
||||
description_html: '<p>ebin</p>',
|
||||
favourites_count: 0,
|
||||
fields: [],
|
||||
followers_count: 1,
|
||||
following: true,
|
||||
follows_you: true,
|
||||
friends_count: 1,
|
||||
id: '60717',
|
||||
is_local: false,
|
||||
locked: false,
|
||||
name: 'Spurdo :ebin:',
|
||||
name_html: 'Spurdo <img src="whatever">',
|
||||
no_rich_text: false,
|
||||
pleroma: { confirmation_pending: false, tags: [] },
|
||||
profile_image_url: 'https://ap.example/whatever',
|
||||
profile_image_url_https: 'https://ap.example/whatever',
|
||||
profile_image_url_original: 'https://ap.example/whatever',
|
||||
profile_image_url_profile_size: 'https://ap.example/whatever',
|
||||
rights: { delete_others_notice: false },
|
||||
screen_name: 'spurdo@ap.example',
|
||||
statuses_count: 46,
|
||||
statusnet_blocking: false,
|
||||
statusnet_profile_url: ''
|
||||
}, overrides)
|
||||
}
|
||||
|
||||
const makeMockUserMasto = (overrides = {}) => {
|
||||
return Object.assign({
|
||||
acct: 'hj',
|
||||
avatar:
|
||||
'https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png',
|
||||
avatar_static:
|
||||
'https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png',
|
||||
bot: false,
|
||||
created_at: '2017-12-17T21:54:14.000Z',
|
||||
display_name: 'whatever whatever whatever witch',
|
||||
emojis: [],
|
||||
fields: [],
|
||||
followers_count: 705,
|
||||
following_count: 326,
|
||||
header:
|
||||
'https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png',
|
||||
header_static:
|
||||
'https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png',
|
||||
id: '1',
|
||||
locked: false,
|
||||
note:
|
||||
'Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is <span><a data-user="1" href="https://shigusegubu.club/users/hj">@<span>hj</span></a></span>:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it\'s truly private matter and you\'re instance\'s admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.',
|
||||
pleroma: { confirmation_pending: false, tags: null },
|
||||
source: { note: '', privacy: 'public', sensitive: false },
|
||||
statuses_count: 41775,
|
||||
url: 'https://shigusegubu.club/users/hj',
|
||||
username: 'hj'
|
||||
}, overrides)
|
||||
}
|
||||
|
||||
const makeMockStatusMasto = (overrides = {}) => {
|
||||
return Object.assign({
|
||||
account: makeMockUserMasto(),
|
||||
application: { name: 'Web', website: null },
|
||||
content:
|
||||
'<span><a data-user="14660" href="https://pleroma.soykaf.com/users/sampo">@<span>sampo</span></a></span> god i wish i was there',
|
||||
created_at: '2019-01-17T16:29:23.000Z',
|
||||
emojis: [],
|
||||
favourited: false,
|
||||
favourites_count: 1,
|
||||
id: '10423476',
|
||||
in_reply_to_account_id: '14660',
|
||||
in_reply_to_id: '10423197',
|
||||
language: null,
|
||||
media_attachments: [],
|
||||
mentions: [
|
||||
{
|
||||
acct: 'sampo@pleroma.soykaf.com',
|
||||
id: '14660',
|
||||
url: 'https://pleroma.soykaf.com/users/sampo',
|
||||
username: 'sampo'
|
||||
}
|
||||
],
|
||||
muted: false,
|
||||
reblog: null,
|
||||
reblogged: false,
|
||||
reblogs_count: 0,
|
||||
replies_count: 0,
|
||||
sensitive: false,
|
||||
spoiler_text: '',
|
||||
tags: [],
|
||||
uri: 'https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639',
|
||||
url: 'https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639',
|
||||
visibility: 'public'
|
||||
}, overrides)
|
||||
}
|
||||
|
||||
const makeMockNotificationQvitter = (overrides = {}) => {
|
||||
return Object.assign({
|
||||
notice: makeMockStatusQvitter(),
|
||||
ntype: 'follow',
|
||||
from_profile: makeMockUserQvitter(),
|
||||
is_seen: 0,
|
||||
id: 123
|
||||
}, overrides)
|
||||
}
|
||||
|
||||
parseNotification
|
||||
parseUser
|
||||
parseStatus
|
||||
makeMockStatusQvitter
|
||||
makeMockUserQvitter
|
||||
|
||||
describe('API Entities normalizer', () => {
|
||||
describe('parseStatus', () => {
|
||||
describe('QVitter preprocessing', () => {
|
||||
it('doesn\'t blow up', () => {
|
||||
const parsed = qvitterapidata.map(parseStatus)
|
||||
expect(parsed.length).to.eq(qvitterapidata.length)
|
||||
})
|
||||
|
||||
it('identifies favorites', () => {
|
||||
const fav = {
|
||||
uri: 'tag:soykaf.com,2016-08-21:fave:2558:note:339495:2016-08-21T16:54:04+00:00',
|
||||
is_post_verb: false
|
||||
}
|
||||
|
||||
const mastoFav = {
|
||||
uri: 'tag:mastodon.social,2016-11-27:objectId=73903:objectType=Favourite',
|
||||
is_post_verb: false
|
||||
}
|
||||
|
||||
expect(parseStatus(makeMockStatusQvitter(fav))).to.have.property('type', 'favorite')
|
||||
expect(parseStatus(makeMockStatusQvitter(mastoFav))).to.have.property('type', 'favorite')
|
||||
})
|
||||
|
||||
it('processes repeats correctly', () => {
|
||||
const post = makeMockStatusQvitter({ retweeted_status: null, id: 'deadbeef' })
|
||||
const repeat = makeMockStatusQvitter({ retweeted_status: post, is_post_verb: false, id: 'foobar' })
|
||||
|
||||
const parsedPost = parseStatus(post)
|
||||
const parsedRepeat = parseStatus(repeat)
|
||||
|
||||
expect(parsedPost).to.have.property('type', 'status')
|
||||
expect(parsedRepeat).to.have.property('type', 'retweet')
|
||||
expect(parsedRepeat).to.have.property('retweeted_status')
|
||||
expect(parsedRepeat).to.have.deep.property('retweeted_status.id', 'deadbeef')
|
||||
})
|
||||
|
||||
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'})
|
||||
|
||||
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})
|
||||
|
||||
expect(parseStatus(nsfw).nsfw).to.eq(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Mastoapi preprocessing and converting', () => {
|
||||
it('doesn\'t blow up', () => {
|
||||
const parsed = mastoapidata.map(parseStatus)
|
||||
expect(parsed.length).to.eq(mastoapidata.length)
|
||||
})
|
||||
|
||||
it('processes repeats correctly', () => {
|
||||
const post = makeMockStatusMasto({ reblog: null, id: 'deadbeef' })
|
||||
const repeat = makeMockStatusMasto({ reblog: post, id: 'foobar' })
|
||||
|
||||
const parsedPost = parseStatus(post)
|
||||
const parsedRepeat = parseStatus(repeat)
|
||||
|
||||
expect(parsedPost).to.have.property('type', 'status')
|
||||
expect(parsedRepeat).to.have.property('type', 'retweet')
|
||||
expect(parsedRepeat).to.have.property('retweeted_status')
|
||||
expect(parsedRepeat).to.have.deep.property('retweeted_status.id', 'deadbeef')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// Statuses generally already contain some info regarding users and there's nearly 1:1 mapping, so very little to test
|
||||
describe('parseUsers (MastoAPI)', () => {
|
||||
it('sets correct is_local for users depending on their screen_name', () => {
|
||||
const local = makeMockUserMasto({ acct: 'foo' })
|
||||
const remote = makeMockUserMasto({ acct: 'foo@bar.baz' })
|
||||
|
||||
expect(parseUser(local)).to.have.property('is_local', true)
|
||||
expect(parseUser(remote)).to.have.property('is_local', false)
|
||||
})
|
||||
})
|
||||
|
||||
// We currently use QvitterAPI notifications only, and especially due to MastoAPI lacking is_seen, support for MastoAPI
|
||||
// is more of an afterthought
|
||||
describe('parseNotifications (QvitterAPI)', () => {
|
||||
it('correctly normalizes data to FE\'s format', () => {
|
||||
const notif = makeMockNotificationQvitter({
|
||||
id: 123,
|
||||
notice: makeMockStatusQvitter({ id: 444 }),
|
||||
from_profile: makeMockUserQvitter({ id: 'spurdo' })
|
||||
})
|
||||
expect(parseNotification(notif)).to.have.property('id', '123')
|
||||
expect(parseNotification(notif)).to.have.property('seen', false)
|
||||
expect(parseNotification(notif)).to.have.deep.property('status.id', '444')
|
||||
expect(parseNotification(notif)).to.have.deep.property('action.id', '444')
|
||||
expect(parseNotification(notif)).to.have.deep.property('from_profile.id', 'spurdo')
|
||||
})
|
||||
|
||||
it('correctly normalizes favorite notifications', () => {
|
||||
const notif = makeMockNotificationQvitter({
|
||||
id: 123,
|
||||
ntype: 'like',
|
||||
notice: makeMockStatusQvitter({
|
||||
id: 444,
|
||||
favorited_status: makeMockStatusQvitter({ id: 4412 })
|
||||
}),
|
||||
is_seen: 1,
|
||||
from_profile: makeMockUserQvitter({ id: 'spurdo' })
|
||||
})
|
||||
expect(parseNotification(notif)).to.have.property('id', '123')
|
||||
expect(parseNotification(notif)).to.have.property('type', 'like')
|
||||
expect(parseNotification(notif)).to.have.property('seen', true)
|
||||
expect(parseNotification(notif)).to.have.deep.property('status.id', '4412')
|
||||
expect(parseNotification(notif)).to.have.deep.property('action.id', '444')
|
||||
expect(parseNotification(notif)).to.have.deep.property('from_profile.id', 'spurdo')
|
||||
})
|
||||
})
|
||||
})
|
|
@ -9,15 +9,15 @@ describe('NotificationUtils', () => {
|
|||
notifications: {
|
||||
data: [
|
||||
{
|
||||
action: { id: 1 },
|
||||
action: { id: '1' },
|
||||
type: 'like'
|
||||
},
|
||||
{
|
||||
action: { id: 2 },
|
||||
action: { id: '2' },
|
||||
type: 'mention'
|
||||
},
|
||||
{
|
||||
action: { id: 3 },
|
||||
action: { id: '3' },
|
||||
type: 'repeat'
|
||||
}
|
||||
]
|
||||
|
@ -34,11 +34,11 @@ describe('NotificationUtils', () => {
|
|||
}
|
||||
const expected = [
|
||||
{
|
||||
action: { id: 3 },
|
||||
action: { id: '3' },
|
||||
type: 'repeat'
|
||||
},
|
||||
{
|
||||
action: { id: 1 },
|
||||
action: { id: '1' },
|
||||
type: 'like'
|
||||
}
|
||||
]
|
||||
|
@ -54,12 +54,12 @@ describe('NotificationUtils', () => {
|
|||
notifications: {
|
||||
data: [
|
||||
{
|
||||
action: { id: 1 },
|
||||
action: { id: '1' },
|
||||
type: 'like',
|
||||
seen: false
|
||||
},
|
||||
{
|
||||
action: { id: 2 },
|
||||
action: { id: '2' },
|
||||
type: 'mention',
|
||||
seen: true
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ describe('NotificationUtils', () => {
|
|||
}
|
||||
const expected = [
|
||||
{
|
||||
action: { id: 1 },
|
||||
action: { id: '1' },
|
||||
type: 'like',
|
||||
seen: false
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue