Merge branch 'chat-refactor' into sonarqube-cleanup
This commit is contained in:
commit
56efd36759
79 changed files with 3228 additions and 2094 deletions
|
|
@ -37,8 +37,8 @@ describe('routes', () => {
|
|||
|
||||
const matchedComponents = router.currentRoute.value.matched
|
||||
|
||||
expect(matchedComponents[0].components.default.name).to.eql(
|
||||
'AsyncComponentWrapper',
|
||||
expect(matchedComponents[0].components.default.__file).to.contain(
|
||||
'user_profile.vue',
|
||||
)
|
||||
})
|
||||
|
||||
|
|
@ -47,8 +47,8 @@ describe('routes', () => {
|
|||
|
||||
const matchedComponents = router.currentRoute.value.matched
|
||||
|
||||
expect(matchedComponents[0].components.default.name).to.eql(
|
||||
'AsyncComponentWrapper',
|
||||
expect(matchedComponents[0].components.default.__file).to.contain(
|
||||
'user_profile.vue',
|
||||
)
|
||||
})
|
||||
|
||||
|
|
@ -56,9 +56,8 @@ describe('routes', () => {
|
|||
await router.push('/lists')
|
||||
|
||||
const matchedComponents = router.currentRoute.value.matched
|
||||
|
||||
expect(matchedComponents[0].components.default.name).to.eql(
|
||||
'AsyncComponentWrapper',
|
||||
expect(matchedComponents[0].components.default.__file).to.contain(
|
||||
'lists.vue',
|
||||
)
|
||||
})
|
||||
|
||||
|
|
@ -67,8 +66,8 @@ describe('routes', () => {
|
|||
|
||||
const matchedComponents = router.currentRoute.value.matched
|
||||
|
||||
expect(matchedComponents[0].components.default.name).to.eql(
|
||||
'AsyncComponentWrapper',
|
||||
expect(matchedComponents[0].components.default.__file).to.contain(
|
||||
'lists_timeline.vue',
|
||||
)
|
||||
})
|
||||
|
||||
|
|
@ -77,8 +76,8 @@ describe('routes', () => {
|
|||
|
||||
const matchedComponents = router.currentRoute.value.matched
|
||||
|
||||
expect(matchedComponents[0].components.default.name).to.eql(
|
||||
'AsyncComponentWrapper',
|
||||
expect(matchedComponents[0].components.default.__file).to.contain(
|
||||
'lists_edit.vue',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
244
test/unit/specs/components/chat_message_list.spec.js
Normal file
244
test/unit/specs/components/chat_message_list.spec.js
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
import { shallowMount } from '@vue/test-utils'
|
||||
|
||||
import ChatMessageList from 'src/components/chat_message_list/chat_message_list.vue'
|
||||
|
||||
describe('ChatMessageList', () => {
|
||||
describe('computed.chatItems', () => {
|
||||
it('Inserts date separators', () => {
|
||||
const component = shallowMount(ChatMessageList, {
|
||||
props: {
|
||||
messages: [
|
||||
{
|
||||
id: '0',
|
||||
account_id: 'Alice',
|
||||
created_at: new Date('2020-06-22T20:00:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
account_id: 'Alice',
|
||||
created_at: new Date('2020-06-22T20:01:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
account_id: 'Alice',
|
||||
created_at: new Date('2020-06-23T20:00:00.000Z'),
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
expect(component.vm.chatItems.map((i) => i.type)).to.eql([
|
||||
'message',
|
||||
'message',
|
||||
'date',
|
||||
'message',
|
||||
])
|
||||
})
|
||||
|
||||
it('Inserts date header if needed', () => {
|
||||
const component = shallowMount(ChatMessageList, {
|
||||
props: {
|
||||
headerDate: true,
|
||||
messages: [
|
||||
{
|
||||
id: '0',
|
||||
account_id: 'Alice',
|
||||
created_at: new Date('2020-06-23T20:00:00.000Z'),
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
expect(component.vm.chatItems.map((i) => i.type)).to.eql([
|
||||
'date',
|
||||
'message',
|
||||
])
|
||||
})
|
||||
|
||||
it('Inserts time separators if messages were sent with considerable delay (5 minutes)', () => {
|
||||
const component = shallowMount(ChatMessageList, {
|
||||
props: {
|
||||
messages: [
|
||||
{
|
||||
id: '0',
|
||||
account_id: 'Alice',
|
||||
created_at: new Date('2020-06-22T20:00:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
account_id: 'Alice',
|
||||
created_at: new Date('2020-06-22T20:06:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
account_id: 'Alice',
|
||||
created_at: new Date('2020-06-23T20:00:00.000Z'),
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
expect(component.vm.chatItems.map((i) => i.type)).to.eql([
|
||||
'message',
|
||||
'date',
|
||||
'message',
|
||||
'date',
|
||||
'message',
|
||||
])
|
||||
expect(component.vm.chatItems.map((i) => i.isTime)).to.eql([
|
||||
undefined,
|
||||
true,
|
||||
undefined,
|
||||
false,
|
||||
undefined,
|
||||
])
|
||||
})
|
||||
|
||||
it('Groups message chains by time and author', () => {
|
||||
const component = shallowMount(ChatMessageList, {
|
||||
props: {
|
||||
messages: [
|
||||
{
|
||||
id: '0',
|
||||
account_id: 'Alice',
|
||||
created_at: new Date('2020-06-22T20:00:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
account_id: 'Alice',
|
||||
created_at: new Date('2020-06-22T20:06:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
account_id: 'Alice',
|
||||
created_at: new Date('2020-06-23T20:00:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
account_id: 'Bob',
|
||||
created_at: new Date('2020-06-23T20:01:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
account_id: 'Bob',
|
||||
created_at: new Date('2020-06-23T20:02:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
account_id: 'Bob',
|
||||
created_at: new Date('2020-06-23T20:03:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
account_id: 'Eve',
|
||||
created_at: new Date('2020-06-23T20:04:00.000Z'),
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
// Type check
|
||||
expect(component.vm.chatItems.map((i) => i.type)).to.eql([
|
||||
'message',
|
||||
'date',
|
||||
'message',
|
||||
'date',
|
||||
'message',
|
||||
'message',
|
||||
'message',
|
||||
'message',
|
||||
'message',
|
||||
])
|
||||
|
||||
// Chain head/Tail checks
|
||||
expect(component.vm.chatItems.map((i) => [i.isHead, i.isTail])).to.eql([
|
||||
[true, true],
|
||||
[undefined, undefined],
|
||||
[true, true],
|
||||
[undefined, undefined],
|
||||
[true, true],
|
||||
[true, false],
|
||||
[false, false],
|
||||
[false, true],
|
||||
[true, true],
|
||||
])
|
||||
|
||||
// Unique ID is randomly generated so we have to compare data against itself
|
||||
// Two messages from Bob next to each other
|
||||
expect(component.vm.chatItems[5].messageChainId).to.eql(
|
||||
component.vm.chatItems[6].messageChainId,
|
||||
)
|
||||
|
||||
// Message from Even right after Bob
|
||||
expect(component.vm.chatItems[7].messageChainId).to.not.eql(
|
||||
component.vm.chatItems[8].messageChainId,
|
||||
)
|
||||
})
|
||||
})
|
||||
describe('methods.getPreviousItem', () => {
|
||||
describe('Finds correct previous meaningful (non-separator) message in the chatlist', () => {
|
||||
let component
|
||||
|
||||
beforeEach(() => {
|
||||
component = shallowMount(ChatMessageList, {
|
||||
props: {
|
||||
messages: [
|
||||
{
|
||||
id: '0',
|
||||
account_id: 'Alice',
|
||||
created_at: new Date('2020-06-22T20:00:00.000Z'),
|
||||
},
|
||||
{
|
||||
// Separator
|
||||
id: '1', // 2
|
||||
account_id: 'Alice',
|
||||
created_at: new Date('2020-06-22T20:06:00.000Z'),
|
||||
},
|
||||
{
|
||||
// Separator
|
||||
id: '2', // 4
|
||||
account_id: 'Alice',
|
||||
created_at: new Date('2020-06-23T20:00:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '3', // 5
|
||||
account_id: 'Bob',
|
||||
created_at: new Date('2020-06-23T20:01:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '4', // 6
|
||||
account_id: 'Bob',
|
||||
created_at: new Date('2020-06-23T20:02:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '5', // 7
|
||||
account_id: 'Bob',
|
||||
created_at: new Date('2020-06-23T20:03:00.000Z'),
|
||||
},
|
||||
{
|
||||
id: '6', // 8
|
||||
account_id: 'Eve',
|
||||
created_at: new Date('2020-06-23T20:04:00.000Z'),
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('Directly next to each other', () => {
|
||||
const correct = component.vm.chatItems[6]
|
||||
expect(component.vm.getPreviousItem(7)).to.eql(correct)
|
||||
})
|
||||
|
||||
it('Across separator', () => {
|
||||
const correct = component.vm.chatItems[2]
|
||||
expect(component.vm.getPreviousItem(4)).to.eql(correct)
|
||||
})
|
||||
|
||||
it('Returns null if no previous item exist', () => {
|
||||
const correct = null
|
||||
expect(component.vm.getPreviousItem(0)).to.eql(correct)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
137
test/unit/specs/components/chat_view.spec.js
Normal file
137
test/unit/specs/components/chat_view.spec.js
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
import { createTestingPinia } from '@pinia/testing'
|
||||
import { shallowMount } from '@vue/test-utils'
|
||||
import { setActivePinia } from 'pinia'
|
||||
|
||||
import ChatView from 'src/components/chat_view/chat_view.vue'
|
||||
|
||||
const message1 = {
|
||||
id: '1',
|
||||
chat_id: 2,
|
||||
idempotency_key: '1',
|
||||
created_at: new Date('2020-06-22T18:45:53.000Z'),
|
||||
}
|
||||
|
||||
const message2 = {
|
||||
id: '2',
|
||||
chat_id: 2,
|
||||
idempotency_key: '2',
|
||||
account_id: '9vmRb29zLQReckr5ay',
|
||||
created_at: new Date('2020-06-22T18:45:56.000Z'),
|
||||
}
|
||||
|
||||
const message3 = {
|
||||
id: '3',
|
||||
chat_id: 2,
|
||||
idempotency_key: '3',
|
||||
account_id: '9vmRb29zLQReckr5ay',
|
||||
created_at: new Date('2020-07-22T18:45:59.000Z'),
|
||||
}
|
||||
|
||||
const global = {
|
||||
mocks: {
|
||||
$store: {
|
||||
state: {
|
||||
api: {},
|
||||
users: {},
|
||||
statuses: {
|
||||
allStatusesObject: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
$route: {
|
||||
params: {
|
||||
recipient_id: 2,
|
||||
},
|
||||
},
|
||||
$router: {
|
||||
push: () => {
|
||||
/* noop */
|
||||
},
|
||||
},
|
||||
},
|
||||
stubs: {
|
||||
FAIcon: true,
|
||||
},
|
||||
}
|
||||
|
||||
describe('ChatView methods', () => {
|
||||
let component
|
||||
beforeEach(() => {
|
||||
setActivePinia(createTestingPinia())
|
||||
component = shallowMount(ChatView, { global, props: { testMode: true } })
|
||||
component.vm.chat = { id: 2 }
|
||||
})
|
||||
|
||||
describe('addMessages', () => {
|
||||
it("Doesn't add duplicates", () => {
|
||||
component.vm.addMessages({ messages: [message1] })
|
||||
component.vm.addMessages({ messages: [message1] })
|
||||
expect(component.vm.messages.length).to.eql(1)
|
||||
|
||||
component.vm.addMessages({ messages: [message2] })
|
||||
expect(component.vm.messages.length).to.eql(2)
|
||||
})
|
||||
|
||||
it('Updates minId and lastMessage and newMessageCount', async () => {
|
||||
component.vm.addMessages({ messages: [message1] })
|
||||
expect(component.vm.maxId).to.eql(message1.id)
|
||||
expect(component.vm.minId).to.eql(message1.id)
|
||||
expect(component.vm.newMessageCount).to.eql(1)
|
||||
|
||||
component.vm.addMessages({ messages: [message2] })
|
||||
expect(component.vm.maxId).to.eql(message2.id)
|
||||
expect(component.vm.minId).to.eql(message1.id)
|
||||
expect(component.vm.newMessageCount).to.eql(2)
|
||||
|
||||
await component.vm.readChat()
|
||||
expect(component.vm.newMessageCount).to.eql(0)
|
||||
expect(component.vm.lastReadMessageId).to.eql(message2.id)
|
||||
|
||||
// Add message with higher id
|
||||
component.vm.addMessages({ messages: [message3] })
|
||||
expect(component.vm.newMessageCount).to.eql(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe('deleteChatMessage', () => {
|
||||
it('Updates minId and lastMessage', () => {
|
||||
component.vm.addMessages({ messages: [message1] })
|
||||
component.vm.addMessages({ messages: [message2] })
|
||||
component.vm.addMessages({ messages: [message3] })
|
||||
|
||||
expect(component.vm.maxId).to.eql(message3.id)
|
||||
expect(component.vm.minId).to.eql(message1.id)
|
||||
|
||||
component.vm.deleteChatMessage({ messageId: message3.id })
|
||||
expect(component.vm.maxId).to.eql(message2.id)
|
||||
expect(component.vm.minId).to.eql(message1.id)
|
||||
|
||||
component.vm.deleteChatMessage({ messageId: message1.id })
|
||||
expect(component.vm.maxId).to.eql(message2.id)
|
||||
expect(component.vm.minId).to.eql(message2.id)
|
||||
})
|
||||
})
|
||||
|
||||
describe('cullOlder', () => {
|
||||
it('keeps 50 newest messages and messagesIndex matches', () => {
|
||||
for (let i = 100; i > 0; i--) {
|
||||
// Use decimal values with toFixed to hack together constant length predictable strings
|
||||
component.vm.addMessages({
|
||||
messages: [
|
||||
{
|
||||
...message1,
|
||||
id: 'a' + (i / 1000).toFixed(3),
|
||||
idempotency_key: i,
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
component.vm.cullOlder()
|
||||
expect(component.vm.messages.length).to.eql(50)
|
||||
expect(component.vm.messages[0].id).to.eql('a0.051')
|
||||
expect(component.vm.minId).to.eql('a0.051')
|
||||
expect(component.vm.messages[49].id).to.eql('a0.100')
|
||||
expect(Object.keys(component.vm.messagesIndex).length).to.eql(50)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
import { createTestingPinia } from '@pinia/testing'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { setActivePinia } from 'pinia'
|
||||
import { vi } from 'vitest'
|
||||
|
||||
import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'
|
||||
import { mountOpts } from '../../../fixtures/setup_test'
|
||||
|
||||
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||
import { useMergedConfigStore } from 'src/stores/merged_config.js'
|
||||
|
||||
const currentUser = {
|
||||
id: 'current-user',
|
||||
|
|
@ -24,15 +24,16 @@ const repliedStatus = {
|
|||
user: repliedUser,
|
||||
}
|
||||
|
||||
const replyMountOpts = () =>
|
||||
const repliedStatus2 = {
|
||||
id: 'status-2',
|
||||
visibility: 'private',
|
||||
summary: 'subject',
|
||||
user: repliedUser,
|
||||
}
|
||||
|
||||
const replyMountOpts = (props) =>
|
||||
mountOpts({
|
||||
props: {
|
||||
replyTo: repliedStatus.id,
|
||||
repliedUser,
|
||||
attentions: [],
|
||||
copyMessageScope: repliedStatus.visibility,
|
||||
disableDraft: true,
|
||||
},
|
||||
props,
|
||||
afterStore(store) {
|
||||
store.state.users.currentUser = currentUser
|
||||
store.state.statuses.allStatusesObject = {
|
||||
|
|
@ -43,19 +44,279 @@ const replyMountOpts = () =>
|
|||
|
||||
describe('PostStatusForm', () => {
|
||||
beforeEach(() => {
|
||||
setActivePinia(createTestingPinia())
|
||||
vi.useFakeTimers()
|
||||
})
|
||||
|
||||
it('initializes a reply form when quoteReply is unset', () => {
|
||||
useInstanceCapabilitiesStore().quotingAvailable = true
|
||||
|
||||
it('Clean empty initial state', () => {
|
||||
const wrapper = mount(PostStatusForm, replyMountOpts())
|
||||
|
||||
expect(wrapper.vm.newStatus.type).to.equal('reply')
|
||||
expect(wrapper.vm.newStatus.quote).to.eql({
|
||||
id: '',
|
||||
url: '',
|
||||
thread: false,
|
||||
})
|
||||
expect(wrapper.vm.statusType).to.equal('new')
|
||||
expect(wrapper.vm.newStatus.spoilerText).to.eql('')
|
||||
expect(wrapper.vm.newStatus.mentions).to.eql('')
|
||||
expect(wrapper.vm.newStatus.status).to.eql('')
|
||||
})
|
||||
|
||||
it('Reset cleans form to pristine state equal to state form was when created', () => {
|
||||
const wrapper = mount(PostStatusForm, replyMountOpts())
|
||||
|
||||
const initial = { ...wrapper.vm.newStatus }
|
||||
wrapper.vm.clearStatus()
|
||||
|
||||
expect(wrapper.vm.newStatus).to.eql(initial)
|
||||
})
|
||||
|
||||
it('Initializes a reply form', () => {
|
||||
const wrapper = mount(
|
||||
PostStatusForm,
|
||||
replyMountOpts({
|
||||
repliedStatus: repliedStatus,
|
||||
}),
|
||||
)
|
||||
|
||||
useInstanceCapabilitiesStore().quotingAvailable = true
|
||||
|
||||
expect(wrapper.vm.statusType).to.equal('reply')
|
||||
expect(wrapper.vm.isReply).to.equal(true)
|
||||
expect(wrapper.vm.refId).to.equal('status-1')
|
||||
expect(wrapper.vm.quotable).to.equal(true)
|
||||
expect(wrapper.vm.inReplyToStatusId).to.equal('status-1')
|
||||
expect(wrapper.vm.newStatus.quote).to.eql(null)
|
||||
expect(wrapper.vm.newStatus.poll).to.eql(null)
|
||||
expect(wrapper.vm.newStatus.spoilerText).to.eql('')
|
||||
expect(wrapper.vm.newStatus.mentions).to.eql('@replied')
|
||||
expect(wrapper.vm.newStatus.status).to.eql('@replied ')
|
||||
expect(wrapper.vm.newStatus.visibility).to.eql('public')
|
||||
})
|
||||
|
||||
it('Copies scope and subject line, disables quoting for locked posts', () => {
|
||||
const wrapper = mount(
|
||||
PostStatusForm,
|
||||
replyMountOpts({
|
||||
repliedStatus: repliedStatus2,
|
||||
}),
|
||||
)
|
||||
|
||||
useInstanceCapabilitiesStore().quotingAvailable = true
|
||||
|
||||
expect(wrapper.vm.statusType).to.equal('reply')
|
||||
expect(wrapper.vm.isReply).to.equal(true)
|
||||
expect(wrapper.vm.quotable).to.equal(false)
|
||||
expect(wrapper.vm.newStatus.quote).to.eql(null)
|
||||
expect(wrapper.vm.newStatus.poll).to.eql(null)
|
||||
expect(wrapper.vm.newStatus.spoilerText).to.eql('re: subject')
|
||||
expect(wrapper.vm.newStatus.mentions).to.eql('@replied')
|
||||
expect(wrapper.vm.newStatus.status).to.eql('@replied ')
|
||||
expect(wrapper.vm.newStatus.visibility).to.eql('private')
|
||||
|
||||
expect(wrapper.vm.postingOptions.status).to.eql('@replied ')
|
||||
expect(wrapper.vm.postingOptions.spoilerText).to.eql('re: subject')
|
||||
expect(wrapper.vm.postingOptions.visibility).to.eql('private')
|
||||
expect(wrapper.vm.postingOptions.sensitive).to.eql(false)
|
||||
expect(wrapper.vm.postingOptions.media).to.eql([])
|
||||
expect(wrapper.vm.postingOptions.inReplyToStatusId).to.eql('status-2')
|
||||
expect(wrapper.vm.postingOptions.quoteId).to.eql(null)
|
||||
expect(wrapper.vm.postingOptions.contentType).to.eql('text/plain')
|
||||
expect(wrapper.vm.postingOptions.poll).to.eql(null)
|
||||
})
|
||||
|
||||
it('Forces direct mode when replying to a DM, mastodon style subject handling', () => {
|
||||
// We need to initialize pinia first which is happening here...
|
||||
const options = replyMountOpts({
|
||||
repliedStatus: { ...repliedStatus2, visibility: 'direct' },
|
||||
})
|
||||
|
||||
// ...set our settings...
|
||||
useMergedConfigStore().mergedConfig = {
|
||||
...useMergedConfigStore().mergedConfig,
|
||||
subjectLineBehavior: 'masto',
|
||||
}
|
||||
|
||||
// ...and only then mount our component
|
||||
const wrapper = mount(PostStatusForm, options)
|
||||
|
||||
// Otherwise we get multiple instances of pinia that don't talk to each other
|
||||
|
||||
expect(wrapper.vm.statusType).to.equal('reply')
|
||||
expect(wrapper.vm.isReply).to.equal(true)
|
||||
expect(wrapper.vm.quotable).to.equal(false)
|
||||
expect(wrapper.vm.newStatus.quote).to.eql(null)
|
||||
expect(wrapper.vm.newStatus.poll).to.eql(null)
|
||||
expect(wrapper.vm.newStatus.spoilerText).to.eql('subject')
|
||||
expect(wrapper.vm.newStatus.mentions).to.eql('@replied')
|
||||
expect(wrapper.vm.newStatus.status).to.eql('@replied ')
|
||||
expect(wrapper.vm.newStatus.visibility).to.eql('direct')
|
||||
})
|
||||
|
||||
it('Sets status to statusText without mentions if mentions line is enabled', () => {
|
||||
const wrapper = mount(
|
||||
PostStatusForm,
|
||||
replyMountOpts({
|
||||
repliedStatus: repliedStatus2,
|
||||
statusText: 'testing',
|
||||
mentionsLine: true,
|
||||
}),
|
||||
)
|
||||
|
||||
expect(wrapper.vm.statusType).to.equal('reply')
|
||||
expect(wrapper.vm.isReply).to.equal(true)
|
||||
expect(wrapper.vm.newStatus.mentions).to.eql('@replied')
|
||||
expect(wrapper.vm.newStatus.status).to.eql('testing')
|
||||
})
|
||||
|
||||
it('Sets mention when asked for it', () => {
|
||||
const wrapper = mount(
|
||||
PostStatusForm,
|
||||
replyMountOpts({
|
||||
profileMention: repliedUser,
|
||||
}),
|
||||
)
|
||||
|
||||
expect(wrapper.vm.statusType).to.equal('mention')
|
||||
expect(wrapper.vm.isReply).to.equal(false)
|
||||
expect(wrapper.vm.newStatus.mentions).to.eql('@replied')
|
||||
expect(wrapper.vm.newStatus.status).to.eql('@replied ')
|
||||
})
|
||||
|
||||
it('Initializes quote when reply/quote toggled to quote', () => {
|
||||
const wrapper = mount(
|
||||
PostStatusForm,
|
||||
replyMountOpts({
|
||||
repliedStatus: repliedStatus2,
|
||||
}),
|
||||
)
|
||||
|
||||
expect(wrapper.vm.statusType).to.equal('reply')
|
||||
expect(wrapper.vm.isReply).to.equal(true)
|
||||
|
||||
wrapper.vm.quoteThreadToggled = true
|
||||
|
||||
expect(wrapper.vm.newStatus.quote).to.eql({ thread: true, id: 'status-2' })
|
||||
})
|
||||
|
||||
it('Resets quote when reply/quote toggled to reply', () => {
|
||||
const wrapper = mount(
|
||||
PostStatusForm,
|
||||
replyMountOpts({
|
||||
repliedStatus: repliedStatus2,
|
||||
}),
|
||||
)
|
||||
|
||||
expect(wrapper.vm.statusType).to.equal('reply')
|
||||
expect(wrapper.vm.isReply).to.equal(true)
|
||||
|
||||
wrapper.vm.quoteThreadToggled = true
|
||||
wrapper.vm.quoteThreadToggled = false
|
||||
|
||||
expect(wrapper.vm.newStatus.quote).to.eql(null)
|
||||
})
|
||||
|
||||
it('Initializes and reset quote when toggling quote attachment', () => {
|
||||
const wrapper = mount(
|
||||
PostStatusForm,
|
||||
replyMountOpts({
|
||||
repliedStatus: repliedStatus2,
|
||||
}),
|
||||
)
|
||||
|
||||
expect(wrapper.vm.statusType).to.equal('reply')
|
||||
expect(wrapper.vm.isReply).to.equal(true)
|
||||
|
||||
wrapper.vm.toggleQuoteForm()
|
||||
expect(wrapper.vm.newStatus.quote).to.eql({
|
||||
thread: false,
|
||||
id: null,
|
||||
url: '',
|
||||
})
|
||||
wrapper.vm.toggleQuoteForm()
|
||||
expect(wrapper.vm.newStatus.quote).to.eql(null)
|
||||
})
|
||||
|
||||
it('Status editing', () => {
|
||||
const wrapper = mount(
|
||||
PostStatusForm,
|
||||
replyMountOpts({
|
||||
statusId: 'edited',
|
||||
statusText: 'text',
|
||||
statusSubject: 'heading',
|
||||
statusIsSensitive: true,
|
||||
statusPoll: {},
|
||||
statusQuote: {},
|
||||
statusFiles: [],
|
||||
statusMediaDescriptions: {},
|
||||
statusVisibility: 'unlisted',
|
||||
statusContentType: 'text/markdown',
|
||||
}),
|
||||
)
|
||||
|
||||
expect(wrapper.vm.statusType).to.equal('edit')
|
||||
expect(wrapper.vm.isReply).to.equal(false) // edits don't support changing reply-to so it's pretty much ignored
|
||||
expect(wrapper.vm.isEdit).to.equal(true)
|
||||
expect(wrapper.vm.newStatus.quote).to.eql({})
|
||||
expect(wrapper.vm.newStatus.poll).to.eql({})
|
||||
expect(wrapper.vm.newStatus.spoilerText).to.eql('heading')
|
||||
expect(wrapper.vm.newStatus.mentions).to.eql('')
|
||||
expect(wrapper.vm.newStatus.status).to.eql('text')
|
||||
expect(wrapper.vm.newStatus.visibility).to.eql('unlisted')
|
||||
expect(wrapper.vm.newStatus.contentType).to.eql('text/markdown')
|
||||
expect(wrapper.vm.newStatus.nsfw).to.equal(true)
|
||||
expect(wrapper.vm.newStatus.files).to.eql([])
|
||||
})
|
||||
|
||||
it('Posting should reset idempotency key', async () => {
|
||||
vi.setSystemTime(new Date(2027, 1, 1, 13))
|
||||
const wrapper = mount(PostStatusForm, replyMountOpts())
|
||||
const oldIdempotency = wrapper.vm.idempotencyKey
|
||||
|
||||
vi.setSystemTime(new Date(2028, 1, 1, 13))
|
||||
|
||||
wrapper.vm.newStatus.status = 'Testing'
|
||||
await wrapper.vm.postStatus()
|
||||
|
||||
expect(wrapper.vm.idempotencyKey).to.not.eql(oldIdempotency)
|
||||
})
|
||||
|
||||
// TODO Probably better to separate attachment upload/manipulation into its own component?
|
||||
// we need to upload-on-submit for compression setting anyway
|
||||
it('Attachments manipulations (moving, adding, removing)', () => {
|
||||
const wrapper = mount(PostStatusForm, replyMountOpts())
|
||||
|
||||
const i1 = { id: '1', url: 'a' }
|
||||
const i2 = { id: '2', url: 'b' }
|
||||
const i3 = { id: '3', url: 'c' }
|
||||
const i4 = { id: '4', url: 'd' }
|
||||
const iX = { id: 'x', url: 'x' }
|
||||
|
||||
wrapper.vm.newStatus.files = [i3, i1, iX, i2]
|
||||
|
||||
wrapper.vm.removeMediaFile(iX)
|
||||
expect(wrapper.vm.newStatus.files).to.eql([i3, i1, i2])
|
||||
|
||||
wrapper.vm.shiftUpMediaFile(i1)
|
||||
expect(wrapper.vm.newStatus.files).to.eql([i1, i3, i2])
|
||||
|
||||
wrapper.vm.shiftUpMediaFile(i1) // should ignore
|
||||
expect(wrapper.vm.newStatus.files).to.eql([i1, i3, i2])
|
||||
|
||||
wrapper.vm.shiftDnMediaFile(i3)
|
||||
expect(wrapper.vm.newStatus.files).to.eql([i1, i2, i3])
|
||||
|
||||
wrapper.vm.shiftDnMediaFile(i3) // should ignore
|
||||
expect(wrapper.vm.newStatus.files).to.eql([i1, i2, i3])
|
||||
|
||||
wrapper.vm.addMediaFile(i4)
|
||||
expect(wrapper.vm.newStatus.files).to.eql([i1, i2, i3, i4])
|
||||
})
|
||||
|
||||
it('Attachment descriptions', () => {
|
||||
const wrapper = mount(PostStatusForm, replyMountOpts())
|
||||
|
||||
const i1 = { id: '1', url: 'a' }
|
||||
|
||||
wrapper.vm.addMediaFile(i1)
|
||||
expect(wrapper.vm.newStatus.files).to.eql([i1])
|
||||
|
||||
wrapper.vm.editAttachment(i1, 'description')
|
||||
expect(wrapper.vm.newStatus.mediaDescriptions['1']).to.eql('description')
|
||||
})
|
||||
// TODO: Drafts (needs vuex to pinia migration)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,122 +0,0 @@
|
|||
import chatService from '../../../../../src/services/chat_service/chat_service.js'
|
||||
|
||||
const message1 = {
|
||||
id: '9wLkdcmQXD21Oy8lEX',
|
||||
idempotency_key: '1',
|
||||
created_at: new Date('2020-06-22T18:45:53.000Z'),
|
||||
}
|
||||
|
||||
const message2 = {
|
||||
id: '9wLkdp6ihaOVdNj8Wu',
|
||||
idempotency_key: '2',
|
||||
account_id: '9vmRb29zLQReckr5ay',
|
||||
created_at: new Date('2020-06-22T18:45:56.000Z'),
|
||||
}
|
||||
|
||||
const message3 = {
|
||||
id: '9wLke9zL4Dy4OZR2RM',
|
||||
idempotency_key: '3',
|
||||
account_id: '9vmRb29zLQReckr5ay',
|
||||
created_at: new Date('2020-07-22T18:45:59.000Z'),
|
||||
}
|
||||
|
||||
describe('chatService', () => {
|
||||
describe('.add', () => {
|
||||
it("Doesn't add duplicates", () => {
|
||||
const chat = chatService.empty()
|
||||
chatService.add(chat, { messages: [message1] })
|
||||
chatService.add(chat, { messages: [message1] })
|
||||
expect(chat.messages.length).to.eql(1)
|
||||
|
||||
chatService.add(chat, { messages: [message2] })
|
||||
expect(chat.messages.length).to.eql(2)
|
||||
})
|
||||
|
||||
it('Updates minId and lastMessage and newMessageCount', () => {
|
||||
const chat = chatService.empty()
|
||||
|
||||
chatService.add(chat, { messages: [message1] })
|
||||
expect(chat.maxId).to.eql(message1.id)
|
||||
expect(chat.minId).to.eql(message1.id)
|
||||
expect(chat.newMessageCount).to.eql(1)
|
||||
|
||||
chatService.add(chat, { messages: [message2] })
|
||||
expect(chat.maxId).to.eql(message2.id)
|
||||
expect(chat.minId).to.eql(message1.id)
|
||||
expect(chat.newMessageCount).to.eql(2)
|
||||
|
||||
chatService.resetNewMessageCount(chat)
|
||||
expect(chat.newMessageCount).to.eql(0)
|
||||
expect(chat.lastSeenMessageId).to.eql(message2.id)
|
||||
|
||||
// Add message with higher id
|
||||
chatService.add(chat, { messages: [message3] })
|
||||
expect(chat.newMessageCount).to.eql(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe('.delete', () => {
|
||||
it('Updates minId and lastMessage', () => {
|
||||
const chat = chatService.empty()
|
||||
|
||||
chatService.add(chat, { messages: [message1] })
|
||||
chatService.add(chat, { messages: [message2] })
|
||||
chatService.add(chat, { messages: [message3] })
|
||||
|
||||
expect(chat.maxId).to.eql(message3.id)
|
||||
expect(chat.minId).to.eql(message1.id)
|
||||
|
||||
chatService.deleteMessage(chat, message3.id)
|
||||
expect(chat.maxId).to.eql(message2.id)
|
||||
expect(chat.minId).to.eql(message1.id)
|
||||
|
||||
chatService.deleteMessage(chat, message1.id)
|
||||
expect(chat.maxId).to.eql(message2.id)
|
||||
expect(chat.minId).to.eql(message2.id)
|
||||
})
|
||||
})
|
||||
|
||||
describe('.getView', () => {
|
||||
it('Inserts date separators', () => {
|
||||
const chat = chatService.empty()
|
||||
|
||||
chatService.add(chat, { messages: [message1] })
|
||||
chatService.add(chat, { messages: [message2] })
|
||||
chatService.add(chat, { messages: [message3] })
|
||||
|
||||
const view = chatService.getView(chat)
|
||||
expect(view.map((i) => i.type)).to.eql([
|
||||
'date',
|
||||
'message',
|
||||
'message',
|
||||
'date',
|
||||
'message',
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe('.cullOlderMessages', () => {
|
||||
it('keeps 50 newest messages and idIndex matches', () => {
|
||||
const chat = chatService.empty()
|
||||
|
||||
for (let i = 100; i > 0; i--) {
|
||||
// Use decimal values with toFixed to hack together constant length predictable strings
|
||||
chatService.add(chat, {
|
||||
messages: [
|
||||
{
|
||||
...message1,
|
||||
id: 'a' + (i / 1000).toFixed(3),
|
||||
idempotency_key: i,
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
chatService.cullOlderMessages(chat)
|
||||
expect(chat.messages.length).to.eql(50)
|
||||
expect(chat.messages[0].id).to.eql('a0.051')
|
||||
expect(chat.minId).to.eql('a0.051')
|
||||
expect(chat.messages[49].id).to.eql('a0.100')
|
||||
expect(Object.keys(chat.idIndex).length).to.eql(50)
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue