Skip to content

test(agent-service): cover the auth, workflow, and backend API clients - #7384

Open
aglinxinyuan wants to merge 2 commits into
apache:mainfrom
aglinxinyuan:test-agent-api
Open

test(agent-service): cover the auth, workflow, and backend API clients#7384
aglinxinyuan wants to merge 2 commits into
apache:mainfrom
aglinxinyuan:test-agent-api

Conversation

@aglinxinyuan

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

Three of the four API clients under agent-service/src/api had no spec. auth-api.ts is the one that decides whether a request is authenticated at all, and none of its decisions were pinned.

Adds 30 tests across three spec files, following the fetch-spy pattern already established by compile-api.spec.ts.

auth-api — several of these are policy choices that read like oversights, so the tests state the intent rather than just the behaviour:

Input Result
token with no exp valid — tokens minted without an expiry never expire
malformed token invalid — the decode error is swallowed and reported as expired, not thrown
payload with no role REGULAR, so absent means least privilege
bearer / BEARER accepted; the scheme is matched case-insensitively
two-segment token whose payload parses rejected

workflow-api — the workflow content round-trips as a nested JSON string: the request sends JSON.stringify(content) and the response is re-parsed when it comes back as a string. Sending the object directly is the obvious-looking mistake and the backend rejects it, so both directions are pinned, along with the empty-description default and the error text on a refused save or a missing workflow.

backend-api — the endpoint set, the defensive copy of the module-level config, and the two failure paths of the metadata fetch.

Verified by mutation, all reverted (production diff empty):

Mutation Result
default a missing role to ADMIN red
remove the three-segment check red
treat a token with no exp as expired red
compare exp as milliseconds instead of seconds red
make the Bearer scheme case-sensitive red
report a malformed token as valid red
send content as a nested object red
drop the empty-description default red
stop re-parsing a stringified response content red
drop the wid from the retrieve URL red
return the shared config by reference red

The three-segment mutation initially survived: the test used "only.two", whose payload fails JSON.parse regardless, so the segment check was never actually exercised. Replaced with a two-segment token carrying a valid payload — an unsigned token — which is the case the check exists for.

No production file is touched.

Any related issues, documentation, discussions?

Closes #7381

How was this PR tested?

bun test
 232 pass
 0 fail
Ran 232 tests across 18 files.

bun run typecheck and bun run format:check both pass.

Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Opus 5)

Three of the four API clients under src/api had no spec. auth-api is the one
that decides whether a request is authenticated at all, and none of its
decisions were pinned.

Adds 30 tests:

- auth-api: JWT decoding and its segment-count check, the REGULAR role default,
  expiry in seconds, the never-expires case of a token without exp, and Bearer
  header parsing.
- workflow-api: the nested JSON-string encoding of workflow content in both
  directions, the empty-description default, and the error text on a refused
  save or a missing workflow.
- backend-api: the endpoint set, the defensive copy of the shared config, and
  the metadata fetch's failure paths.

No production file is touched.
Copilot AI lite review requested due to automatic review settings August 7, 2026 04:08
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • No candidates found from git blame history.

@codecov-commenter

codecov-commenter commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.45%. Comparing base (99b07db) to head (dc459d5).
⚠️ Report is 17 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #7384      +/-   ##
============================================
+ Coverage     84.24%   84.45%   +0.20%     
  Complexity     4142     4142              
============================================
  Files          1169     1169              
  Lines         46745    46734      -11     
  Branches       5201     5201              
============================================
+ Hits          39381    39469      +88     
+ Misses         5663     5564      -99     
  Partials       1701     1701              
Flag Coverage Δ *Carryforward flag
access-control-service 70.00% <ø> (ø) Carriedforward from 5b5b8c7
agent-service 86.87% <ø> (+3.22%) ⬆️
amber 80.74% <ø> (ø) Carriedforward from 5b5b8c7
computing-unit-managing-service 50.72% <ø> (ø) Carriedforward from 5b5b8c7
config-service 65.97% <ø> (ø) Carriedforward from 5b5b8c7
file-service 69.05% <ø> (ø) Carriedforward from 5b5b8c7
frontend 85.81% <ø> (ø) Carriedforward from 5b5b8c7
notebook-migration-service 78.89% <ø> (ø) Carriedforward from 5b5b8c7
pyamber 97.40% <ø> (ø) Carriedforward from 5b5b8c7
workflow-compiling-service 26.31% <ø> (ø) Carriedforward from 5b5b8c7

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Bun test coverage for the agent-service API client layer under agent-service/src/api, pinning current behavior for auth token handling, workflow persistence/retrieval (including nested JSON string encoding of workflow content), and backend operator-metadata fetching/config exposure.

Changes:

  • Added new specs for auth-api, covering JWT decoding/validation policy decisions and header parsing/creation.
  • Added new specs for workflow-api, covering persist/retrieve request shapes, content stringification/parsing, and error propagation.
  • Added new specs for backend-api, covering config copying semantics and operator-metadata fetch success/failure paths.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
agent-service/src/api/workflow-api.spec.ts Adds tests for workflow persist/retrieve request/response encoding and error handling.
agent-service/src/api/backend-api.spec.ts Adds tests for backend config copying and operator-metadata fetch failure modes.
agent-service/src/api/auth-api.spec.ts Adds tests pinning JWT decode/expiry policy and Bearer header handling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread agent-service/src/api/auth-api.spec.ts Outdated
import { describe, expect, test } from "bun:test";
import { createAuthHeaders, extractBearerToken, extractUserFromToken, validateToken } from "./auth-api";

/** Builds a token with the given payload. Only the payload segment is ever read back. */

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — reworded. The helper now says all three segments are required and that only the payload one is decoded, so the header and signature just have to be present.

Comment thread agent-service/src/api/auth-api.spec.ts Outdated
return `header.${encoded}.signature`;
}

const SECONDS = 1000;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — dropped the constant instead of renaming it. exp is a UNIX second count, so the expiries are now built in seconds (nowInSeconds() + 60) and there is no ms/s conversion left to reason about. Re-ran the two mutations that cover these lines (relax the three-segment check, compare exp as milliseconds) — both still red.

@aglinxinyuan
aglinxinyuan requested a review from mengw15 August 7, 2026 05:36

@mengw15 mengw15 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Address review comments on the auth-api spec.

The `tokenWith` doc said only the payload segment is ever read back, which
reads as if a two-segment token would do; `decodeJWT` requires exactly three.

`SECONDS = 1000` was a millisecond conversion factor under a name that reads
as a second count. `exp` is a UNIX second count, so build the expiries in
seconds via a `nowInSeconds` helper and drop the conversion entirely.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cover the agent service's auth, workflow, and backend API clients

4 participants