Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  canvas-documents.test.ts

  Sprache: JAVA
 

Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

import { mkdtemp, mkdir, writeFile, readFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import {
  buildCanvasDocumentEntryUrl,
  createCanvasDocument,
  resolveCanvasDocumentAssets,
  resolveCanvasDocumentDir,
  resolveCanvasHttpPathToLocalPath,
} from "./canvas-documents.js";

const tempDirs: string[] = [];

afterEach(async () => {
  await Promise.all(
    tempDirs.splice(0).map(async (dir) => {
      await import("node:fs/promises").then((fs) => fs.rm(dir, { recursive: true, force: true }));
    }),
  );
});

describe("canvas documents", () => {
  it("builds entry urls for materialized path documents under managed storage", async () => {
    const stateDir = await mkdtemp(path.join(tmpdir(), "openclaw-canvas-documents-"));
    tempDirs.push(stateDir);
    const workspaceDir = await mkdtemp(path.join(tmpdir(), "openclaw-canvas-documents-workspace-"));
    tempDirs.push(workspaceDir);
    await mkdir(path.join(workspaceDir, "player"), { recursive: true });
    await writeFile(path.join(workspaceDir, "player/index.html"), "<div>ok</div>", "utf8");

    const document = await createCanvasDocument(
      {
        kind: "html_bundle",
        entrypoint: {
          type: "path",
          value: "player/index.html",
        },
      },
      { stateDir, workspaceDir },
    );

    expect(document.entryUrl).toContain("/__openclaw__/canvas/documents/");
    expect(document.localEntrypoint).toBe("index.html");
    expect(resolveCanvasDocumentDir(document.id, { stateDir })).toContain(stateDir);
  });

  it("normalizes nested local entrypoint urls", () => {
    const url = buildCanvasDocumentEntryUrl("cv_example", "collection.media/index.html");
    expect(url).toBe("/__openclaw__/canvas/documents/cv_example/collection.media/index.html");
  });

  it("encodes special characters in hosted entrypoint path segments", () => {
    const url = buildCanvasDocumentEntryUrl("cv_example", "bundle#1/entry%20point?.html");
    expect(url).toBe(
      "/__openclaw__/canvas/documents/cv_example/bundle%231/entry%2520point%3F.html",
    );
  });

  it("materializes inline html bundles as index documents", async () => {
    const stateDir = await mkdtemp(path.join(tmpdir(), "openclaw-canvas-documents-"));
    tempDirs.push(stateDir);

    const document = await createCanvasDocument(
      {
        kind: "html_bundle",
        title: "Preview",
        entrypoint: {
          type: "html",
          value:
            "<!doctype html><html><head><style>.demo{color:red}</style></head><body><div class='demo'>Front</div></body></html>",
        },
      },
      { stateDir },
    );

    const indexHtml = await import("node:fs/promises").then((fs) =>
      fs.readFile(
        path.join(resolveCanvasDocumentDir(document.id, { stateDir }), "index.html"),
        "utf8",
      ),
    );

    expect(indexHtml).toContain("<div class='demo'>Front</div>");
    expect(indexHtml).toContain("<style>.demo{color:red}</style>");
    expect(document.title).toBe("Preview");
    expect(document.entryUrl).toBe(`/__openclaw__/canvas/documents/${document.id}/index.html`);
  });

  it("reuses a supplied stable document id by replacing the prior materialized view", async () => {
    const stateDir = await mkdtemp(path.join(tmpdir(), "openclaw-canvas-documents-"));
    tempDirs.push(stateDir);

    const first = await createCanvasDocument(
      {
        id: "status-card",
        kind: "html_bundle",
        entrypoint: { type: "html", value: "<div>first</div>" },
      },
      { stateDir },
    );
    const second = await createCanvasDocument(
      {
        id: "status-card",
        kind: "html_bundle",
        entrypoint: { type: "html", value: "<div>second</div>" },
      },
      { stateDir },
    );

    expect(first.id).toBe("status-card");
    expect(second.id).toBe("status-card");

    const indexHtml = await import("node:fs/promises").then((fs) =>
      fs.readFile(
        path.join(resolveCanvasDocumentDir(second.id, { stateDir }), "index.html"),
        "utf8",
      ),
    );
    expect(indexHtml).toContain("second");
    expect(indexHtml).not.toContain("first");
  });

  it("exposes stable managed asset urls for copied canvas assets", async () => {
    const stateDir = await mkdtemp(path.join(tmpdir(), "openclaw-canvas-documents-"));
    tempDirs.push(stateDir);
    const workspaceDir = await mkdtemp(path.join(tmpdir(), "openclaw-canvas-documents-workspace-"));
    tempDirs.push(workspaceDir);
    await mkdir(path.join(workspaceDir, "collection.media"), { recursive: true });
    await writeFile(path.join(workspaceDir, "collection.media/audio.mp3"), "audio", "utf8");

    const document = await createCanvasDocument(
      {
        kind: "html_bundle",
        entrypoint: {
          type: "html",
          value:
            '<audio controls><source src="collection.media/audio.mp3" type="audio/mpeg" /></audio>',
        },
        assets: [
          {
            logicalPath: "collection.media/audio.mp3",
            sourcePath: "collection.media/audio.mp3",
            contentType: "audio/mpeg",
          },
        ],
      },
      { stateDir, workspaceDir },
    );

    expect(resolveCanvasDocumentAssets(document, { stateDir })).toEqual([
      {
        logicalPath: "collection.media/audio.mp3",
        contentType: "audio/mpeg",
        localPath: path.join(
          resolveCanvasDocumentDir(document.id, { stateDir }),
          "collection.media/audio.mp3",
        ),
        url: `/__openclaw__/canvas/documents/${document.id}/collection.media/audio.mp3`,
      },
    ]);
    expect(
      resolveCanvasDocumentAssets(document, {
        baseUrl: "http://127.0.0.1:19003",
        stateDir,
      }),
    ).toEqual([
      {
        logicalPath: "collection.media/audio.mp3",
        contentType: "audio/mpeg",
        localPath: path.join(
          resolveCanvasDocumentDir(document.id, { stateDir }),
          "collection.media/audio.mp3",
        ),
        url: `http://127.0.0.1:19003/__openclaw__/canvas/documents/${document.id}/collection.media/audio.mp3`,
      },
    ]);
  });

  it("wraps local pdf documents in an index viewer page", async () => {
    const stateDir = await mkdtemp(path.join(tmpdir(), "openclaw-canvas-documents-"));
    tempDirs.push(stateDir);
    const workspaceDir = await mkdtemp(path.join(tmpdir(), "openclaw-canvas-documents-workspace-"));
    tempDirs.push(workspaceDir);
    await writeFile(path.join(workspaceDir, "demo.pdf"), "%PDF-1.4", "utf8");

    const document = await createCanvasDocument(
      {
        kind: "document",
        entrypoint: {
          type: "path",
          value: "demo.pdf",
        },
      },
      { stateDir, workspaceDir },
    );

    expect(document.entryUrl).toBe(`/__openclaw__/canvas/documents/${document.id}/index.html`);
    const indexHtml = await readFile(
      path.join(resolveCanvasDocumentDir(document.id, { stateDir }), "index.html"),
      "utf8",
    );
    expect(indexHtml).toContain('type="application/pdf"');
    expect(indexHtml).toContain('data="demo.pdf"');
  });

  it("wraps remote pdf urls in an index viewer page", async () => {
    const stateDir = await mkdtemp(path.join(tmpdir(), "openclaw-canvas-documents-"));
    tempDirs.push(stateDir);

    const document = await createCanvasDocument(
      {
        kind: "document",
        entrypoint: {
          type: "url",
          value: "https://example.com/demo.pdf",
        },
      },
      { stateDir },
    );

    expect(document.entryUrl).toBe(`/__openclaw__/canvas/documents/${document.id}/index.html`);
    const indexHtml = await readFile(
      path.join(resolveCanvasDocumentDir(document.id, { stateDir }), "index.html"),
      "utf8",
    );
    expect(indexHtml).toContain('type="application/pdf"');
    expect(indexHtml).toContain('data="https://example.com/demo.pdf"');
  });

  it("rejects traversal-style document ids in hosted canvas paths", async () => {
    const stateDir = await mkdtemp(path.join(tmpdir(), "openclaw-canvas-documents-"));
    tempDirs.push(stateDir);

    expect(
      resolveCanvasHttpPathToLocalPath(
        "/__openclaw__/canvas/documents/../collection.media/index.html",
        { stateDir },
      ),
    ).toBeNull();
  });
});

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge