Skip to content

Commit 02c88eb

Browse files
committed
[red] require consistent v0.6.1 home support tutorials and social metadata
Signed-off-by: Viwat Vchirawongkwin <viwat.v@chula.ac.th>
1 parent 7fae9ac commit 02c88eb

2 files changed

Lines changed: 62 additions & 11 deletions

File tree

‎tools/web/src/test/site-contract.test.tsx‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -204,19 +204,19 @@ describe("public-site contract", () => {
204204
"https://pyble.dev/learn/waveshare-lcd-147b",
205205
]);
206206
expect(sitemap).toMatch(
207-
/<loc>https:\/\/pyble\.dev\/privacy<\/loc>\s*<lastmod>2026-08-28T00:00:00\.000Z<\/lastmod>/,
207+
/<loc>https:\/\/pyble\.dev\/privacy<\/loc>\s*<lastmod>2026-09-11T00:00:00\.000Z<\/lastmod>/,
208208
);
209209
expect(sitemap).toMatch(
210-
/<loc>https:\/\/pyble\.dev\/<\/loc>\s*<lastmod>2026-08-28T00:00:00\.000Z<\/lastmod>/,
210+
/<loc>https:\/\/pyble\.dev\/<\/loc>\s*<lastmod>2026-09-11T00:00:00\.000Z<\/lastmod>/,
211211
);
212212
expect(sitemap).toMatch(
213-
/<loc>https:\/\/pyble\.dev\/app<\/loc>\s*<lastmod>2026-08-28T00:00:00\.000Z<\/lastmod>/,
213+
/<loc>https:\/\/pyble\.dev\/app<\/loc>\s*<lastmod>2026-09-11T00:00:00\.000Z<\/lastmod>/,
214214
);
215215
expect(sitemap).toMatch(
216-
/<loc>https:\/\/pyble\.dev\/support<\/loc>\s*<lastmod>2026-08-28T00:00:00\.000Z<\/lastmod>/,
216+
/<loc>https:\/\/pyble\.dev\/support<\/loc>\s*<lastmod>2026-09-11T00:00:00\.000Z<\/lastmod>/,
217217
);
218218
expect(sitemap).toContain(
219-
"<loc>https://pyble.dev/features</loc>\n <lastmod>2026-09-01T00:00:00.000Z</lastmod>",
219+
"<loc>https://pyble.dev/features</loc>\n <lastmod>2026-09-11T00:00:00.000Z</lastmod>",
220220
);
221221
for (const path of [
222222
"/learn",
@@ -232,7 +232,7 @@ describe("public-site contract", () => {
232232
"/learn/waveshare-lcd-147b",
233233
]) {
234234
expect(sitemap).toContain(
235-
`<loc>https://pyble.dev${path}</loc>\n <lastmod>2026-08-28T00:00:00.000Z</lastmod>`,
235+
`<loc>https://pyble.dev${path}</loc>\n <lastmod>2026-09-11T00:00:00.000Z</lastmod>`,
236236
);
237237
}
238238
expect(robots).toContain("Host: https://pyble.dev");
@@ -247,8 +247,8 @@ describe("public-site contract", () => {
247247
});
248248

249249
it("publishes a real-app large social card and local TestFlight card", async () => {
250-
const socialPngName = "pyble-beta-og-277eee8a-1200x630.png";
251-
const socialSvgName = "pyble-beta-og-b47b6d10-1200x630.svg";
250+
const socialPngName = "pyble-v061-og-297b270f-1200x630.png";
251+
const socialSvgName = "pyble-v061-og-d3bab0c0-1200x630.svg";
252252
const socialUrl = `https://pyble.dev/social/${socialPngName}`;
253253
expect(rootMetadata.openGraph?.images).toEqual([
254254
{
@@ -285,7 +285,7 @@ describe("public-site contract", () => {
285285
]);
286286
expect(socialSvg).toContain("One-time USB setup.");
287287
expect(socialSvg).toContain("Everyday coding over BLE.");
288-
expect(socialSvg).toContain("WEB FLASHING VALIDATED");
288+
expect(socialSvg).toContain("FIRMWARE v0.6.1 AVAILABLE");
289289
expect(socialSvg).not.toContain("FIRMWARE HIL PENDING");
290290
const socialPngSha256 = createHash("sha256")
291291
.update(socialPng)
@@ -294,10 +294,10 @@ describe("public-site contract", () => {
294294
.update(socialSvg)
295295
.digest("hex");
296296
expect(socialPngSha256).toBe(
297-
"277eee8ae859c3e26444df830cf1b03f624f2be1f1524bc3246ce2d946332023",
297+
"297b270fd4ec7637752ff954416cf4ca69570992b28d48b4530982db07c03af9",
298298
);
299299
expect(socialSvgSha256).toBe(
300-
"b47b6d10d6de3e16a5687680d8f34f115f9a276d0fdbde06051751de2270ddfd",
300+
"d3bab0c05e2c07783b6f7006a7cd8152b4b0a8798f4ade55e31d28076cb9bb1f",
301301
);
302302
expect(socialPngName).toContain(socialPngSha256.slice(0, 8));
303303
expect(socialSvgName).toContain(socialSvgSha256.slice(0, 8));
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// SPDX-License-Identifier: MIT
2+
// Part of PyBLE (https://pyble.dev) — see /LICENSE.
3+
import { render, screen } from "@testing-library/react";
4+
import { afterEach, describe, expect, it, vi } from "vitest";
5+
import HomePage from "@/app/page";
6+
import SupportPage from "@/app/support/page";
7+
import LearnPage from "@/app/learn/page";
8+
import FilesPage from "@/app/learn/files/page";
9+
import FirstProgramPage from "@/app/learn/first-program/page";
10+
import { firmwareProfileDescriptors, type FirmwareReleaseDescriptor } from "@/lib/firmware-release";
11+
import * as selection from "@/lib/firmware-release-selection";
12+
import { firmwareTargetsForRelease } from "@/lib/site";
13+
14+
const release: FirmwareReleaseDescriptor = {
15+
deployment: "owner-confirmed", accessControlled: false, version: "0.6.1",
16+
builtAt: "2026-09-11T03:59:01Z", hilStatus: "pending",
17+
releaseJson: { path: "/firmware/v0.6.1/release.json", sha256: "71f6aca6df07e31a1f54c7f70a48d82c7fe26b1c8ca0626a8ffc57c804fbb1bd" },
18+
schemaPath: "/firmware/v0.6.1/release.schema.json",
19+
recoveryPath: "/firmware/v0.6.1/RECOVERY.md",
20+
profiles: firmwareProfileDescriptors("0.6.1"),
21+
};
22+
afterEach(() => vi.restoreAllMocks());
23+
describe("current v0.6.1 website consistency", () => {
24+
it.each([HomePage, SupportPage])("presents the owner-confirmed release as available", (Page) => {
25+
vi.spyOn(selection, "firmwareReleaseSelectedAtBuild").mockReturnValue(release);
26+
const {container} = render(<Page />);
27+
expect(container).toHaveTextContent(/v0.6.1 firmware is available/i);
28+
expect(container).not.toHaveTextContent(/Protected candidate v0.6.1|installer is currently unavailable/i);
29+
});
30+
it("gives all five target cards the same release status", () => {
31+
const targets=firmwareTargetsForRelease(release);
32+
expect(targets).toHaveLength(5);
33+
for(const target of targets) {
34+
expect(target.status).toBe("v0.6.1 public release · owner-confirmed");
35+
expect(target.planned).toBe(false);
36+
}
37+
});
38+
it("separates current tutorial guidance from historic captures", () => {
39+
render(<FilesPage />);
40+
expect(screen.getByRole("region", {name:"Tutorial overview"})).toHaveTextContent(/firmware 0.6.1/i);
41+
expect(screen.getByText(/historical screenshots/i)).toBeVisible();
42+
expect(screen.getByText(/all five official profiles use LFS2/i)).toBeVisible();
43+
});
44+
it("updates the Learn hub and explains fresh globals", () => {
45+
const hub=render(<LearnPage />);
46+
expect(hub.container).toHaveTextContent(/firmware 0.6.1/i);
47+
hub.unmount();
48+
const first=render(<FirstProgramPage />);
49+
expect(first.container).toHaveTextContent(/fresh globals/i);
50+
});
51+
});

0 commit comments

Comments
 (0)