ConusAI vendor v0.1.0-dev.20261027+9b1131fb
ci / gate (push) Waiting to run

This commit is contained in:
ConusAI vendor v0.1.0-dev.20261027+9b1131fb
2026-10-27 18:05:17 +00:00
commit 3102273ec7
538 changed files with 80203 additions and 0 deletions
+222
View File
@@ -0,0 +1,222 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// The brand as a share image and an email show it (spec §10.2, §10.3): the app brand's name and logo, or an
// organization's, drawn through the kit's logo checks. Every logo here goes the way it goes in production: an
// organization's through the caller (so a stored, normalised file), the app's from a file of a public folder.
import { mkdtempSync, rmSync, writeFileSync } from "node:fs"
import { tmpdir } from "node:os"
import { join } from "node:path"
import {
type BrandView,
type ComposedEmail,
composeEmail,
type MailTransport,
renderShareImage,
type ShareBrand,
sendEmail,
shareBrand,
} from "@app/modules/branding"
import { afterEach, describe, expect, it } from "vitest"
import { appLogoSource, readersFor } from "../apps/web/src/server/brand-assets"
import { closeApps, makeDocumentsApp, type SeededProject } from "./support/documents-app.js"
import { dimensions, markPng, pixelAt } from "./support/images.js"
const directories: string[] = []
afterEach(async () => {
await closeApps()
for (const dir of directories.splice(0)) rmSync(dir, { recursive: true, force: true })
})
const TEAL = [0x80, 0xcd, 0xc6, 255]
const svg = (fill: string) =>
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 80"><rect width="300" height="80" fill="${fill}"/></svg>`
/** A public folder holding the app brand's two logos: a blue rectangle for light, a red one for dark. */
function publicFolder(): string {
const dir = mkdtempSync(join(tmpdir(), "share-public-"))
directories.push(dir)
writeFileSync(join(dir, "app-light.svg"), svg("#3366aa"))
writeFileSync(join(dir, "app-dark.svg"), svg("#aa3333"))
return dir
}
const appIdentity = { name: "Example App", logo: { light: "/app-light.svg", dark: "/app-dark.svg" } }
const empty: BrandView = { displayName: null, primary: null, accent: null, logoLight: null, logoDark: null }
async function acme(): Promise<{ project: SeededProject }> {
const app = await makeDocumentsApp({
document: { engine: { name: "unused", version: "0" }, page_count: 0, pages: [] },
})
return { project: await app.seedProject("acme", "owner@acme.test") }
}
const upload = (project: SeededProject, variant: "light" | "dark", bytes: Uint8Array) =>
project.call.callByName("branding.logo.set", {
org: project.orgSlug,
variant,
contentType: "image/png",
body: Buffer.from(bytes).toString("base64"),
})
// The logo box of the share image: 300 x 80 at (80, 80); a wide logo's middle is at (230, 120).
const logoCentre = (png: Uint8Array) => pixelAt(png, 230, 120)
describe("the app brand's logo from the public folder", () => {
it("is read from a file of the folder and from nowhere else", async () => {
const dir = publicFolder()
expect(await appLogoSource("/app-dark.svg", dir)).toMatchObject({ contentType: "image/svg+xml" })
await expect(appLogoSource("/../secret.svg", dir)).rejects.toThrow(/public folder/)
await expect(appLogoSource("/app.exe", dir)).rejects.toThrow(/PNG, WebP or SVG/)
await expect(appLogoSource("/missing.svg", dir)).rejects.toThrow()
})
})
describe("the share image", () => {
it("draws the app brand's logo for the dark page when there is no organization", async () => {
const dir = publicFolder()
const share = await shareBrand({
app: appIdentity,
tenant: null,
readers: { appLogo: (path) => appLogoSource(path, dir), tenantLogo: () => Promise.reject(new Error("none")) },
})
expect(share.name).toBe("Example App")
const png = await renderShareImage(share, { title: share.name })
expect(dimensions(png)).toEqual({ width: 1200, height: 630 })
expect(logoCentre(png)).toEqual([0xaa, 0x33, 0x33, 255])
})
it("draws an organization's own logo and display name, and the logo is the stored one", async () => {
const { project } = await acme()
await project.call.callByName("branding.brand.set", { org: project.orgSlug, displayName: "Acme Review" })
await upload(project, "dark", markPng(2000, 500))
const brand = (await project.call.callByName("branding.brand.get", { org: project.orgSlug })) as BrandView
const share = await shareBrand({
app: appIdentity,
tenant: { name: "Acme Ltd", brand },
readers: readersFor(project.call, project.orgSlug, publicFolder()),
})
expect(share.name).toBe("Acme Review")
expect(share.logo.contentType).toBe("image/png")
expect(logoCentre(await renderShareImage(share, { title: share.name }))).toEqual(TEAL)
})
it("draws the only logo the organization has when it is the light one, because the page is dark", async () => {
const { project } = await acme()
await upload(project, "light", markPng(2000, 500))
const brand = (await project.call.callByName("branding.brand.get", { org: project.orgSlug })) as BrandView
expect(brand.logoDark).toBeNull()
const share = await shareBrand({
app: appIdentity,
tenant: { name: "Acme Ltd", brand },
readers: readersFor(project.call, project.orgSlug, publicFolder()),
})
expect(share.name).toBe("Acme Ltd")
expect(logoCentre(await renderShareImage(share, { title: share.name }))).toEqual(TEAL)
})
it("is not stopped by a missing app logo file when the organization has a good logo of its own", async () => {
const { project } = await acme()
await upload(project, "dark", markPng(2000, 500))
const brand = (await project.call.callByName("branding.brand.get", { org: project.orgSlug })) as BrandView
const share = await shareBrand({
app: appIdentity,
tenant: { name: "Acme Ltd", brand },
readers: readersFor(project.call, project.orgSlug, mkdtempSync(join(tmpdir(), "share-nofile-"))),
})
expect(logoCentre(await renderShareImage(share, { title: share.name }))).toEqual(TEAL)
})
it("falls back to the app brand's logo for an organization with none", async () => {
const { project } = await acme()
const share = await shareBrand({
app: appIdentity,
tenant: { name: "Acme Ltd", brand: empty },
readers: readersFor(project.call, project.orgSlug, publicFolder()),
})
expect(logoCentre(await renderShareImage(share, { title: share.name }))).toEqual([0xaa, 0x33, 0x33, 255])
})
it("draws the app brand's logo instead when the chosen one cannot be drawn, and does not fail", async () => {
const dir = publicFolder()
const broken: ShareBrand = {
name: "Acme Ltd",
logo: { contentType: "image/png", bytes: new TextEncoder().encode("<svg/>") },
fallback: await appLogoSource("/app-dark.svg", dir),
}
expect(logoCentre(await renderShareImage(broken, { title: broken.name }))).toEqual([0xaa, 0x33, 0x33, 255])
const refused: ShareBrand = { ...broken, fallback: broken.logo }
await expect(renderShareImage(refused, { title: "x" })).rejects.toThrow(/logo cannot be used/)
})
})
describe("the email", () => {
const recorded = () => {
const sent: Array<ComposedEmail & { to: string }> = []
const transport: MailTransport = {
async send(message) {
sent.push(message)
},
}
return { sent, transport }
}
async function shareOf(logo: Uint8Array | null, dir = publicFolder()): Promise<ShareBrand> {
const { project } = await acme()
if (logo) await upload(project, "dark", logo)
const brand = (await project.call.callByName("branding.brand.get", { org: project.orgSlug })) as BrandView
return shareBrand({
app: appIdentity,
tenant: { name: "Acme Ltd", brand: { ...brand, displayName: "Acme Review" } },
readers: readersFor(project.call, project.orgSlug, dir),
})
}
it("carries the organization's name and its logo as an inline attachment, and names no host", async () => {
const mail = await composeEmail(await shareOf(markPng(2000, 500)), {
subject: "You are invited",
paragraphs: ["Hello,", "Open the app to accept."],
})
expect(mail.subject).toBe("You are invited - Acme Review")
expect(mail.html).toContain('alt="Acme Review"')
expect(mail.html).toContain('src="cid:brand-logo"')
expect(mail.html).not.toMatch(/https?:/)
expect(mail.html.toLowerCase()).not.toContain("conusai")
expect(mail.text).toBe("Hello,\n\nOpen the app to accept.\n\nAcme Review\n")
const [logo] = mail.attachments
expect(logo).toMatchObject({ cid: "brand-logo", contentType: "image/png" })
expect(dimensions(logo?.content ?? new Uint8Array())).toEqual({ width: 420, height: 105 })
expect(pixelAt(logo?.content ?? new Uint8Array(), 210, 52)).toEqual(TEAL)
})
it("uses the app brand's logo for an organization with none", async () => {
const mail = await composeEmail(await shareOf(null), { subject: "Hi", paragraphs: ["x"] })
const content = mail.attachments[0]?.content ?? new Uint8Array()
expect(dimensions(content).width).toBe(420)
expect(pixelAt(content, 210, 52)).toEqual([0xaa, 0x33, 0x33, 255])
})
it("escapes what it is given as text, and refuses a subject that is more than one line", async () => {
const share = await shareOf(null)
const mail = await composeEmail(share, { subject: "x", paragraphs: ['<script>alert("1")</script> & more'] })
expect(mail.html).toContain("&#60;script&#62;alert(&#34;1&#34;)&#60;/script&#62; &#38; more")
expect(mail.html).not.toContain("<script>")
await expect(composeEmail(share, { subject: "x\r\nBcc: someone@example.test", paragraphs: ["x"] })).rejects.toThrow(
/one line/,
)
await expect(composeEmail(share, { subject: "x", paragraphs: [] })).rejects.toThrow(/paragraph/)
})
it("is handed to the transport with one address, and refuses an address that carries a header", async () => {
const share = await shareOf(null)
const { sent, transport } = recorded()
await sendEmail(transport, share, "member@acme.test", { subject: "Welcome", paragraphs: ["Hello"] })
expect(sent).toHaveLength(1)
expect(sent[0]).toMatchObject({ to: "member@acme.test", subject: "Welcome - Acme Review" })
for (const to of ["a@b.test\r\nBcc: c@d.test", "a@b.test, c@d.test", "no-address", "a b@c.test"]) {
await expect(sendEmail(transport, share, to, { subject: "x", paragraphs: ["x"] })).rejects.toThrow(
/one email address/,
)
}
expect(sent).toHaveLength(1)
})
})