Skip to content

Commit e75f1f4

Browse files
committed
[red] require consistent Google Play open-testing copy
Signed-off-by: Viwat Vchirawongkwin <viwat.v@chula.ac.th>
1 parent b063121 commit e75f1f4

3 files changed

Lines changed: 62 additions & 41 deletions

File tree

‎tests/publication/test_public_claims.py‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,15 @@ def test_readme_distinguishes_app_source_from_store_availability(self) -> None:
188188
firmware = markdown_section(self.readme, "What works")
189189
normalized = " ".join(firmware.split())
190190
self.assertIn("0.2.0+8", firmware)
191-
self.assertIn("does not establish a live store release", normalized)
191+
self.assertIn("Google Play open testing", normalized)
192+
self.assertIn("published Android version is `0.2.0`", normalized)
193+
self.assertIn("exact source", normalized)
194+
self.assertIn("later connection-lifecycle fixes", normalized)
195+
self.assertIn(
196+
"https://play.google.com/store/apps/details?id=dev.pyble.pyble",
197+
self.readme,
198+
)
199+
self.assertNotRegex(self.readme, r"(?i)Android (?:invited|internal) test")
192200
self.assertIn("offline privacy policy", normalized)
193201
self.assertIn("multi-file deletion", normalized)
194202

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

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { render, screen, within } from "@testing-library/react";
1010
import { describe, expect, it, vi } from "vitest";
1111

1212
import AppPage, { metadata as appMetadata } from "@/app/app/page";
13+
import SetupPage from "@/app/learn/setup/page";
1314
import FlashPage, { metadata as flashMetadata } from "@/app/flash/page";
1415
import { metadata as rootMetadata } from "@/app/layout";
1516
import HomePage, { metadata as homeMetadata } from "@/app/page";
@@ -135,6 +136,32 @@ function jpegDimensions(bytes: Buffer): { width: number; height: number } {
135136
}
136137

