fix: clear main CI deploy blockers #1856

Merged
hongming merged 1 commits from fix/main-ci-display-deploy-blockers into main 2026-05-25 20:09:54 +00:00
3 changed files with 28 additions and 20 deletions
@@ -201,15 +201,13 @@ describe("CreateWorkspaceDialog — WCAG SC 1.3.1 label/input association", () =
expect(label?.textContent).toContain("Budget limit");
});
it("Template input has a <label> whose htmlFor matches the input id", async () => {
it("Workspace Template select has a <label> whose htmlFor matches the select id", async () => {
await openDialog();
const templateInput = screen.getByPlaceholderText(
"e.g. seo-agent (from workspace-configs-templates/)"
) as HTMLInputElement;
expect(templateInput.id).toBeTruthy();
const label = document.querySelector(`label[for="${templateInput.id}"]`);
const templateSelect = screen.getByLabelText("Workspace Template") as HTMLSelectElement;
expect(templateSelect.id).toBeTruthy();
const label = document.querySelector(`label[for="${templateSelect.id}"]`);
expect(label).toBeTruthy();
expect(label?.textContent).toContain("Template");
expect(label?.textContent).toContain("Workspace Template");
});
it("each InputField generates a distinct id (no id collisions)", async () => {
@@ -218,13 +216,16 @@ describe("CreateWorkspaceDialog — WCAG SC 1.3.1 label/input association", () =
screen.getByPlaceholderText("e.g. SEO Agent"),
screen.getByPlaceholderText("e.g. SEO Specialist"),
screen.getByPlaceholderText("e.g. 100"),
screen.getByPlaceholderText("e.g. seo-agent (from workspace-configs-templates/)"),
] as HTMLInputElement[];
const selects = [
screen.getByLabelText("Runtime"),
screen.getByLabelText("Workspace Template"),
] as HTMLSelectElement[];
const ids = inputs.map((i) => i.id).filter(Boolean);
const ids = [...inputs, ...selects].map((i) => i.id).filter(Boolean);
const unique = new Set(ids);
expect(unique.size).toBe(ids.length); // no duplicates
expect(ids.length).toBe(4);
expect(ids.length).toBe(5);
});
it("Name label text contains the required asterisk indicator", async () => {
+9 -6
View File
@@ -4,9 +4,10 @@
# Round-trip: register a workspace as poll-mode (no callback URL) → POST a
# multi-file chat upload → verify each file becomes (a) one
# `chat_upload_receive` activity row and (b) one /pending-uploads row → fetch
# the bytes back via the poll endpoint → ack → verify the row 404s on
# subsequent fetch. Also pins cross-workspace bleed protection: workspace B
# cannot read workspace A's pending uploads even with its own valid bearer.
# the bytes back via the poll endpoint → ack → verify the row stays readable
# during retention for refreshed canvas previews. Also pins cross-workspace
# bleed protection: workspace B cannot read workspace A's pending uploads even
# with its own valid bearer.
#
# Why this exists separately from test_chat_upload_e2e.sh: that script
# covers the PUSH path (the workspace's own /internal/chat/uploads/ingest).
@@ -218,14 +219,16 @@ case "$RE_ACK1_CODE" in
;;
esac
# ---------- Phase 7: GET content after ack returns 404 ----------
# ---------- Phase 7: GET content after ack remains readable ----------
echo ""
echo "--- Phase 7: Acked file 404s on subsequent fetch ---"
echo "--- Phase 7: Acked file remains readable during retention ---"
POST_ACK=$(curl -s -w '\n%{http_code}' --max-time "$TIMEOUT" -H "Authorization: Bearer $TOK_A" \
"$BASE/workspaces/$WS_A/pending-uploads/$FID1/content")
POST_ACK_CODE=$(printf '%s' "$POST_ACK" | tail -n1)
check_eq "acked alpha returns HTTP 404" "404" "$POST_ACK_CODE"
POST_ACK_BODY=$(printf '%s' "$POST_ACK" | sed '$d')
check_eq "acked alpha returns HTTP 200" "200" "$POST_ACK_CODE"
check_eq "acked alpha bytes still readable" "$EXPECTED1" "$POST_ACK_BODY"
# ---------- Phase 8: cross-workspace bleed protection ----------
echo ""
@@ -124,13 +124,17 @@ func TestIntegration_PendingUploads_PutGetAckRoundTrip(t *testing.T) {
t.Errorf("FetchedAt should be set after MarkFetched")
}
// Ack flips acked_at; subsequent Gets return ErrNotFound (acked rows
// are filtered out at the SELECT predicate).
// Ack flips acked_at. Acked rows remain readable during retention so
// refreshed canvas previews can resolve platform-pending: attachment URIs.
if err := store.Ack(ctx, fileID); err != nil {
t.Fatalf("Ack: %v", err)
}
if _, err := store.Get(ctx, fileID); err != pendinguploads.ErrNotFound {
t.Errorf("Get after Ack: got %v, want ErrNotFound", err)
rec3, err := store.Get(ctx, fileID)
if err != nil {
t.Fatalf("Get after Ack: %v", err)
}
if rec3.AckedAt == nil {
t.Errorf("AckedAt should be set after Ack")
}
// Idempotent re-ack succeeds.