Refactor outbound delivery state
This commit is contained in:
parent
831ec98418
commit
9c48a95eb5
29 changed files with 3200 additions and 697 deletions
|
@ -3,10 +3,16 @@
|
|||
|
||||
import { assert } from 'chai';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { SendStatus } from '../../../messages/MessageSendState';
|
||||
import {
|
||||
MessageAttributesType,
|
||||
ShallowChallengeError,
|
||||
} from '../../../model-types.d';
|
||||
import { ConversationType } from '../../../state/ducks/conversations';
|
||||
|
||||
import {
|
||||
canReply,
|
||||
getMessagePropStatus,
|
||||
isEndSession,
|
||||
isGroupUpdate,
|
||||
isIncoming,
|
||||
|
@ -14,6 +20,12 @@ import {
|
|||
} from '../../../state/selectors/message';
|
||||
|
||||
describe('state/selectors/messages', () => {
|
||||
let ourConversationId: string;
|
||||
|
||||
beforeEach(() => {
|
||||
ourConversationId = uuid();
|
||||
});
|
||||
|
||||
describe('canReply', () => {
|
||||
const defaultConversation: ConversationType = {
|
||||
id: uuid(),
|
||||
|
@ -35,7 +47,7 @@ describe('state/selectors/messages', () => {
|
|||
isGroupV1AndDisabled: true,
|
||||
});
|
||||
|
||||
assert.isFalse(canReply(message, getConversationById));
|
||||
assert.isFalse(canReply(message, ourConversationId, getConversationById));
|
||||
});
|
||||
|
||||
// NOTE: This is missing a test for mandatory profile sharing.
|
||||
|
@ -48,33 +60,70 @@ describe('state/selectors/messages', () => {
|
|||
};
|
||||
const getConversationById = () => defaultConversation;
|
||||
|
||||
assert.isFalse(canReply(message, getConversationById));
|
||||
assert.isFalse(canReply(message, ourConversationId, getConversationById));
|
||||
});
|
||||
|
||||
it('returns false for outgoing messages that have not been sent', () => {
|
||||
const message = {
|
||||
conversationId: 'fake-conversation-id',
|
||||
type: 'outgoing' as const,
|
||||
sent_to: [],
|
||||
sendStateByConversationId: {
|
||||
[ourConversationId]: {
|
||||
status: SendStatus.Sent,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Pending,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
},
|
||||
};
|
||||
const getConversationById = () => defaultConversation;
|
||||
|
||||
assert.isFalse(canReply(message, getConversationById));
|
||||
assert.isFalse(canReply(message, ourConversationId, getConversationById));
|
||||
});
|
||||
|
||||
it('returns true for outgoing messages that have been delivered to at least one person', () => {
|
||||
it('returns true for outgoing messages that are only sent to yourself', () => {
|
||||
const message = {
|
||||
conversationId: 'fake-conversation-id',
|
||||
type: 'outgoing' as const,
|
||||
receipients: [uuid(), uuid()],
|
||||
sent_to: [uuid()],
|
||||
sendStateByConversationId: {
|
||||
[ourConversationId]: {
|
||||
status: SendStatus.Pending,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
},
|
||||
};
|
||||
const getConversationById = () => defaultConversation;
|
||||
|
||||
assert.isTrue(canReply(message, ourConversationId, getConversationById));
|
||||
});
|
||||
|
||||
it('returns true for outgoing messages that have been sent to at least one person', () => {
|
||||
const message = {
|
||||
conversationId: 'fake-conversation-id',
|
||||
type: 'outgoing' as const,
|
||||
sendStateByConversationId: {
|
||||
[ourConversationId]: {
|
||||
status: SendStatus.Sent,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Pending,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Sent,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
},
|
||||
};
|
||||
const getConversationById = () => ({
|
||||
...defaultConversation,
|
||||
type: 'group' as const,
|
||||
});
|
||||
|
||||
assert.isTrue(canReply(message, getConversationById));
|
||||
assert.isTrue(canReply(message, ourConversationId, getConversationById));
|
||||
});
|
||||
|
||||
it('returns true for incoming messages', () => {
|
||||
|
@ -84,7 +133,247 @@ describe('state/selectors/messages', () => {
|
|||
};
|
||||
const getConversationById = () => defaultConversation;
|
||||
|
||||
assert.isTrue(canReply(message, getConversationById));
|
||||
assert.isTrue(canReply(message, ourConversationId, getConversationById));
|
||||
});
|
||||
});
|
||||
|
||||
describe('getMessagePropStatus', () => {
|
||||
const createMessage = (overrides: Partial<MessageAttributesType>) => ({
|
||||
type: 'outgoing' as const,
|
||||
...overrides,
|
||||
});
|
||||
|
||||
it('returns undefined for incoming messages', () => {
|
||||
const message = createMessage({ type: 'incoming' });
|
||||
|
||||
assert.isUndefined(
|
||||
getMessagePropStatus(message, ourConversationId, true)
|
||||
);
|
||||
});
|
||||
|
||||
it('returns "paused" for messages with challenges', () => {
|
||||
const challengeError: ShallowChallengeError = Object.assign(
|
||||
new Error('a challenge'),
|
||||
{
|
||||
name: 'SendMessageChallengeError',
|
||||
retryAfter: 123,
|
||||
data: {},
|
||||
}
|
||||
);
|
||||
const message = createMessage({ errors: [challengeError] });
|
||||
|
||||
assert.strictEqual(
|
||||
getMessagePropStatus(message, ourConversationId, true),
|
||||
'paused'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns "partial-sent" if the message has errors but was sent to at least one person', () => {
|
||||
const message = createMessage({
|
||||
errors: [new Error('whoopsie')],
|
||||
sendStateByConversationId: {
|
||||
[ourConversationId]: {
|
||||
status: SendStatus.Sent,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Pending,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Delivered,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
getMessagePropStatus(message, ourConversationId, true),
|
||||
'partial-sent'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns "error" if the message has errors and has not been sent', () => {
|
||||
const message = createMessage({
|
||||
errors: [new Error('whoopsie')],
|
||||
sendStateByConversationId: {
|
||||
[ourConversationId]: {
|
||||
status: SendStatus.Pending,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Pending,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Pending,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
getMessagePropStatus(message, ourConversationId, true),
|
||||
'error'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns "read" if the message is just for you and has been sent', () => {
|
||||
const message = createMessage({
|
||||
sendStateByConversationId: {
|
||||
[ourConversationId]: {
|
||||
status: SendStatus.Sent,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
[true, false].forEach(readReceiptSetting => {
|
||||
assert.strictEqual(
|
||||
getMessagePropStatus(message, ourConversationId, readReceiptSetting),
|
||||
'read'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('returns "read" if the message was read by at least one person and you have read receipts enabled', () => {
|
||||
const readMessage = createMessage({
|
||||
sendStateByConversationId: {
|
||||
[ourConversationId]: {
|
||||
status: SendStatus.Sent,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Pending,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Delivered,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Read,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
},
|
||||
});
|
||||
assert.strictEqual(
|
||||
getMessagePropStatus(readMessage, ourConversationId, true),
|
||||
'read'
|
||||
);
|
||||
|
||||
const viewedMessage = createMessage({
|
||||
sendStateByConversationId: {
|
||||
[uuid()]: {
|
||||
status: SendStatus.Viewed,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
},
|
||||
});
|
||||
assert.strictEqual(
|
||||
getMessagePropStatus(viewedMessage, ourConversationId, true),
|
||||
'read'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns "delivered" if the message was read by at least one person and you have read receipts disabled', () => {
|
||||
const message = createMessage({
|
||||
sendStateByConversationId: {
|
||||
[ourConversationId]: {
|
||||
status: SendStatus.Sent,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Pending,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Read,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
getMessagePropStatus(message, ourConversationId, false),
|
||||
'delivered'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns "delivered" if the message was delivered to at least one person, but no "higher"', () => {
|
||||
const message = createMessage({
|
||||
sendStateByConversationId: {
|
||||
[ourConversationId]: {
|
||||
status: SendStatus.Sent,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Pending,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Sent,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Delivered,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
getMessagePropStatus(message, ourConversationId, true),
|
||||
'delivered'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns "sent" if the message was sent to at least one person, but no "higher"', () => {
|
||||
const message = createMessage({
|
||||
sendStateByConversationId: {
|
||||
[ourConversationId]: {
|
||||
status: SendStatus.Sent,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Pending,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Sent,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
getMessagePropStatus(message, ourConversationId, true),
|
||||
'sent'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns "sending" if the message has not been sent yet, even if it has been synced to yourself', () => {
|
||||
const message = createMessage({
|
||||
sendStateByConversationId: {
|
||||
[ourConversationId]: {
|
||||
status: SendStatus.Sent,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Pending,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
[uuid()]: {
|
||||
status: SendStatus.Pending,
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
getMessagePropStatus(message, ourConversationId, true),
|
||||
'sending'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue