Refactor group story reply receipt logic

This commit is contained in:
trevor-signal 2023-05-31 16:07:43 -04:00 committed by GitHub
parent cfabf8f533
commit 4fa9ce5096
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 89 additions and 2 deletions

View file

@ -2482,12 +2482,18 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
if (!storyQuoteIsFromSelf) {
return true;
}
// The sender is not a recipient for this story
if (sendState === undefined) {
return false;
}
// Group replies are always allowed
if (!isDirectConversation(conversation.attributes)) {
return false;
return true;
}
// For 1:1 stories, we need to check if they can be replied to
return sendState.isAllowedToReplyToStory !== false;
});

View file

@ -4,6 +4,7 @@
import createDebug from 'debug';
import Long from 'long';
import { Proto, StorageState } from '@signalapp/mock-server';
import type { Group } from '@signalapp/mock-server';
import * as durations from '../../util/durations';
import { uuidToBytes } from '../../util/uuidToBytes';
@ -24,6 +25,7 @@ describe('story/messaging', function unknownContacts() {
let bootstrap: Bootstrap;
let app: App;
let group: Group;
beforeEach(async () => {
bootstrap = new Bootstrap();
@ -81,6 +83,20 @@ describe('story/messaging', function unknownContacts() {
},
});
// Add a group for story send
const members = [...contacts].slice(0, 10);
group = await phone.createGroup({
title: 'Mock Group',
members: [phone, ...members],
});
state = state
.addGroup(group, {
whitelisted: true,
storySendMode: Proto.GroupV2Record.StorySendMode.ENABLED,
})
.pinGroup(group);
// Finally whitelist and pin contacts
for (const contact of [first, second]) {
state = state.addContact(contact, {
@ -192,4 +208,69 @@ describe('story/messaging', function unknownContacts() {
.locator(`[data-testid="${second.device.uuid}"] >> "second reply"`)
.waitFor();
});
it('allows replies to groups', async () => {
const { desktop, contacts } = bootstrap;
const window = await app.getWindow();
debug('waiting for storage service sync to complete');
await app.waitForStorageService();
const leftPane = window.locator('.left-pane-wrapper');
debug('Create and send a story to the group');
await leftPane.getByRole('button', { name: 'Stories' }).click();
await window.getByRole('button', { name: 'Add a story' }).first().click();
await window.getByRole('button', { name: 'Text story' }).click();
await window.locator('.TextAttachment').click();
await window.getByRole('textbox', { name: 'Add text' }).type('hello');
await window.getByRole('button', { name: 'Next' }).click();
await window
.locator('.Checkbox__container')
.getByText('Mock Group')
.click();
await window.getByRole('button', { name: 'Send story' }).click();
// Grab the time the story was sent at
const time = await window.locator('time').nth(1).getAttribute('datetime');
if (!time) {
throw new Error('Cannot locate story time');
}
const sentAt = new Date(time).valueOf();
debug('Contact sends reply to group story');
await contacts[0].sendRaw(
desktop,
{
dataMessage: {
body: 'first reply',
storyContext: {
authorUuid: desktop.uuid,
sentTimestamp: Long.fromNumber(sentAt),
},
groupV2: {
masterKey: group.masterKey,
},
timestamp: Long.fromNumber(sentAt + 1),
},
},
{ timestamp: sentAt + 1 }
);
debug('Ensure sender sees the reply');
await window
.locator('.StoryListItem__button')
.getByText('Mock Group')
.click();
// For some reason we need to click the story & exit before the reply shows up
await window.getByRole('button', { name: 'Close' }).click();
await window
.locator('.StoryListItem__button')
.getByText('Mock Group')
.click();
await window.getByText('1 reply').click();
await window.getByText('first reply').waitFor();
});
});

View file

@ -50,7 +50,7 @@ export async function findStoryMessages(
isStoryAMatch(item, conversationId, ourConversationId, authorUuid, sentAt)
);
if (found.length !== 0) {
if (found.length === 0) {
log.info('findStoryMessages: message not found', sentAt);
return [];
}