Update unread count when creating important local notifications
This commit is contained in:
parent
ddde85cdd8
commit
105508c50f
5 changed files with 521 additions and 6 deletions
51
ts/groups.ts
51
ts/groups.ts
|
@ -83,6 +83,8 @@ import {
|
||||||
conversationJobQueue,
|
conversationJobQueue,
|
||||||
conversationQueueJobEnum,
|
conversationQueueJobEnum,
|
||||||
} from './jobs/conversationJobQueue';
|
} from './jobs/conversationJobQueue';
|
||||||
|
import { ReadStatus } from './messages/MessageReadStatus';
|
||||||
|
import { SeenStatus } from './MessageSeenStatus';
|
||||||
|
|
||||||
type AccessRequiredEnum = Proto.AccessControl.AccessRequired;
|
type AccessRequiredEnum = Proto.AccessControl.AccessRequired;
|
||||||
|
|
||||||
|
@ -272,7 +274,10 @@ type UploadedAvatarType = {
|
||||||
key: string;
|
key: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type BasicMessageType = Pick<MessageAttributesType, 'id' | 'schemaVersion'>;
|
type BasicMessageType = Pick<
|
||||||
|
MessageAttributesType,
|
||||||
|
'id' | 'schemaVersion' | 'readStatus' | 'seenStatus'
|
||||||
|
>;
|
||||||
|
|
||||||
type GroupV2ChangeMessageType = {
|
type GroupV2ChangeMessageType = {
|
||||||
type: 'group-v2-change';
|
type: 'group-v2-change';
|
||||||
|
@ -1845,9 +1850,11 @@ export async function createGroupV2({
|
||||||
type: 'group-v2-change',
|
type: 'group-v2-change',
|
||||||
sourceUuid: ourUuid,
|
sourceUuid: ourUuid,
|
||||||
conversationId: conversation.id,
|
conversationId: conversation.id,
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
received_at: window.Signal.Util.incrementMessageCounter(),
|
received_at: window.Signal.Util.incrementMessageCounter(),
|
||||||
received_at_ms: timestamp,
|
received_at_ms: timestamp,
|
||||||
timestamp,
|
timestamp,
|
||||||
|
seenStatus: SeenStatus.Seen,
|
||||||
sent_at: timestamp,
|
sent_at: timestamp,
|
||||||
groupV2Change: {
|
groupV2Change: {
|
||||||
from: ourUuid,
|
from: ourUuid,
|
||||||
|
@ -2289,6 +2296,8 @@ export async function initiateMigrationToGroupV2(
|
||||||
type: 'group-v1-migration',
|
type: 'group-v1-migration',
|
||||||
invitedGV2Members: pendingMembersV2,
|
invitedGV2Members: pendingMembersV2,
|
||||||
droppedGV2MemberIds,
|
droppedGV2MemberIds,
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: SeenStatus.Seen,
|
||||||
});
|
});
|
||||||
|
|
||||||
await updateGroup({
|
await updateGroup({
|
||||||
|
@ -2634,7 +2643,11 @@ export async function respondToGroupV2Migration({
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
groupChangeMessages: [
|
groupChangeMessages: [
|
||||||
getBasicMigrationBubble(),
|
{
|
||||||
|
...getBasicMigrationBubble(),
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: SeenStatus.Seen,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
...generateBasicMessage(),
|
...generateBasicMessage(),
|
||||||
type: 'group-v2-change',
|
type: 'group-v2-change',
|
||||||
|
@ -2646,6 +2659,8 @@ export async function respondToGroupV2Migration({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: SeenStatus.Unseen,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
members: [],
|
members: [],
|
||||||
|
@ -2663,7 +2678,13 @@ export async function respondToGroupV2Migration({
|
||||||
sentAt,
|
sentAt,
|
||||||
updates: {
|
updates: {
|
||||||
newAttributes: attributes,
|
newAttributes: attributes,
|
||||||
groupChangeMessages: [getBasicMigrationBubble()],
|
groupChangeMessages: [
|
||||||
|
{
|
||||||
|
...getBasicMigrationBubble(),
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: SeenStatus.Seen,
|
||||||
|
},
|
||||||
|
],
|
||||||
members: [],
|
members: [],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -2694,9 +2715,11 @@ export async function respondToGroupV2Migration({
|
||||||
// Generate notifications into the timeline
|
// Generate notifications into the timeline
|
||||||
const groupChangeMessages: Array<GroupChangeMessageType> = [];
|
const groupChangeMessages: Array<GroupChangeMessageType> = [];
|
||||||
|
|
||||||
groupChangeMessages.push(
|
groupChangeMessages.push({
|
||||||
buildMigrationBubble(previousGroupV1MembersIds, newAttributes)
|
...buildMigrationBubble(previousGroupV1MembersIds, newAttributes),
|
||||||
);
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: SeenStatus.Seen,
|
||||||
|
});
|
||||||
|
|
||||||
const areWeInvited = (newAttributes.pendingMembersV2 || []).some(
|
const areWeInvited = (newAttributes.pendingMembersV2 || []).some(
|
||||||
item => item.uuid === ourUuid
|
item => item.uuid === ourUuid
|
||||||
|
@ -2717,6 +2740,8 @@ export async function respondToGroupV2Migration({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: SeenStatus.Unseen,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3190,6 +3215,7 @@ async function appendChangeMessages(
|
||||||
// We updated the message, but didn't add new ones - refresh left pane
|
// We updated the message, but didn't add new ones - refresh left pane
|
||||||
if (!newMessages && mergedMessages.length > 0) {
|
if (!newMessages && mergedMessages.length > 0) {
|
||||||
await conversation.updateLastMessage();
|
await conversation.updateLastMessage();
|
||||||
|
conversation.updateUnread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3519,6 +3545,8 @@ async function generateLeftGroupChanges(
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: SeenStatus.Unseen,
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -4299,6 +4327,7 @@ function extractDiffs({
|
||||||
let timerNotification: GroupChangeMessageType | undefined;
|
let timerNotification: GroupChangeMessageType | undefined;
|
||||||
|
|
||||||
const firstUpdate = !isNumber(old.revision);
|
const firstUpdate = !isNumber(old.revision);
|
||||||
|
const isFromUs = ourUuid === sourceUuid;
|
||||||
|
|
||||||
// Here we hardcode initial messages if this is our first time processing data this
|
// Here we hardcode initial messages if this is our first time processing data this
|
||||||
// group. Ideally we can collapse it down to just one of: 'you were added',
|
// group. Ideally we can collapse it down to just one of: 'you were added',
|
||||||
|
@ -4317,6 +4346,8 @@ function extractDiffs({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: isFromUs ? SeenStatus.Seen : SeenStatus.Unseen,
|
||||||
};
|
};
|
||||||
} else if (firstUpdate && dropInitialJoinMessage) {
|
} else if (firstUpdate && dropInitialJoinMessage) {
|
||||||
// None of the rest of the messages should be added if dropInitialJoinMessage = true
|
// None of the rest of the messages should be added if dropInitialJoinMessage = true
|
||||||
|
@ -4333,6 +4364,8 @@ function extractDiffs({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: isFromUs ? SeenStatus.Seen : SeenStatus.Unseen,
|
||||||
};
|
};
|
||||||
} else if (firstUpdate && areWeInGroup) {
|
} else if (firstUpdate && areWeInGroup) {
|
||||||
message = {
|
message = {
|
||||||
|
@ -4347,6 +4380,8 @@ function extractDiffs({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: isFromUs ? SeenStatus.Seen : SeenStatus.Unseen,
|
||||||
};
|
};
|
||||||
} else if (firstUpdate) {
|
} else if (firstUpdate) {
|
||||||
message = {
|
message = {
|
||||||
|
@ -4360,6 +4395,8 @@ function extractDiffs({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: isFromUs ? SeenStatus.Seen : SeenStatus.Unseen,
|
||||||
};
|
};
|
||||||
} else if (details.length > 0) {
|
} else if (details.length > 0) {
|
||||||
message = {
|
message = {
|
||||||
|
@ -4370,6 +4407,8 @@ function extractDiffs({
|
||||||
from: sourceUuid,
|
from: sourceUuid,
|
||||||
details,
|
details,
|
||||||
},
|
},
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: isFromUs ? SeenStatus.Seen : SeenStatus.Unseen,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2909,6 +2909,7 @@ export class ConversationModel extends window.Backbone
|
||||||
);
|
);
|
||||||
|
|
||||||
this.trigger('newmessage', model);
|
this.trigger('newmessage', model);
|
||||||
|
this.updateUnread();
|
||||||
}
|
}
|
||||||
|
|
||||||
async addDeliveryIssue({
|
async addDeliveryIssue({
|
||||||
|
@ -2954,6 +2955,7 @@ export class ConversationModel extends window.Backbone
|
||||||
this.trigger('newmessage', model);
|
this.trigger('newmessage', model);
|
||||||
|
|
||||||
await this.notify(model);
|
await this.notify(model);
|
||||||
|
this.updateUnread();
|
||||||
}
|
}
|
||||||
|
|
||||||
async addKeyChange(keyChangedId: UUID): Promise<void> {
|
async addKeyChange(keyChangedId: UUID): Promise<void> {
|
||||||
|
@ -3050,6 +3052,7 @@ export class ConversationModel extends window.Backbone
|
||||||
);
|
);
|
||||||
|
|
||||||
this.trigger('newmessage', model);
|
this.trigger('newmessage', model);
|
||||||
|
this.updateUnread();
|
||||||
|
|
||||||
const uuid = this.getUuid();
|
const uuid = this.getUuid();
|
||||||
if (isDirectConversation(this.attributes) && uuid) {
|
if (isDirectConversation(this.attributes) && uuid) {
|
||||||
|
@ -3115,6 +3118,7 @@ export class ConversationModel extends window.Backbone
|
||||||
);
|
);
|
||||||
|
|
||||||
this.trigger('newmessage', model);
|
this.trigger('newmessage', model);
|
||||||
|
this.updateUnread();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4546,7 +4550,9 @@ export class ConversationModel extends window.Backbone
|
||||||
model.set({ id });
|
model.set({ id });
|
||||||
|
|
||||||
const message = window.MessageController.register(id, model);
|
const message = window.MessageController.register(id, model);
|
||||||
|
|
||||||
this.addSingleMessage(message);
|
this.addSingleMessage(message);
|
||||||
|
this.updateUnread();
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
132
ts/sql/migrations/58-update-unread.ts
Normal file
132
ts/sql/migrations/58-update-unread.ts
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import type { Database } from 'better-sqlite3';
|
||||||
|
import { ReadStatus } from '../../messages/MessageReadStatus';
|
||||||
|
import { SeenStatus } from '../../MessageSeenStatus';
|
||||||
|
|
||||||
|
import type { LoggerType } from '../../types/Logging';
|
||||||
|
|
||||||
|
export default function updateToSchemaVersion58(
|
||||||
|
currentVersion: number,
|
||||||
|
db: Database,
|
||||||
|
logger: LoggerType
|
||||||
|
): void {
|
||||||
|
if (currentVersion >= 58) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.transaction(() => {
|
||||||
|
db.exec(
|
||||||
|
`
|
||||||
|
--- Promote unread status in JSON to SQL column
|
||||||
|
|
||||||
|
UPDATE messages
|
||||||
|
SET
|
||||||
|
readStatus = ${ReadStatus.Unread},
|
||||||
|
seenStatus = ${SeenStatus.Unseen}
|
||||||
|
WHERE
|
||||||
|
json_extract(json, '$.unread') IS true OR
|
||||||
|
json_extract(json, '$.unread') IS 1;
|
||||||
|
|
||||||
|
--- Clean up all old messages that still have a null read status
|
||||||
|
--- Note: we don't need to update seenStatus, because that was defaulted to zero
|
||||||
|
|
||||||
|
UPDATE messages
|
||||||
|
SET
|
||||||
|
readStatus = ${ReadStatus.Read}
|
||||||
|
WHERE
|
||||||
|
readStatus IS NULL;
|
||||||
|
|
||||||
|
--- Re-run unseen/unread queries from migration 56
|
||||||
|
|
||||||
|
UPDATE messages
|
||||||
|
SET
|
||||||
|
seenStatus = ${SeenStatus.Unseen}
|
||||||
|
WHERE
|
||||||
|
readStatus = ${ReadStatus.Unread} AND
|
||||||
|
(
|
||||||
|
type IS NULL
|
||||||
|
OR
|
||||||
|
type IN (
|
||||||
|
'call-history',
|
||||||
|
'change-number-notification',
|
||||||
|
'chat-session-refreshed',
|
||||||
|
'delivery-issue',
|
||||||
|
'group',
|
||||||
|
'incoming',
|
||||||
|
'keychange',
|
||||||
|
'timer-notification',
|
||||||
|
'verified-change'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
UPDATE messages
|
||||||
|
SET
|
||||||
|
readStatus = ${ReadStatus.Read}
|
||||||
|
WHERE
|
||||||
|
readStatus = ${ReadStatus.Unread} AND
|
||||||
|
type IS NOT NULL AND
|
||||||
|
type NOT IN (
|
||||||
|
'call-history',
|
||||||
|
'change-number-notification',
|
||||||
|
'chat-session-refreshed',
|
||||||
|
'delivery-issue',
|
||||||
|
'group',
|
||||||
|
'incoming',
|
||||||
|
'keychange',
|
||||||
|
'timer-notification',
|
||||||
|
'verified-change'
|
||||||
|
);
|
||||||
|
|
||||||
|
--- (new) Ensure these message types are not unread, just unseen
|
||||||
|
|
||||||
|
UPDATE messages
|
||||||
|
SET
|
||||||
|
readStatus = ${ReadStatus.Read}
|
||||||
|
WHERE
|
||||||
|
readStatus = ${ReadStatus.Unread} AND
|
||||||
|
(
|
||||||
|
type IN (
|
||||||
|
'change-number-notification',
|
||||||
|
'keychange'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
--- (new) Ensure that these message types are neither unseen nor unread
|
||||||
|
|
||||||
|
UPDATE messages
|
||||||
|
SET
|
||||||
|
readStatus = ${ReadStatus.Read},
|
||||||
|
seenStatus = ${SeenStatus.Seen}
|
||||||
|
WHERE
|
||||||
|
type IN (
|
||||||
|
'group-v1-migration',
|
||||||
|
'message-history-unsynced',
|
||||||
|
'outgoing',
|
||||||
|
'profile-change',
|
||||||
|
'universal-timer-notification'
|
||||||
|
);
|
||||||
|
|
||||||
|
--- Make sure JSON reflects SQL columns
|
||||||
|
|
||||||
|
UPDATE messages
|
||||||
|
SET
|
||||||
|
json = json_patch(
|
||||||
|
json,
|
||||||
|
json_object(
|
||||||
|
'readStatus', readStatus,
|
||||||
|
'seenStatus', seenStatus
|
||||||
|
)
|
||||||
|
)
|
||||||
|
WHERE
|
||||||
|
readStatus IS NOT NULL OR
|
||||||
|
seenStatus IS NOT 0;
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
db.pragma('user_version = 58');
|
||||||
|
})();
|
||||||
|
|
||||||
|
logger.info('updateToSchemaVersion58: success!');
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ import updateToSchemaVersion54 from './54-unprocessed-received-at-counter';
|
||||||
import updateToSchemaVersion55 from './55-report-message-aci';
|
import updateToSchemaVersion55 from './55-report-message-aci';
|
||||||
import updateToSchemaVersion56 from './56-add-unseen-to-message';
|
import updateToSchemaVersion56 from './56-add-unseen-to-message';
|
||||||
import updateToSchemaVersion57 from './57-rm-message-history-unsynced';
|
import updateToSchemaVersion57 from './57-rm-message-history-unsynced';
|
||||||
|
import updateToSchemaVersion58 from './58-update-unread';
|
||||||
|
|
||||||
function updateToSchemaVersion1(
|
function updateToSchemaVersion1(
|
||||||
currentVersion: number,
|
currentVersion: number,
|
||||||
|
@ -1929,6 +1930,7 @@ export const SCHEMA_VERSIONS = [
|
||||||
updateToSchemaVersion55,
|
updateToSchemaVersion55,
|
||||||
updateToSchemaVersion56,
|
updateToSchemaVersion56,
|
||||||
updateToSchemaVersion57,
|
updateToSchemaVersion57,
|
||||||
|
updateToSchemaVersion58,
|
||||||
];
|
];
|
||||||
|
|
||||||
export function updateSchema(db: Database, logger: LoggerType): void {
|
export function updateSchema(db: Database, logger: LoggerType): void {
|
||||||
|
|
|
@ -2026,4 +2026,340 @@ describe('SQL migrations test', () => {
|
||||||
assert.notInclude(second, 'SCAN', 'second');
|
assert.notInclude(second, 'SCAN', 'second');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('updateToSchemaVersion58', () => {
|
||||||
|
it('updates readStatus/seenStatus for messages with unread: true/1 in JSON', () => {
|
||||||
|
const MESSAGE_ID_1 = generateGuid();
|
||||||
|
const MESSAGE_ID_2 = generateGuid();
|
||||||
|
const MESSAGE_ID_3 = generateGuid();
|
||||||
|
const MESSAGE_ID_4 = generateGuid();
|
||||||
|
const CONVERSATION_ID = generateGuid();
|
||||||
|
|
||||||
|
updateToVersion(57);
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
db.exec(
|
||||||
|
`
|
||||||
|
INSERT INTO messages
|
||||||
|
(id, conversationId, type, json)
|
||||||
|
VALUES
|
||||||
|
('${MESSAGE_ID_1}', '${CONVERSATION_ID}', 'incoming', '${JSON.stringify(
|
||||||
|
{ unread: true }
|
||||||
|
)}'),
|
||||||
|
('${MESSAGE_ID_2}', '${CONVERSATION_ID}', 'incoming', '${JSON.stringify(
|
||||||
|
{ unread: 1 }
|
||||||
|
)}'),
|
||||||
|
('${MESSAGE_ID_3}', '${CONVERSATION_ID}', 'incoming', '${JSON.stringify(
|
||||||
|
{ unread: undefined }
|
||||||
|
)}'),
|
||||||
|
('${MESSAGE_ID_4}', '${CONVERSATION_ID}', 'incoming', '${JSON.stringify(
|
||||||
|
{ unread: 0 }
|
||||||
|
)}');
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
db.prepare('SELECT COUNT(*) FROM messages;').pluck().get(),
|
||||||
|
4,
|
||||||
|
'starting total'
|
||||||
|
);
|
||||||
|
|
||||||
|
updateToVersion(58);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
db.prepare('SELECT COUNT(*) FROM messages;').pluck().get(),
|
||||||
|
4,
|
||||||
|
'ending total'
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
`SELECT COUNT(*) FROM messages WHERE readStatus = ${ReadStatus.Unread};`
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
2,
|
||||||
|
'ending unread count'
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
`SELECT COUNT(*) FROM messages WHERE seenStatus = ${SeenStatus.Unseen};`
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
2,
|
||||||
|
'ending unread count'
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
`SELECT readStatus FROM messages WHERE id = '${MESSAGE_ID_2}' LIMIT 1;`
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
ReadStatus.Unread,
|
||||||
|
'checking read status for message2'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updates unseenStatus for previously-unread messages', () => {
|
||||||
|
const MESSAGE_ID_1 = generateGuid();
|
||||||
|
const MESSAGE_ID_2 = generateGuid();
|
||||||
|
const MESSAGE_ID_3 = generateGuid();
|
||||||
|
const MESSAGE_ID_4 = generateGuid();
|
||||||
|
const MESSAGE_ID_5 = generateGuid();
|
||||||
|
const MESSAGE_ID_6 = generateGuid();
|
||||||
|
const MESSAGE_ID_7 = generateGuid();
|
||||||
|
const MESSAGE_ID_8 = generateGuid();
|
||||||
|
const MESSAGE_ID_9 = generateGuid();
|
||||||
|
const MESSAGE_ID_10 = generateGuid();
|
||||||
|
const MESSAGE_ID_11 = generateGuid();
|
||||||
|
const CONVERSATION_ID = generateGuid();
|
||||||
|
|
||||||
|
updateToVersion(55);
|
||||||
|
|
||||||
|
db.exec(
|
||||||
|
`
|
||||||
|
INSERT INTO messages
|
||||||
|
(id, conversationId, type, readStatus)
|
||||||
|
VALUES
|
||||||
|
('${MESSAGE_ID_1}', '${CONVERSATION_ID}', 'call-history', ${ReadStatus.Unread}),
|
||||||
|
('${MESSAGE_ID_2}', '${CONVERSATION_ID}', 'change-number-notification', ${ReadStatus.Unread}),
|
||||||
|
('${MESSAGE_ID_3}', '${CONVERSATION_ID}', 'chat-session-refreshed', ${ReadStatus.Unread}),
|
||||||
|
('${MESSAGE_ID_4}', '${CONVERSATION_ID}', 'delivery-issue', ${ReadStatus.Unread}),
|
||||||
|
('${MESSAGE_ID_5}', '${CONVERSATION_ID}', 'group', ${ReadStatus.Unread}),
|
||||||
|
('${MESSAGE_ID_6}', '${CONVERSATION_ID}', 'incoming', ${ReadStatus.Unread}),
|
||||||
|
('${MESSAGE_ID_7}', '${CONVERSATION_ID}', 'keychange', ${ReadStatus.Unread}),
|
||||||
|
('${MESSAGE_ID_8}', '${CONVERSATION_ID}', 'timer-notification', ${ReadStatus.Unread}),
|
||||||
|
('${MESSAGE_ID_9}', '${CONVERSATION_ID}', 'verified-change', ${ReadStatus.Unread}),
|
||||||
|
('${MESSAGE_ID_10}', '${CONVERSATION_ID}', NULL, ${ReadStatus.Unread}),
|
||||||
|
('${MESSAGE_ID_11}', '${CONVERSATION_ID}', 'other', ${ReadStatus.Unread});
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
db.prepare('SELECT COUNT(*) FROM messages;').pluck().get(),
|
||||||
|
11,
|
||||||
|
'starting total'
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
`SELECT COUNT(*) FROM messages WHERE readStatus = ${ReadStatus.Unread};`
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
11,
|
||||||
|
'starting unread count'
|
||||||
|
);
|
||||||
|
|
||||||
|
updateToVersion(56);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
db.prepare('SELECT COUNT(*) FROM messages;').pluck().get(),
|
||||||
|
11,
|
||||||
|
'ending total'
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
`SELECT COUNT(*) FROM messages WHERE readStatus = ${ReadStatus.Unread};`
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
10,
|
||||||
|
'ending unread count'
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
`SELECT COUNT(*) FROM messages WHERE seenStatus = ${SeenStatus.Unseen};`
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
10,
|
||||||
|
'ending unseen count'
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
"SELECT readStatus FROM messages WHERE type = 'other' LIMIT 1;"
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
ReadStatus.Read,
|
||||||
|
"checking read status for 'other' message"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Sets readStatus=Read for keychange and change-number-notification messages', () => {
|
||||||
|
const MESSAGE_ID_1 = generateGuid();
|
||||||
|
const MESSAGE_ID_2 = generateGuid();
|
||||||
|
const MESSAGE_ID_3 = generateGuid();
|
||||||
|
const CONVERSATION_ID = generateGuid();
|
||||||
|
|
||||||
|
updateToVersion(57);
|
||||||
|
|
||||||
|
db.exec(
|
||||||
|
`
|
||||||
|
INSERT INTO messages
|
||||||
|
(id, conversationId, type, readStatus)
|
||||||
|
VALUES
|
||||||
|
('${MESSAGE_ID_1}', '${CONVERSATION_ID}', 'incoming', ${ReadStatus.Unread}),
|
||||||
|
('${MESSAGE_ID_2}', '${CONVERSATION_ID}', 'change-number-notification', ${ReadStatus.Unread}),
|
||||||
|
('${MESSAGE_ID_3}', '${CONVERSATION_ID}', 'keychange', ${ReadStatus.Unread});
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
db.prepare('SELECT COUNT(*) FROM messages;').pluck().get(),
|
||||||
|
3,
|
||||||
|
'starting total'
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
`SELECT COUNT(*) FROM messages WHERE readStatus = ${ReadStatus.Unread};`
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
3,
|
||||||
|
'starting unread count'
|
||||||
|
);
|
||||||
|
|
||||||
|
updateToVersion(58);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
db.prepare('SELECT COUNT(*) FROM messages;').pluck().get(),
|
||||||
|
3,
|
||||||
|
'ending total'
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
`SELECT COUNT(*) FROM messages WHERE readStatus = ${ReadStatus.Unread};`
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
1,
|
||||||
|
'ending unread count'
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
"SELECT readStatus FROM messages WHERE type = 'keychange' LIMIT 1;"
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
ReadStatus.Read,
|
||||||
|
"checking read status for 'keychange' message"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
"SELECT seenStatus FROM messages WHERE type = 'keychange' LIMIT 1;"
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
SeenStatus.Unseen,
|
||||||
|
"checking seen status for 'keychange' message"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updates readStatus/seenStatus for messages with unread: true/1 in JSON', () => {
|
||||||
|
const MESSAGE_ID_1 = generateGuid();
|
||||||
|
const MESSAGE_ID_2 = generateGuid();
|
||||||
|
const MESSAGE_ID_3 = generateGuid();
|
||||||
|
const MESSAGE_ID_4 = generateGuid();
|
||||||
|
const CONVERSATION_ID = generateGuid();
|
||||||
|
|
||||||
|
updateToVersion(57);
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
db.exec(
|
||||||
|
`
|
||||||
|
INSERT INTO messages
|
||||||
|
(id, conversationId, type, readStatus, seenStatus, json)
|
||||||
|
VALUES
|
||||||
|
('${MESSAGE_ID_1}', '${CONVERSATION_ID}', 'incoming', ${ReadStatus.Unread}, NULL, '${JSON.stringify(
|
||||||
|
{ body: 'message1' }
|
||||||
|
)}'),
|
||||||
|
('${MESSAGE_ID_2}', '${CONVERSATION_ID}', 'incoming', ${ReadStatus.Read}, NULL, '${JSON.stringify(
|
||||||
|
{ body: 'message2' }
|
||||||
|
)}'),
|
||||||
|
('${MESSAGE_ID_3}', '${CONVERSATION_ID}', 'incoming', NULL, ${SeenStatus.Unseen}, '${JSON.stringify(
|
||||||
|
{ body: 'message3' }
|
||||||
|
)}'),
|
||||||
|
('${MESSAGE_ID_4}', '${CONVERSATION_ID}', 'incoming', NULL, ${SeenStatus.Seen}, '${JSON.stringify(
|
||||||
|
{ body: 'message4' }
|
||||||
|
)}');
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
db.prepare('SELECT COUNT(*) FROM messages;').pluck().get(),
|
||||||
|
4,
|
||||||
|
'starting total'
|
||||||
|
);
|
||||||
|
|
||||||
|
updateToVersion(58);
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
`SELECT json FROM messages WHERE id = '${MESSAGE_ID_1}' LIMIT 1;`
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
JSON.stringify({
|
||||||
|
body: 'message1',
|
||||||
|
readStatus: ReadStatus.Unread,
|
||||||
|
seenStatus: SeenStatus.Unseen,
|
||||||
|
}),
|
||||||
|
'checking JSON for message1'
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
`SELECT json FROM messages WHERE id = '${MESSAGE_ID_2}' LIMIT 1;`
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
JSON.stringify({ body: 'message2', readStatus: ReadStatus.Read }),
|
||||||
|
'checking JSON for message2'
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
`SELECT json FROM messages WHERE id = '${MESSAGE_ID_3}' LIMIT 1;`
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
JSON.stringify({
|
||||||
|
body: 'message3',
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: SeenStatus.Unseen,
|
||||||
|
}),
|
||||||
|
'checking JSON for message3'
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
db
|
||||||
|
.prepare(
|
||||||
|
`SELECT json FROM messages WHERE id = '${MESSAGE_ID_4}' LIMIT 1;`
|
||||||
|
)
|
||||||
|
.pluck()
|
||||||
|
.get(),
|
||||||
|
JSON.stringify({
|
||||||
|
body: 'message4',
|
||||||
|
readStatus: ReadStatus.Read,
|
||||||
|
seenStatus: SeenStatus.Seen,
|
||||||
|
}),
|
||||||
|
'checking JSON for message4'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue