Skip to content

test(job): cover job tool validation and state transitions#681

Open
Protocol-zero-0 wants to merge 1 commit intonearai:mainfrom
Protocol-zero-0:test/job-tool-coverage
Open

test(job): cover job tool validation and state transitions#681
Protocol-zero-0 wants to merge 1 commit intonearai:mainfrom
Protocol-zero-0:test/job-tool-coverage

Conversation

@Protocol-zero-0
Copy link

Summary

  • add focused tests for job tool parameter validation, list formatting, status transitions, and cancel behavior
  • verify list summaries stay scoped to the current user and report readable status labels
  • lock in the current behavior for cancelling running jobs vs. already completed jobs

Why

The job tool surface has useful coverage already, but several user-facing paths still relied on implicit behavior. These tests make the small but important responses around validation and job lifecycle changes explicit, which lowers regression risk for future refactors.

Tests

  • cargo test --lib test_create_job_params
  • target/debug/deps/ironclaw-6fd0143b37beb5d3 --exact tools::builtin::job::tests::test_list_jobs_formatting
  • target/debug/deps/ironclaw-6fd0143b37beb5d3 --exact tools::builtin::job::tests::test_job_status_transitions
  • target/debug/deps/ironclaw-6fd0143b37beb5d3 --exact tools::builtin::job::tests::test_cancel_job_running
  • target/debug/deps/ironclaw-6fd0143b37beb5d3 --exact tools::builtin::job::tests::test_cancel_job_completed
  • cargo fmt --check

Notes

  • I intentionally excluded unrelated Cargo.lock updates caused by local dependency resolution so this PR stays test-only.
  • I did not rerun full cargo clippy --all --benches --tests --examples --all-features -- -D warnings on the rebased branch because local disk pressure from a fresh full rebuild on current main caused repeated out-of-space failures. The same test-only diff passed full clippy before the rebase, and the targeted tests above were rerun after rebasing this branch onto current main.

Made with Cursor

Add focused coverage for create/list/status/cancel job tools so validation errors, summary formatting, and cancellation behavior stay stable. This locks in the current user-facing responses for running and completed jobs without changing production code.

Made-with: Cursor
Copilot AI review requested due to automatic review settings March 7, 2026 21:10
@github-actions github-actions bot added scope: tool/builtin Built-in tools size: M 50-199 changed lines risk: medium Business logic, config, or moderate-risk modules labels Mar 7, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the robustness of the job tool by introducing comprehensive test coverage for previously implicit behaviors. The added tests explicitly validate job creation parameters, ensure correct formatting and user-specific scoping of job lists, and solidify the lifecycle management of jobs, particularly around state transitions and cancellation logic. This effort aims to reduce regression risks during future refactoring by making these critical user-facing interactions explicit and thoroughly tested.

Highlights

  • Job Tool Parameter Validation: Added focused tests to ensure proper validation of parameters for job creation.
  • Job List Formatting and Scoping: Verified that job list summaries are correctly formatted, scoped to the current user, and display readable status labels.
  • Job State Transitions and Cancellation Behavior: Implemented tests for job status transitions and confirmed the expected behavior when cancelling running versus already completed jobs.
Changelog
  • src/tools/builtin/job.rs
    • Added test_create_job_params to validate required parameters for job creation.
    • Introduced test_list_jobs_formatting to verify job list output, user-specific filtering, and status display.
    • Created test_job_status_transitions to confirm correct job state changes.
    • Added test_cancel_job_running to ensure a running job can be successfully cancelled.
    • Implemented test_cancel_job_completed to verify that completed jobs cannot be cancelled.
Activity
  • The author provided specific cargo test commands to run the newly added tests.
  • The author explicitly excluded Cargo.lock updates to maintain focus on the test-only changes.
  • The author noted that a full cargo clippy run was skipped due to local disk space constraints but confirmed previous passes and targeted test reruns after rebasing.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds valuable test coverage for the job management tools, specifically focusing on parameter validation, job listing formats, status transitions, and cancellation behavior. The new tests help solidify the existing behavior and prevent future regressions.

I've found one critical issue in the test_create_job_params test where the use of unwrap_err() after borrowing the Result with is_err() will cause a compilation failure. I've provided a code suggestion to fix this by using the more idiomatic expect_err() method, which aligns with our guidelines for clear test failures. The other tests appear to be well-structured and correctly verify the intended tool behaviors.

Comment on lines +1425 to +1445
let missing_title = tool
.execute(serde_json::json!({ "description": "A test job" }), &ctx)
.await;
assert!(missing_title.is_err());
assert!(
missing_title
.unwrap_err()
.to_string()
.contains("missing 'title' parameter")
);

let missing_description = tool
.execute(serde_json::json!({ "title": "Test Job" }), &ctx)
.await;
assert!(missing_description.is_err());
assert!(
missing_description
.unwrap_err()
.to_string()
.contains("missing 'description' parameter")
);
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

This test contains a pattern that will fail to compile. The unwrap_err() method consumes the Result, so it cannot be used after is_err() has already borrowed it. A more idiomatic and robust way to write this test is to use expect_err(), which asserts that the result is an Err and returns the error value, making the test cleaner and more direct. This approach aligns with the principle of using expect() in tests to explicitly fail with clear messages, as outlined in our repository's code review guidelines.

Suggested change
let missing_title = tool
.execute(serde_json::json!({ "description": "A test job" }), &ctx)
.await;
assert!(missing_title.is_err());
assert!(
missing_title
.unwrap_err()
.to_string()
.contains("missing 'title' parameter")
);
let missing_description = tool
.execute(serde_json::json!({ "title": "Test Job" }), &ctx)
.await;
assert!(missing_description.is_err());
assert!(
missing_description
.unwrap_err()
.to_string()
.contains("missing 'description' parameter")
);
let missing_title_err = tool
.execute(serde_json::json!({ "description": "A test job" }), &ctx)
.await
.expect_err("should fail without title");
assert!(
missing_title_err
.to_string()
.contains("missing 'title' parameter")
);
let missing_description_err = tool
.execute(serde_json::json!({ "title": "Test Job" }), &ctx)
.await
.expect_err("should fail without description");
assert!(
missing_description_err
.to_string()
.contains("missing 'description' parameter")
);
References
  1. In tests, when setting up a state that depends on environmental factors (e.g., system uptime for time calculations), prefer expect() to explicitly fail the test with a clear message if the setup is not possible. Avoid fallbacks like unwrap_or() that could cause the test to silently check the wrong logic.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds additional unit tests in the built-in job tool module to explicitly cover parameter validation failures, list output formatting/summarization, job state transitions, and cancellation behavior.

Changes:

  • Add tests for create_job parameter validation error paths.
  • Add tests for list_jobs formatting + per-user scoping and summary counts.
  • Add tests for job_status transition timestamps and cancel_job behavior across running vs. completed jobs.

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

Comment on lines +1491 to +1502
assert!(jobs.iter().any(|job| {
job.get("job_id").and_then(|v| v.as_str()) == Some(&pending_id.to_string())
&& job.get("status").and_then(|v| v.as_str()) == Some("Pending")
}));
assert!(jobs.iter().any(|job| {
job.get("job_id").and_then(|v| v.as_str()) == Some(&completed_id.to_string())
&& job.get("status").and_then(|v| v.as_str()) == Some("Completed")
}));
assert!(jobs.iter().any(|job| {
job.get("job_id").and_then(|v| v.as_str()) == Some(&failed_id.to_string())
&& job.get("status").and_then(|v| v.as_str()) == Some("Failed")
}));
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

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

These assertions expect status values like "Pending"/"Completed"/"Failed", but the codebase generally serializes JobState as snake_case via JobState::to_string() (e.g., the web jobs API returns state: ctx.state.to_string()). Locking TitleCase here will cement an inconsistent API across job surfaces (create_job/cancel_job already return lowercase). Consider updating ListJobsTool to emit status: ctx.state.to_string() and adjust this test to expect "pending"/"completed"/"failed" accordingly.

Copilot uses AI. Check for mistakes.

assert_eq!(
result.result.get("status").and_then(|v| v.as_str()),
Some("Completed")
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

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

This test expects job_status.status to be "Completed" (Debug formatting), but other parts of the codebase (and JobState's Display) use snake_case ("completed"). To keep the tool API consistent with create_job/cancel_job and the web jobs endpoints, consider changing JobStatusTool to use job_ctx.state.to_string() and update this assertion to expect "completed".

Suggested change
Some("Completed")
Some("completed")

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: new First-time contributor risk: medium Business logic, config, or moderate-risk modules scope: tool/builtin Built-in tools size: M 50-199 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants