Skip to content

Commit 42275c7

Browse files
committed
chats: mint URI for messages document
1 parent 6cf8e8e commit 42275c7

5 files changed

Lines changed: 110 additions & 2 deletions

File tree

chats/rdflib/src/module/ChatsModuleRdfLib.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { createChat } from "./update-operations/index.js";
1818
import { ChatQuery } from "./queries/index.js";
1919
import { MessagesDocumentQuery } from "./queries/MessagesDocumentQuery.js";
2020
import { DateContainerQuery } from "./queries/DateContainerQuery.js";
21+
import { mintMessageUri } from './uris/index.js';
2122

2223
interface ModuleConfig {
2324
store: IndexedFormula;
@@ -101,7 +102,7 @@ export class ChatsModuleRdfLib implements ChatsModule {
101102
}
102103

103104
// eslint-disable-next-line @typescript-eslint/no-unused-vars
104-
postMessage(command: PostMessageCommand): Promise<string> {
105-
throw new Error("Method not implemented.");
105+
async postMessage({ chatUri }: PostMessageCommand): Promise<string> {
106+
return mintMessageUri(sym(chatUri));
106107
}
107108
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { setupModule } from "../../test-support/setupModule";
2+
import { generateId } from "@solid-data-modules/rdflib-utils/identifier";
3+
import { when } from "jest-when";
4+
import { mockTurtleDocument } from "@solid-data-modules/rdflib-utils/test-support";
5+
6+
jest.mock("@solid-data-modules/rdflib-utils/identifier");
7+
8+
describe("post message", () => {
9+
it("creates the message in a document for the current date and returns the minted URI", async () => {
10+
// given a random ID is generated
11+
when(generateId).mockReturnValue("8c615b");
12+
13+
// and today is a specific date
14+
jest.useFakeTimers({
15+
now: new Date("2024-07-30"),
16+
});
17+
18+
// and a chats module
19+
const authenticatedFetch = jest.fn();
20+
const chats = setupModule(authenticatedFetch);
21+
22+
// and an existing chat document
23+
mockTurtleDocument(
24+
authenticatedFetch,
25+
"https://pod.test/alice/chats/abc123/index.ttl",
26+
`
27+
<#this> a <http://www.w3.org/ns/pim/meeting#LongChat>;
28+
<http://purl.org/dc/elements/1.1/title> "An existing chat channel".
29+
`,
30+
);
31+
32+
// when a message is posted to the chat
33+
const uri = await chats.postMessage({
34+
chatUri: "https://pod.test/alice/chats/abc123/index.ttl#this",
35+
text: "A new message",
36+
authorWebId: "https://pod.test/alice/profile/card#me",
37+
});
38+
39+
// then the minted URI is returned
40+
expect(uri).toMatch(
41+
new RegExp(
42+
"https://pod.test/alice/chats/abc123/2024/07/30/chat.ttl#8c615b",
43+
),
44+
);
45+
});
46+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { mintMessageUri } from './mintMessageUri.js';
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { generateId } from "@solid-data-modules/rdflib-utils/identifier";
2+
import { when } from "jest-when";
3+
import { mintMessageUri } from "./mintMessageUri";
4+
import { sym } from "rdflib";
5+
6+
jest.mock("@solid-data-modules/rdflib-utils/identifier");
7+
8+
describe("mintMessageUri", () => {
9+
it("creates a new URI based on the chat container, the current date and a random ID", () => {
10+
// given a random ID is generated
11+
when(generateId).mockReturnValue("qwerty123");
12+
13+
// and today is this date
14+
jest.useFakeTimers({
15+
now: new Date("2024-08-15"),
16+
});
17+
18+
// and a chat node
19+
20+
const chatNode = sym("https://pod.test/chat/123/index.ttl#this");
21+
22+
// when a URI for a message is minted
23+
const result = mintMessageUri(chatNode);
24+
25+
// then
26+
expect(result).toEqual(
27+
"https://pod.test/chat/123/2024/08/15/chat.ttl#qwerty123",
28+
);
29+
});
30+
31+
it("fails if chat has no container", () => {
32+
// given a random ID is generated
33+
when(generateId).mockReturnValue("qwerty123");
34+
35+
// and today is this date
36+
jest.useFakeTimers({
37+
now: new Date("2024-08-15"),
38+
});
39+
40+
// and a chat node
41+
const chatNode = sym("https://pod.test");
42+
43+
// when a URI for a message is minted
44+
expect(() => mintMessageUri(chatNode)).toThrow(
45+
new Error("Chat https://pod.test has no container"),
46+
);
47+
});
48+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { NamedNode } from "rdflib";
2+
import { generateId } from "@solid-data-modules/rdflib-utils/identifier";
3+
4+
export function mintMessageUri(chatNode: NamedNode) {
5+
const date = new Date();
6+
const dateFolders = date.toISOString().split("T")[0].replace(/-/g, "/");
7+
const container = chatNode.doc().dir();
8+
if (!container) {
9+
throw new Error(`Chat ${chatNode.uri} has no container`);
10+
}
11+
return container.uri + dateFolders + "/chat.ttl#" + generateId();
12+
}

0 commit comments

Comments
 (0)