Files
Toju/toju-app/src/app/domains/chat/domain/rules/message-revision.builder.rules.spec.ts
2026-06-05 18:34:01 +02:00

95 lines
2.6 KiB
TypeScript

import {
describe,
it,
expect
} from 'vitest';
import type { Message } from '../../../../shared-kernel';
import {
buildMessageRevision,
materializeMessageFromRevision,
revisionBeatsMessage
} from './message-revision.builder.rules';
function createMessage(overrides: Partial<Message> = {}): Message {
return {
id: 'message-1',
roomId: 'room-1',
senderId: 'user-1',
senderName: 'User 1',
content: 'hello',
timestamp: 1_000,
reactions: [],
isDeleted: false,
...overrides
};
}
describe('message-revision.builder.rules', () => {
it('builds create revisions at revision zero', async () => {
const message = createMessage();
const revision = await buildMessageRevision({
message,
type: 'create',
actorId: 'user-1',
editedAt: 1_000
});
expect(revision.revision).toBe(0);
expect(revision.headHash).toMatch(/^[a-f0-9]{64}$/);
expect(revision.type).toBe('create');
});
it('increments revision for author edits', async () => {
const message = createMessage({ revision: 0, headHash: 'abc' });
const revision = await buildMessageRevision({
message,
type: 'author-edit',
actorId: 'user-1',
content: 'edited',
editedAt: 2_000,
prevRevisionHash: 'abc'
});
expect(revision.revision).toBe(1);
expect(revision.prevRevisionHash).toBe('abc');
expect(revision.content).toBe('edited');
});
it('materializes message state from a revision', async () => {
const revision = await buildMessageRevision({
message: createMessage(),
type: 'author-edit',
actorId: 'user-1',
content: 'edited',
editedAt: 2_000
});
const materialized = materializeMessageFromRevision(createMessage(), revision);
expect(materialized.revision).toBe(1);
expect(materialized.content).toBe('edited');
expect(materialized.headHash).toBe(revision.headHash);
});
it('detects when a revision should replace local state', async () => {
const local = materializeMessageFromRevision(
createMessage({ revision: 0, headHash: 'old' }),
await buildMessageRevision({
message: createMessage(),
type: 'create',
actorId: 'user-1',
editedAt: 1_000
})
);
const incoming = await buildMessageRevision({
message: createMessage({ revision: 0, headHash: local.headHash }),
type: 'author-edit',
actorId: 'user-1',
content: 'edited',
editedAt: 2_000,
prevRevisionHash: local.headHash ?? ''
});
expect(revisionBeatsMessage(incoming, local)).toBe(true);
});
});