diff --git a/src/thread.ts b/src/thread.ts index 2278f43a1..788651357 100644 --- a/src/thread.ts +++ b/src/thread.ts @@ -41,11 +41,13 @@ export class Thread} message reply message to be added. + */ addReply(message: MessageResponse) { - this.latestReplies = addToMessageList(this.latestReplies, formatMessage(message)); + if (message.parent_id !== this.message.id) { + throw new Error('Message does not belong to this thread'); + } + + this.latestReplies = addToMessageList(this.latestReplies, formatMessage(message), true); } updateReply(message: MessageResponse) { @@ -77,6 +88,7 @@ export class Thread { const date = msg.date || new Date().toISOString(); return { id: uuidv4(), - text: 'x', + text: uuidv4(), html: '

x

\n', type: 'regular', user: { id: 'id' }, diff --git a/test/unit/test-utils/generateThread.js b/test/unit/test-utils/generateThread.js new file mode 100644 index 000000000..93d322ec3 --- /dev/null +++ b/test/unit/test-utils/generateThread.js @@ -0,0 +1,21 @@ +import { v4 as uuidv4 } from 'uuid'; +import { generateUser } from './generateUser'; + +export const generateThread = (channel, parent, opts = {}) => { + return { + parent_message_id: parent.id, + parent_message: parent, + channel, + title: 'title', + created_at: new Date().toISOString(), + updated_at: new Date().toISOString(), + channel_cid: channel.cid, + last_message_at: new Date().toISOString(), + deleted_at: '', + read: [], + reply_count: 0, + latest_replies: [], + thread_participants: [], + ...opts, + }; +}; diff --git a/test/unit/thread.js b/test/unit/thread.js new file mode 100644 index 000000000..d0501c421 --- /dev/null +++ b/test/unit/thread.js @@ -0,0 +1,70 @@ +import chai from 'chai'; +import { v4 as uuidv4 } from 'uuid'; + +import { generateChannel } from './test-utils/generateChannel'; +import { generateMember } from './test-utils/generateMember'; +import { generateMsg } from './test-utils/generateMessage'; +import { generateUser } from './test-utils/generateUser'; +import { getClientWithUser } from './test-utils/getClient'; +import { getOrCreateChannelApi } from './test-utils/getOrCreateChannelApi'; +import sinon from 'sinon'; +import { mockChannelQueryResponse } from './test-utils/mockChannelQueryResponse'; + +import { ChannelState, StreamChat, Thread } from '../../src'; +import { generateThread } from './test-utils/generateThread'; + +const expect = chai.expect; + +describe.only('Thread', () => { + describe('addReply', async () => { + let client; + let channel; + let parent; + let thread; + + beforeEach(() => { + client = new StreamChat('apiKey'); + client.userID = 'observer'; + channel = generateChannel().channel; + parent = generateMsg(); + thread = new Thread(client, generateThread(channel, parent)); + }); + it('should throw error if the message is not a reply to the parent', async () => { + const reply = generateMsg({ + status: 'pending', + parent_id: 'some_other_id', + }); + expect(() => thread.addReply(reply)).to.throw('Message does not belong to this thread'); + }); + + it('should add reply to the thread', async () => { + const reply1 = generateMsg({ + status: 'pending', + parent_id: parent.id, + }); + + thread.addReply(reply1); + expect(thread.latestReplies).to.have.length(1); + expect(thread.latestReplies[0].status).to.equal('pending'); + + reply1.status = 'received'; + thread.addReply(reply1); + expect(thread.latestReplies).to.have.length(1); + expect(thread.latestReplies[0].status).to.equal('received'); + + const reply2 = generateMsg({ + status: 'pending', + parent_id: parent.id, + }); + + thread.addReply(reply2); + expect(thread.latestReplies).to.have.length(2); + expect(thread.latestReplies[1].status).to.equal('pending'); + + reply2.status = 'received'; + thread.addReply(reply2); + expect(thread.latestReplies).to.have.length(2); + expect(thread.latestReplies[1].status).to.equal('received'); + }); + }); +});