[core-be-agent] ws + bundle: test coverage — hub, helpers, bug fixes #794

Closed
core-be wants to merge 14 commits from feat/org-layout-test-coverage into main

14 Commits

Author SHA1 Message Date
205be877b8 fix(handlers/test): resolve go vet errors — WSMessage fields, unused vars
Some checks failed
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 20s
E2E API Smoke Test / detect-changes (pull_request) Successful in 1m0s
CI / Detect changes (pull_request) Successful in 1m1s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 1m2s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 1m1s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 22s
qa-review / approved (pull_request) Failing after 19s
gate-check-v3 / gate-check (pull_request) Failing after 37s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 56s
security-review / approved (pull_request) Successful in 19s
sop-checklist-gate / gate (pull_request) Successful in 20s
Harness Replays / Harness Replays (pull_request) Successful in 9s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 58s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m25s
sop-tier-check / tier-check (pull_request) Successful in 18s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 2m10s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m47s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 2m8s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 2m15s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 9s
CI / Python Lint & Test (pull_request) Successful in 9s
audit-force-merge / audit (pull_request) Has been skipped
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m50s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 12s
CI / Platform (Go) (pull_request) Failing after 4m20s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Failing after 4m17s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 8m8s
CI / Canvas (Next.js) (pull_request) Successful in 13m48s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 5s
- hub_test.go: replace non-existent Type/Content fields with correct
  WSMessage.Event field throughout
- bundle_helpers_test.go: remove unused want variable in
  TestSplitLines_TrailingNewline and TestSplitLines_SingleCharNoNewline

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 09:36:36 +00:00
616a94fdc3 ci: retrigger gate-check-v3 for core-devops approval
Some checks failed
E2E API Smoke Test / detect-changes (pull_request) Successful in 30s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 31s
Harness Replays / detect-changes (pull_request) Successful in 18s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 26s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 11s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 19s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 39s
qa-review / approved (pull_request) Failing after 22s
security-review / approved (pull_request) Failing after 19s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 48s
gate-check-v3 / gate-check (pull_request) Failing after 33s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, l
sop-checklist-gate / gate (pull_request) Successful in 15s
sop-tier-check / tier-check (pull_request) Successful in 15s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m20s
CI / Canvas (Next.js) (pull_request) Successful in 6s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 5s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m32s
CI / Python Lint & Test (pull_request) Successful in 7s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m58s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m49s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 14s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 2m2s
Harness Replays / Harness Replays (pull_request) Successful in 9s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 11s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 1m49s
CI / Platform (Go) (pull_request) Failing after 3m38s
CI / all-required (pull_request) Successful in 3s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Failing after 3m16s
2026-05-13 09:06:08 +00:00
a132861920 ci: retrigger gate-check-v3 for core-devops approval 2026-05-13 09:06:08 +00:00
86b2935755 [core-be-agent] fix hub_test.go: unbuffered channel hang + pointer identity
Root cause of CI hang (CI / Platform (Go) failing after 2m11s):

1. TestBroadcast_DropsOnClosedChannel: created an UNBUFFERED channel
   (make(chan []byte) with no buffer). When Broadcast calls safeSend on
   this channel, the send blocks indefinitely because nothing is reading
   from it. go test hangs forever waiting for the test to complete.
   Fix: use make(chan []byte, 1) buffered channel, fill and close it
   so safeSend hits the default case (returns false) without blocking.

2. Pointer identity: Broadcast tests used anonymous struct literals in
   h.clients map assignments, but Go map keys store copies of structs.
   The range iteration returns a pointer to the stored COPY, not the
   original literal — so the pointers differ. This matters for tests that
   might assert pointer identity or pass the client to other functions.
   Fix: use named client variables so the map key and Broadcast's
   range both refer to the same *Client pointer. Applied to all
   Broadcast tests defensively.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 09:06:08 +00:00
7ebdbe102c [core-be-agent] fix type mismatch: return sqlmock.Sqlmock (interface), not *sqlmock.Sqlmock
sqlmock.New() returns (Sqlmock, error) where Sqlmock is the interface
type, not a pointer. setupTestDB correctly returns sqlmock.Sqlmock (interface),
but setupWorkspaceCrudTest and setupInstructionsTestDB incorrectly declared
*sqlmock.Sqlmock (pointer to interface). In Go, *Interface is a distinct
type from Interface — this would be a compile error.

Root cause: copy-paste from setupWorkspaceCrudTest where the original author
assumed *sqlmock.Sqlmock was the correct type.

Fix: change both setup functions to return sqlmock.Sqlmock (interface) to
match what sqlmock.New() actually returns.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 09:06:08 +00:00
446ef9c467 [core-be-agent] fix vet warnings: unused variables in hub_test and bundle_helpers_test
Per QA review of PR #794:

1. hub_test.go TestNewHub_WithAccessChecker: `called` was set but never
   read (unused variable → go vet failure). Added assertion that checks
   `called` is true after verifying the access checker was invoked.

2. bundle_helpers_test.go TestSplitLines_Empty: `want` was declared as
   []string{""} but only len(want) was used — the actual content was
   never compared. Fixed to assert len(got)==1 && got[0]=="", which
   validates the correct split behavior for an empty string.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 09:06:08 +00:00
2e261e1b91 [core-be-agent] fix tests: routing engine + setupInstructionsTest
Two compounding test bugs were causing CI failures in the Platform (Go) job:

1. workspace_crud_test.go: 9 Update tests still registered routes on a
   separate r2 := gin.New() but called r.ServeHTTP() on the original
   engine from setupWorkspaceCrudTest. This sent requests to r (which
   had no PATCH route) → 404 instead of the expected validation error.
   Fixed: use r consistently for both route registration and serving.

2. instructions_test.go: setupInstructionsTest() called setupTestDB()
   (which sets global db.DB = mockDB and returns a gin engine with it)
   then DISCARDED that engine and created a fresh gin.New(). Every test
   then created ANOTHER fresh gin.New() for route registration. So the
   route registration and r.ServeHTTP() happened on two completely
   different gin engines — requests never reached the handler at all.
   Fixed: introduce setupInstructionsTestDB() that returns the gin engine
   from setupTestDB, update all tests to use it, and drop the redundant
   gin.New() calls.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 09:06:08 +00:00
31e75cd9e6 [core-be-agent] fix tests: routing r2→r for delete/resolve, CascadeDelete WithArgs
- workspace_crud_test.go: TestDelete_* tests registered routes on r2 but called
  r.ServeHTTP, causing unmocked DB calls. TestUpdate_WorkspaceNotFound same.
  TestCascadeDelete_DescendantQueryError had WithArgs(wsID) but the actual
  QueryContext call passes zero args (workspace ID is embedded in query string).
- instructions_test.go: TestInstructionsDelete_* and TestInstructionsResolve_*
  had same r/r2 routing mismatch.
2026-05-13 09:06:08 +00:00
cbd5d08101 [core-be-agent] bundle: add bundle_helpers_test.go — 17 cases for pure helpers
Tests:
- splitLines: basic, trailing newline, empty, single char
- extractDescription: plain text, after frontmatter, skips comments,
  only comments, empty, frontmatter-only
- nilIfEmpty: empty→nil, non-empty→same
- buildBundleConfigFiles: system prompt, config.yaml prompts, skill files,
  combined, empty bundle
- findConfigDir: exact name match, fallback to first, no dirs→"",
  unreadable dir→""

No go binary in container — validated by CI.
2026-05-13 09:06:08 +00:00
9ce9931f86 [core-be-agent] fix tests: CascadeDelete mock call, instructions r2→r cleanup
- workspace_crud_test.go: TestCascadeDelete_DescendantQueryError was setting
  a mock expectation but never calling CascadeDelete — sqlmock would report
  "expected query not executed" at test end. Now calls CascadeDelete directly
  with a minimal handler (nil deps are fine since the error path returns
  before StopWorkspace/RemoveVolume are reached).

- instructions_test.go: All Create/Update tests declared r2:=gin.New() then
  called r2.ServeHTTP while the setup's r engine sat unused. Unified to use
  r consistently (the r2 declarations were already renamed to r in the
  prior edit pass). Also removed dead code in TestInstructionsCreate_HappyPath
  (r.POST routed to h.List on an unused engine).
2026-05-13 09:06:08 +00:00
379f41814a [core-be-agent]
ws: add hub_test.go — 13 cases for NewHub, safeSend, Broadcast, Close

Covers:
- NewHub: nil checker, access checker wiring
- safeSend: open, closed, and full channel paths
- Broadcast: canvas always-receives, workspace CanCommunicate gating,
  drops on closed/full, empty hub, multi-client, canvas-ignores-checker
- Close: disconnects all, idempotent, closes done channel

No go binary in container — validated by CI.
2026-05-13 09:06:08 +00:00
848b2d96ca test(handlers): add org_layout_test.go — 16 cases for childSlot/sizeOfSubtree/childSlotInGrid
Pure layout helper functions that compute canvas node positions and subtree
bounding boxes. Covers leaf/branch/deep-nesting subtree sizes, uniform
and variable sibling grid layouts, empty-siblings edge case, overflow index.

Closes test coverage gap on org.go canvas layout helpers.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 09:06:08 +00:00
c09a5000b2 test(handlers): add workspace_crud_test.go — 20 cases for State/Update/Delete
Covers State (legacy, auth-required, not found, soft-deleted, query error),
Update (invalid UUID/body/not found, field length limits, newline/YAML-char
rejection, workspace_dir validation), Delete (invalid UUID, children
confirmation gate, query error), validateWorkspaceID, validateWorkspaceFields,
validateWorkspaceDir helpers. Closes test coverage gap on workspace_crud.go.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 09:06:08 +00:00
14739a19c7 test(handlers): add instructions_test.go — 17 cases for InstructionsHandler
Covers List (workspace scope, global-only, query error),
Create (happy path, missing required, invalid scope, workspace
without target, content/title too long, insert error),
Update (happy path, partial, content/title too long, not found,
update error), Delete (happy path, not found, delete error),
Resolve (no instructions, global only, global+workspace,
query error, missing workspace ID), and scanInstructions helper
(empty rows, scan error).

Fixes gap: instructions.go had zero unit test coverage.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 09:06:08 +00:00