137138
describe("public-site contract", () => {
139+
it.each([
140+
["home", HomePage],
141+
["app", AppPage],
142+
["setup", SetupPage],
143+
])(
144+
"keeps %s installation copy consistent with public Android open testing",
145+
(_name, Page) => {
146+
const { container } = render(<Page />);
147+
expect(container).toHaveTextContent(/Google Play open testing/i);
148+
expect(container).not.toHaveTextContent(
149+
/invited|invitation.only|internal test|approved testers|unapproved|not (?:a )?public Google Play release/i,
150+
);
151+
},
152+
);
153+
154+
it("describes Android open testing in search and social metadata", () => {
155+
for (const metadata of [rootMetadata, homeMetadata, appMetadata]) {
156+
expect(metadata.description).toMatch(/Google Play open testing/i);
157+
expect(JSON.stringify(metadata)).not.toMatch(/invited|internal test/i);
158+
}
159+
for (const metadata of [rootMetadata, appMetadata]) {
160+
expect(metadata.openGraph?.description).toBe(metadata.description);
161+
expect(metadata.twitter?.description).toBe(metadata.description);
162+
}
163+
});
164+
138165
it("keeps pyble.dev canonical and presents Features and Learn in the primary routes", () => {
139166
expect(siteConfig.origin).toBe("https://pyble.dev");
140167
expect(siteConfig.alternateOrigin).toBe("https://pyble.org");
@@ -148,7 +175,7 @@ describe("public-site contract", () => {
148175

149176
it("publishes canonical metadata and static discovery files", async () => {
150177
expect(siteConfig.description).toBe(
151-
"A free, open-source, tablet-first IDE for MicroPython boards with compatible Bluetooth Low Energy agent firmware.",
178+
"PyBLE is a free, open-source MicroPython IDE over Bluetooth Low Energy. Available on Google Play open testing for Android and TestFlight for iPad.",
152179
);
153180
expect(homeMetadata.title).toEqual({
154181
absolute: "PyBLE — Python over Bluetooth Low Energy",
@@ -159,7 +186,7 @@ describe("public-site contract", () => {
159186
});
160187
expect(appMetadata.title).toBe("PyBLE for iPad and Android");
161188
expect(appMetadata.description).toMatch(
162-
/ipad external beta.*android internal test/i,
189+
/google play open testing.*ipad external beta/i,
163190
);
164191
expect(privacyMetadata.alternates).toEqual({
165192
canonical: "https://pyble.dev/privacy",
@@ -240,7 +267,7 @@ describe("public-site contract", () => {
240267
expect(manifest).toMatchObject({
241268
short_name: "PyBLE",
242269
description:
243-
"A free, open-source, tablet-first IDE for MicroPython boards with compatible Bluetooth Low Energy agent firmware.",
270+
"PyBLE is a free, open-source MicroPython IDE over Bluetooth Low Energy. Available on Google Play open testing for Android and TestFlight for iPad.",
244271
start_url: "/",
245272
theme_color: "#081B35",
246273
});
@@ -404,7 +431,7 @@ describe("public-site contract", () => {
404431
screen.getByText("Python over Bluetooth Low Energy"),
405432
).toBeInTheDocument();
406433
expect(
407-
screen.getByText("iPad external beta + Android internal test"),
434+
screen.getByText("iPad external beta + Android open testing"),
408435
).toBeInTheDocument();
409436
expect(
410437
screen.getByRole("link", {
@@ -556,22 +583,19 @@ describe("public-site contract", () => {
556583
);
557584

558585
const androidSection = screen.getByRole("region", {
559-
name: "Join the PyBLE Android internal test.",
586+
name: "Get PyBLE on Google Play.",
560587
});
561588
expect(channelGroup).toContainElement(testFlightSection);
562589
expect(channelGroup).toContainElement(androidSection);
563590
expect(testFlightSection.parentElement).toBe(androidSection.parentElement);
564591
expect(testFlightSection.parentElement).toHaveClass("beta-channel-grid");
565592
expect(testFlightSection.nextElementSibling).toBe(androidSection);
566-
expect(
567-
within(androidSection).getByText(/approved internal testers/i),
568-
).toBeInTheDocument();
569-
expect(
570-
within(androidSection).getByText(/not a public Google Play release/i),
571-
).toBeInTheDocument();
572-
expect(
573-
within(androidSection).getByText(/unapproved.*may.*unavailable/i),
574-
).toBeInTheDocument();
593+
expect(androidSection).toHaveTextContent(
594+
/PyBLE 0\.2\.0 is available on Google Play open testing/i,
595+
);
596+
expect(androidSection).not.toHaveTextContent(
597+
/internal test|invited|approved testers|not a public Google Play release/i,
598+
);
575599

576600
const testFlightLink = within(testFlightSection).getByRole("link", {
577601
name: "Open in TestFlight",
@@ -581,7 +605,7 @@ describe("public-site contract", () => {
581605
expect(testFlightLink).toHaveAttribute("rel", "noopener noreferrer");
582606

583607
const googlePlayLink = within(androidSection).getByRole("link", {
584-
name: "Open Android internal test",
608+
name: "Get PyBLE on Google Play",
585609
});
586610
expect(googlePlayLink).toHaveAttribute("href", googlePlayUrl);
587611
expect(googlePlayLink).toHaveAttribute("target", "_blank");
@@ -602,7 +626,7 @@ describe("public-site contract", () => {
602626
).toHaveAttribute("src", "/testflight/pyble-testflight-qr.svg");
603627

604628
const googlePlayQrDescription =
605-
"QR code for the PyBLE Android internal test on Google Play";
629+
"QR code for PyBLE on Google Play open testing";
606630
const googlePlayQrLink = within(androidSection).getByRole("link", {
607631
name: googlePlayQrDescription,
608632
});
@@ -613,10 +637,7 @@ describe("public-site contract", () => {
613637
within(androidSection).getByRole("img", {
614638
name: googlePlayQrDescription,
615639
}),
616-
).toHaveAttribute(
617-
"src",
618-
"/google-play/pyble-google-play-internal-test-qr.svg",
619-
);
640+
).toHaveAttribute("src", "/google-play/pyble-google-play-qr.svg");
620641

621642
expect(
622643
within(testFlightSection).getByText("testflight.apple.com/join/yU4e8s6d"),
@@ -654,7 +675,7 @@ describe("public-site contract", () => {
654675
process.cwd(),
655676
"public",
656677
"google-play",
657-
"pyble-google-play-internal-test-qr.svg",
678+
"pyble-google-play-qr.svg",
658679
),
659680
sha256:
660681
"fbd84d11d773346d0a2cd23f0e3193d02ff02e6c9780298294431d95dd07f32d",
@@ -684,7 +705,7 @@ describe("public-site contract", () => {
684705
expect(siteConfig.testFlightUrl).toBe(
685706
"https://testflight.apple.com/join/yU4e8s6d",
686707
);
687-
expect(siteConfig.googlePlayInternalTestUrl).toBe(
708+
expect(siteConfig.googlePlayUrl).toBe(
688709
"https://play.google.com/store/apps/details?id=dev.pyble.pyble",
689710
);
690711

@@ -696,12 +717,9 @@ describe("public-site contract", () => {
696717
expect(testFlightLink).toHaveAttribute("rel", "noopener noreferrer");
697718

698719
const googlePlayLink = screen.getByRole("link", {
699-
name: "Open Android internal test",
720+
name: "Get PyBLE on Google Play",
700721
});
701-
expect(googlePlayLink).toHaveAttribute(
702-
"href",
703-
siteConfig.googlePlayInternalTestUrl,
704-
);
722+
expect(googlePlayLink).toHaveAttribute("href", siteConfig.googlePlayUrl);
705723
expect(googlePlayLink).toHaveAttribute("target", "_blank");
706724
expect(googlePlayLink).toHaveAttribute("rel", "noopener noreferrer");
707725

@@ -717,23 +735,18 @@ describe("public-site contract", () => {
717735
).toBeInTheDocument();
718736
expect(
719737
screen.getByRole("img", {
720-
name: "QR code for the PyBLE Android internal test on Google Play",
738+
name: "QR code for PyBLE on Google Play open testing",
721739
}),
722-
).toHaveAttribute(
723-
"src",
724-
"/google-play/pyble-google-play-internal-test-qr.svg",
725-
);
740+
).toHaveAttribute("src", "/google-play/pyble-google-play-qr.svg");
726741
expect(
727-
screen.getByText(siteConfig.googlePlayInternalTestUrl, {
742+
screen.getByText(siteConfig.googlePlayUrl, {
728743
selector: ".app-install__direct span",
729744
}),
730745
).toBeInTheDocument();
731-
expect(screen.getByText(/approved internal testers/i)).toBeInTheDocument();
732-
expect(
733-
screen.getByText(/not a public Google Play release/i),
734-
).toBeInTheDocument();
735746
expect(
736-
screen.getByText(/unapproved.*may.*unavailable/i),
747+
screen.getByText(
748+
/PyBLE 0\.2\.0 is available on Google Play open testing/i,
749+
),
737750
).toBeInTheDocument();
738751
expect(
739752
screen.getByRole("link", { name: /open firmware installer/i }),

‎tools/web/src/test/sites-output.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ describe("Sites vinext-output adapter", () => {
266266
);
267267
const googlePlayQr = await worker.fetch(
268268
new Request(
269-
"https://pyble.dev/google-play/pyble-google-play-internal-test-qr.svg",
269+
"https://pyble.dev/google-play/pyble-google-play-qr.svg",
270270
),
271271
{},
272272
context,
@@ -384,7 +384,7 @@ describe("Sites vinext-output adapter", () => {
384384
},
385385
googlePlayQr: {
386386
status: 200,
387-
body: "vinext:/google-play/pyble-google-play-internal-test-qr.svg:execution-context",
387+
body: "vinext:/google-play/pyble-google-play-qr.svg:execution-context",
388388
},
389389
firmwareManifest: {
390390
status: 200,

0 commit comments

Comments
 (0)