test(server/share): implement basic shaca mocking with content

This commit is contained in:
Elian Doran 2025-09-28 14:40:30 +03:00
parent 804fc72ed8
commit a393584a2a
No known key found for this signature in database
3 changed files with 108 additions and 13 deletions

View File

@ -1,12 +1,12 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { renderCode, renderText, type Result } from "./content_renderer.js"; import { getContent, renderCode, renderText, type Result } from "./content_renderer.js";
import { trimIndentation } from "@triliumnext/commons"; import { trimIndentation } from "@triliumnext/commons";
import SNote from "./shaca/entities/snote.js"; import { buildShareNote } from "../test/shaca_mocking.js";
describe("content_renderer", () => { describe("content_renderer", () => {
describe("renderText", () => { describe("renderText", () => {
it("parses simple note", () => { it("parses simple note", () => {
const input = trimIndentation`\ const content = trimIndentation`\
<figure class="image image-style-align-right image_resized" style="width:29.84%;"> <figure class="image image-style-align-right image_resized" style="width:29.84%;">
<img style="aspect-ratio:150/150;" src="api/attachments/TnyuBzEXJZln/image/Trilium Demo_icon-color.svg" width="150" height="150"> <img style="aspect-ratio:150/150;" src="api/attachments/TnyuBzEXJZln/image/Trilium Demo_icon-color.svg" width="150" height="150">
</figure> </figure>
@ -15,14 +15,12 @@ describe("content_renderer", () => {
Welcome to Trilium Notes! Welcome to Trilium Notes!
</strong> </strong>
</p>`; </p>`;
const note = buildShareNote({
const result = { title: "Note",
content: input, content
header: "", });
isEmpty: false const result = getContent(note);
}; expect(result.content).toStrictEqual(content);
renderText(result, new SNote([ "root", "Note", "text", "text/plain", "1234", "2025-09-28T00:00Z", false]));
expect(result.content).toMatch(input);
}); });
}); });

View File

@ -16,7 +16,7 @@ export interface Result {
isEmpty?: boolean; isEmpty?: boolean;
} }
function getContent(note: SNote) { export function getContent(note: SNote) {
if (note.isProtected) { if (note.isProtected) {
return { return {
header: "", header: "",
@ -65,7 +65,7 @@ function renderIndex(result: Result) {
result.content += "</ul>"; result.content += "</ul>";
} }
function renderText(result: Result, note: SNote) { export function renderText(result: Result, note: SNote) {
const document = new JSDOM(result.content || "").window.document; const document = new JSDOM(result.content || "").window.document;
// Process include notes. // Process include notes.

View File

@ -0,0 +1,97 @@
import utils from "../services/utils.js";
import SAttribute from "../share/shaca/entities/sattribute.js";
import SNote from "../share/shaca/entities/snote.js";
import shaca from "../share/shaca/shaca.js";
type AttributeDefinitions = { [key in `#${string}`]: string; };
type RelationDefinitions = { [key in `~${string}`]: string; };
interface NoteDefinition extends AttributeDefinitions, RelationDefinitions {
id?: string | undefined;
title: string;
content?: string | Buffer<ArrayBufferLike>;
}
/**
* Creates the given notes with the given title and optionally one or more attributes.
*
* For a label to be created, simply pass on a key prefixed with `#` and any desired value.
*
* The notes and attributes will be injected in the froca.
*
* @param notes
* @returns an array containing the IDs of the created notes.
* @example
* buildShareNotes([
* { title: "A", "#startDate": "2025-05-05" },
* { title: "B", "#startDate": "2025-05-07" }
* ]);
*/
export function buildShareNotes(notes: NoteDefinition[]) {
const ids: string[] = [];
for (const noteDef of notes) {
ids.push(buildShareNote(noteDef).noteId);
}
return ids;
}
export function buildShareNote(noteDef: NoteDefinition) {
const blobId = "foo";
const note = new SNote([
noteDef.id ?? utils.randomString(12),
noteDef.title,
"text",
"text/html",
blobId,
new Date().toUTCString(), // utcDateModified
false // is protected
]);
shaca.notes[note.noteId] = note;
// Handle content
if (noteDef.content) {
note.getContent = () => noteDef.content;
}
// Handle labels & relations
let position = 0;
for (const [ key, value ] of Object.entries(noteDef)) {
const attributeId = utils.randomString(12);
const name = key.substring(1);
let attribute: SAttribute | null = null;
if (key.startsWith("#")) {
attribute = new SAttribute([
attributeId,
note.noteId,
"label",
name,
value,
false, // isInheritable
position // position
]);
}
if (key.startsWith("~")) {
attribute = new SAttribute([
attributeId,
note.noteId,
"relation",
name,
value,
false, // isInheritable
position // position
]);
}
if (!attribute) {
continue;
}
shaca.attributes[attributeId] = attribute;
position++;
}
return note;
}