8000 added test cases and unit tests by dotandev · Pull Request #46 · biyard/dagit · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

added test cases and unit tests #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 12, 2025
Merged

Conversation

dotandev
Copy link
Contributor
@dotandev dotandev commented Mar 11, 2025

added unit tests and updated github workflow.

help review the test mod in main.rs and it's implementation in agit/test.rs

Summary by CodeRabbit

  • New Features
    • Introduced utilities for secure hashing and precise time formatting.
    • Added a new GitHub Actions workflow for automated testing of pull requests.
    • Enhanced test context setup with new structures and functions for better test management.
  • Tests
    • Updated tests to focus on successful operations for API endpoints, removing unauthorized access checks.
    • Implemented a client-based interaction model for testing API functionality.
  • Chores
    • Simplified CI/CD workflows by removing redundant testing jobs and environment variables.

@dotandev dotandev requested a review from a team as a code owner March 11, 2025 11:26
Copy link
coderabbitai bot commented Mar 11, 2025

Walkthrough

This pull request introduces several changes, including the addition of a new GitHub Actions workflow for pull request testing, which integrates Rust and PostgreSQL testing alongside UI and API builds. It modifies the existing test suites for controllers to focus on successful operations rather than unauthorized access checks. Additionally, it transitions a dependency in the API package to a workspace configuration and introduces new utility modules for hashing and time manipulation.

Changes

File(s) Change Summary
.github/workflows/dev-workflow.yml Modified job create-release-pr token line (no functional change).
packages/api/Cargo.toml Changed rest-api dependency from versioned to workspace configuration.
packages/api/src/controllers/v1/agit/{mod.rs, tests.rs} Added conditional compilation for a test module; updated tests to use a client-based interaction model, introducing a new test function test_update_agit.
packages/api/src/controllers/v1/collection/{mod.rs, tests.rs} Added a test module declaration; removed unauthorized access tests and replaced them with tests for successful operations: create, query, update, and delete collections.
packages/api/src/main.rs Updated TestContext struct: changed app type and added new field agit_id. Introduced new structs and functions for test setup.
packages/api/src/utils/{hash.rs, mod.rs, time.rs} Introduced a new function get_hash_string for hashing; added a new module time with functions for date/time manipulation. Exposed these modules through mod.rs.
.github/workflows/pr-workflow.yml Added a new workflow for pull request testing with jobs for test, main-ui, and api, integrating Rust and PostgreSQL testing along with UI and API builds.

Sequence Diagram(s)

sequenceDiagram
    participant Runner as GitHub Runner
    participant Repo as Repository
    participant Rust as Rust Setup
    participant DB as PostgreSQL Service
    
    Runner->>Repo: Checkout repository (with submodules)
    Runner->>Rust: Set up Rust toolchain (Clippy, Rustfmt, dependencies)
    Runner->>DB: Initialize PostgreSQL service & run health check
    Runner->>Runner: Run lint, formatting, and tests (make test)
Loading
sequenceDiagram
    actor Client as API Client
    participant Server as Collection Controller
    
    Client->>Server: Send GET request to "/"
    Server->>Client: Return collection data (POST route removed)
Loading

Suggested reviewers

  • hackartists

Poem

Oh, I’m a rabbit, quick on my feet,
Hop-ping through changes, oh so neat!
CI jobs and tests make the code jump high,
With new utilities lighting up the sky.
Scurry on, dear coders, no bug can hide—
In our lively code-field, we take it in stride!
🐇✨


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🔭 Outside diff range comments (1)
.github/workflows/dev-workflow.yml (1)

278-281: 🛠️ Refactor suggestion

Update dependencies for create-release-pr job.

The create-release-pr job currently doesn't depend on the new test jobs, which means it could run even if tests fail.

Update the dependencies to include the new test jobs:

  create-release-pr:
    runs-on: ubuntu-latest
-    needs: [main-ui, build-ui, api]
+    needs: [test-main-ui, test-build-ui, test-api, main-ui, build-ui, api]
🧹 Nitpick comments (13)
packages/api/src/utils/hash.rs (2)

1-9: Good implementation, but missing documentation

The SHA-3 hash implementation looks correct, using the sha3 crate appropriately to create a hex string representation of a hash. However, the function lacks documentation comments to explain its purpose and usage.

Consider adding documentation and slightly simplifying the return:

 use sha3::Digest;
 
+/// Computes the SHA-3 256-bit hash of the provided byte slice and returns it as a hexadecimal string.
+/// 
+/// # Arguments
+/// * `bytes` - The byte slice to hash
+/// 
+/// # Returns
+/// A lowercase hexadecimal string representation of the hash
 pub fn get_hash_string(bytes: &[u8]) -> String {
     let mut hasher = sha3::Sha3_256::new();
     hasher.update(bytes);
     let result = hasher.finalize();
-    let hash = format!("{:x}", result);
-    hash
+    format!("{:x}", result)
 }

1-9: Missing unit tests

This utility function doesn't have associated tests to verify its correctness. Consider adding tests to ensure the function produces expected hash values for known inputs.

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_get_hash_string() {
        // Test empty input
        assert_eq!(
            get_hash_string(&[]),
            "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"
        );
        
        // Test with a simple string
        assert_eq!(
            get_hash_string(b"hello world"),
            "644bcc7e564373040999aac89e7622f3ca71fba1d972fd94a31c3bfbf24e3938"
        );
    }
}
packages/api/Cargo.toml (1)

30-33: Consider workspace-level dependency management

Since other core dependencies are managed at the workspace level (using workspace = true), consider doing the same for these new dependencies if they might be used in multiple packages.

-uuid = "1.15.1"
-rest-api = "0.1.8"
-chrono = "0.4.40"
-sha3 = "0.10.8"
+uuid.workspace = true
+rest-api.workspace = true
+chrono.workspace = true
+sha3.workspace = true

And then add these dependencies with their versions in the workspace's root Cargo.toml.

packages/api/src/utils/time.rs (1)

10-26: Consider making the timezone offset and date format configurable.

The function hardcodes both the UTC+9 timezone (KST) and the "%y-%m-%d" output format, which could limit reusability across different regions or use cases.

Consider modifying the function to accept the timezone offset and date format as parameters:

-pub fn convert_utc_timestamp_to_datetime(
-    timestamp: i64,
-    adjusted_day: Option<u8>,
-) -> Option<String> {
-    let kst_offset = FixedOffset::east_opt(9 * 3600).unwrap(); // UTC+9
+pub fn convert_utc_timestamp_to_datetime(
+    timestamp: i64,
+    adjusted_day: Option<u8>,
+    hours_offset: Option<i32>,
+    format: Option<&str>,
+) -> Option<String> {
+    let hours_offset = hours_offset.unwrap_or(9); // Default to UTC+9 (KST)
+    let format = format.unwrap_or("%y-%m-%d");
+    let timezone_offset = FixedOffset::east_opt(hours_offset * 3600).unwrap();

And update the return statement:

-    Some(datetime.format("%y-%m-%d").to_string())
+    Some(datetime.format(format).to_string())
packages/api/src/controllers/v1/agit/tests.rs (1)

11-30: Unused TestContext variables and test setup inconsistency.

The test creates a TestContext but doesn't use any of its fields. Also, the test suite only checks unauthorized access without testing the authorized case.

Remove unused variables or utilize them in the test:

-    let TestContext {
-        ..
-    } = setup().await.unwrap();
+    // Only setup the test database if that's all we need
+    let pool = setup_test_db().await;

Additionally, consider adding tests for the authorized case to ensure complete test coverage.

packages/api/src/controllers/v1/collection/tests.rs (2)

1-2: Fix indentation in test file.

The entire file appears to have excessive indentation with code starting at column 4 rather than column 0, which is inconsistent with Rust's standard formatting.

Remove the additional indentation throughout the file to align with Rust's standard formatting convention.


10-32: Remove unused TestContext variables.

The TestContext is created but only now and endpoint are extracted, which aren't used in the test.

Simplify the test setup by removing unused variables:

-    let TestContext {
-        now,
-        endpoint,
-        ..
-    } = setup().await.unwrap();
+    let pool = setup_test_db().await;
.github/workflows/dev-workflow.yml (3)

12-38: Good addition of the test-main-ui job.

This job effectively sets up the testing environment for the main UI component, which is a great addition to the CI/CD pipeline. The job includes all necessary steps from checkout to running tests.

Consider updating the checkout action to the latest version for better compatibility:

-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
🧰 Tools
🪛 actionlint (1.7.4)

15-15: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


39-65: Potential duplication in test-build-ui job.

The test-build-ui job is nearly identical to test-main-ui, which suggests a possible opportunity for workflow optimization.

Consider using a reusable workflow or job template to avoid duplicating the same steps. Also, update the checkout action version:

-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
🧰 Tools
🪛 actionlint (1.7.4)

42-42: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


66-110: Well-structured test-api job with PostgreSQL service.

The job correctly sets up a PostgreSQL service for API testing, including health checks and proper database initialization.

Two minor issues to address:

  1. Update the checkout action version:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
  1. Remove the trailing whitespace at the end of line 111:
-        run: make test
-        
+        run: make test
🧰 Tools
🪛 actionlint (1.7.4)

84-84: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

packages/api/src/main.rs (3)

68-87: Well-structured TestContext struct for testing.

The TestContext struct encapsulates all necessary components for testing, which is a good approach.

There's a commented out field on line 81. Either uncomment it if it's needed or remove it completely:

-        // pub user: User,

95-106: Duplicated database connection logic.

The setup_test_db function duplicates logic from both the main function and the setup function.

Consider extracting the database connection logic into a shared function to reduce duplication:

pub async fn connect_database(config: &DatabaseConfig) -> sqlx::Pool<sqlx::Postgres> {
    if let DatabaseConfig::Postgres { url, pool_size } = config {
        PgPoolOptions::new()
            .max_connections(*pool_size)
            .connect(url)
            .await
            .expect("Failed to connect to Postgres")
    } else {
        panic!("Database is not initialized. Call init() first.");
    }
}

Then call this function from both main() and the test setup functions.


124-146: SQL function creation in test setup.

The setup function correctly creates or replaces SQL functions for timestamp handling.

Consider moving the SQL query strings to constants or a separate file to improve readability:

const SET_UPDATED_AT_FUNC: &str = "CREATE OR REPLACE FUNCTION set_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at := EXTRACT(EPOCH FROM now()); RETURN NEW; END; $$ LANGUAGE plpgsql;";
const SET_CREATED_AT_FUNC: &str = "CREATE OR REPLACE FUNCTION set_created_at() RETURNS TRIGGER AS $$ BEGIN NEW.created_at := EXTRACT(EPOCH FROM now()); RETURN NEW; END; $$ LANGUAGE plpgsql;";
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a2531e9 and 0c5fc99.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • .github/workflows/dev-workflow.yml (1 hunks)
  • packages/api/Cargo.toml (2 hunks)
  • packages/api/src/controllers/v1/agit/mod.rs (1 hunks)
  • packages/api/src/controllers/v1/agit/tests.rs (1 hunks)
  • packages/api/src/controllers/v1/collection/mod.rs (2 hunks)
  • packages/api/src/controllers/v1/collection/tests.rs (1 hunks)
  • packages/api/src/main.rs (2 hunks)
  • packages/api/src/utils/hash.rs (1 hunks)
  • packages/api/src/utils/mod.rs (1 hunks)
  • packages/api/src/utils/time.rs (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.4)
.github/workflows/dev-workflow.yml

15-15: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


42-42: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


84-84: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 YAMLlint (1.35.1)
.github/workflows/dev-workflow.yml

[error] 111-111: trailing spaces

(trailing-spaces)

🔇 Additional comments (16)
packages/api/src/utils/mod.rs (1)

1-2: LGTM - New utility modules added

The change adds two public utility modules: hash for cryptographic hashing operations and time for datetime manipulation. This addition follows good modular design principles by organizing related functionality into separate modules.

packages/api/src/controllers/v1/agit/mod.rs (1)

20-20: LGTM - Test module added

Adding a test module for the Agit controller is a good practice for ensuring code quality and preventing regressions. This change follows Rust's convention for including module tests.

packages/api/Cargo.toml (1)

30-33:

❓ Verification inconclusive

Verify dependency versions and consider specifying feature flags

The added dependencies are appropriate for the functionality being implemented. However, it's important to consider specifying only the features you need to minimize bloat.


🏁 Script executed:

#!/bin/bash
# Check if the dependencies are up-to-date and what features are available
cargo outdated -p uuid -p chrono -p sha3 -p rest-api
echo "======= Features available for chrono ======="
cargo metadata --format-version=1 | jq '.packages[] | select(.name == "chrono") | .features'
echo "======= Features available for uuid ======="
cargo metadata --format-version=1 | jq '.packages[] | select(.name == "uuid") | .features'

Length of output: 728


Action: Verify and Specify Minimal Feature Flags for Dependencies

The dependency versions in packages/api/Cargo.toml (uuid = "1.15.1", rest-api = "0.1.8", chrono = "0.4.40", sha3 = "0.10.8") appear appropriate for the functionality implemented. However, to help minimize bloat, please verify locally (with Cargo available) which features are enabled by default for dependencies like chrono and uuid, and consider explicitly specifying only the needed features. For example, if certain default features are not required, you might disable them using the [default-features = false] option and only include the features you need.

  • Note: The verification script did not return dependency details due to the absence of the cargo command in the current environment. Please run these commands in your local development setup to obtain accurate feature lists.
8000
packages/api/src/controllers/v1/collection/mod.rs (2)

21-21: Good addition of test module.

Adding a dedicated test module is a good practice for organizing test code separately from the main implementation. This follows Rust's convention for test organization and improves code maintainability.


129-129:

❓ Verification inconclusive

API surface change: POST endpoint removed from root path.

The route has been modified to only allow GET requests on the root path, removing the POST capability. This makes the API more RESTful by ensuring endpoints follow a consistent pattern (POST operations are still available via /create/:agit_id).

This change could potentially break existing clients that were using the removed POST endpoint at the root path. Please verify this is an intentional change and that all clients have been updated accordingly.


🏁 Script executed:

#!/bin/bash
# Check if there are any client code references to POST requests to the root collection endpoint
rg -i "post.*collection/\""

Length of output: 28


Attention: Manual Verification on POST Endpoint Removal

The POST endpoint at the root path has been removed in favor of a GET-only endpoint (with POST operations now available via /create/:agit_id). Although our initial search for client references to POST requests on the root endpoint returned no results, the absence of output is ambiguous. Please manually verify that no client is still attempting to use the removed POST endpoint. This check is crucial to ensure that the change is intentional and that all client integrations have been updated accordingly.

  • Location: packages/api/src/controllers/v1/collection/mod.rs (Line 129)
  • Key Change: Removed the POST route on / and retained only GET (.route("/", get(Self::get_collection))).
packages/api/src/utils/time.rs (1)

1-8: LGTM: Well-implemented RFC3339 timestamp conversion.

The function correctly handles the conversion from RFC3339 formatted strings to UTC timestamps in milliseconds, properly handling errors through Option returns.

packages/api/src/controllers/v1/agit/tests.rs (3)

1-2: Good test configuration.

The #![cfg(test)] attribute properly marks this file for compilation only during testing, which is a good practice.


32-45: LGTM: Well-structured test for unauthorized query.

This test correctly verifies that unauthorized access to the query method results in the expected Unauthorized error.


47-56: LGTM: Proper test for unauthorized delete operation.

This test correctly verifies that unauthorized access to the delete method results in the expected Unauthorized error.

packages/api/src/controllers/v1/collection/tests.rs (3)

34-47: LGTM: Proper test for unauthorized query.

This test correctly verifies that unauthorized access to the query method results in the expected Unauthorized error.


49-61: LGTM: Well-structured test for unauthorized update.

This test correctly verifies that unauthorized access to the update method results in the expected Unauthorized error.


63-72: LGTM: Proper test for unauthorized delete operation.

This test correctly verifies that unauthorized access to the delete method results in the expected Unauthorized error.

packages/api/src/main.rs (4)

11-13: Appropriate module organization.

The addition of Result import and utils module helps with code organization.


89-93: User struct for test authentication.

This struct provides a clear structure for user data in tests.


109-122: Well-implemented JWT token setup for tests.

The function correctly handles JWT token generation for test authentication.


162-175: Well-implemented request hook for authentication.

The Hook implementation correctly adds authentication headers to requests.

Comment on lines 4 to 57
use crate::controllers::v1::agit::AgitControllerV1;
use crate::dagit_tests::{TestContext, setup, setup_test_db};
use models::{
error as ApiError,
v1::agit::{AgitCreateRequest, AgitQuery},
};

#[tokio::test]
async fn test_create_agit() {
let TestContext {
..
} = setup().await.unwrap();
let pool = setup_test_db().await;
let controller = AgitControllerV1::new(pool);

let result = controller
.create(
None,
AgitCreateRequest {
title: "New Agit Title".to_string(),
},
)
.await;

assert!(result.is_err());
assert_eq!(result.err().unwrap(), ApiError::ServiceError::Unauthorized);
}

#[tokio::test]
async fn test_query_agit() {
let pool = setup_test_db().await;
let controller = AgitControllerV1::new(pool);

let param = AgitQuery {
bookmark: None,
size: 10,
};
let result = controller.query(None, param).await;

assert!(result.is_err());
assert_eq!(result.err().unwrap(), ApiError::ServiceError::Unauthorized);
}

#[tokio::test]
async fn test_delete_agit() {
let pool = setup_test_db().await;
let controller = AgitControllerV1::new(pool);

let result = controller.delete(1, None).await;

assert!(result.is_err());
assert_eq!(result.err().unwrap(), ApiError::ServiceError::Unauthorized);
}

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding positive test cases.

The test suite only verifies unauthorized access scenarios. While these are important, testing the successful path is also crucial.

Add tests for the authorized case to ensure the controller methods work correctly when proper authorization is provided. This would provide better test coverage and confidence in the code's functionality.

For example:

#[tokio::test]
async fn test_create_agit_authorized() {
    let pool = setup_test_db().await;
    let controller = AgitControllerV1::new(pool);
    
    // Mock authorization
    let auth = Some(Authorization::new("test_user", vec!["user"]));
    
    let result = controller
        .create(
            auth,
            AgitCreateRequest {
                title: "New Agit Title".to_string(),
            },
        )
        .await;
    
    assert!(result.is_ok());
    let agit = result.unwrap();
    assert_eq!(agit.title, "New Agit Title");
}

Comment on lines 3 to 72
use super::*;
use crate::dagit_tests::{TestContext, setup_test_db, setup};
use models::{
Result, error as ApiError,
v1::collection::{CollectionCreateRequest, CollectionQuery, CollectionUpdateRequest},
};

#[tokio::test]
async fn test_create_collection_unauthorized() {
let TestContext {
now,
endpoint,
..
} = setup().await.unwrap();
let pool = setup_test_db().await;
let controller = CollectionControllerV1::new(pool);

let result = controller
.create(
None,
1,
CollectionCreateRequest {
title: "New Collection Title".to_string(),
},
)
.await;

assert!(result.is_err());
assert_eq!(result.err().unwrap(), ApiError::ServiceError::Unauthorized);
}

#[tokio::test]
async fn test_query_collection() {
let pool = setup_test_db().await;
let controller = CollectionControllerV1::new(pool);

let param = CollectionQuery {
bookmark: None,
size: 10,
};
let result = controller.query(None, param).await;

assert!(result.is_err());
assert_eq!(result.err().unwrap(), ApiError::ServiceError::Unauthorized);
}

#[tokio::test]
async fn test_update_collection() {
let pool = setup_test_db().await;
let controller = CollectionControllerV1::new(pool);

let param = CollectionUpdateRequest {
title: "Updated Collection Title".to_string(),
};
let result = controller.update(None, 1, param).await;

assert!(result.is_err());
assert_eq!(result.err().unwrap(), ApiError::ServiceError::Unauthorized);
}

#[tokio::test]
async fn test_delete_collection() {
let pool = setup_test_db().await;
let controller = CollectionControllerV1::new(pool);

let result = controller.delete(1, None).await;

assert!(result.is_err());
assert_eq!(result.err().unwrap(), ApiError::ServiceError::Unauthorized);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add positive test cases with authorization.

Similar to the agit tests, this test suite only covers unauthorized access scenarios. Testing the authorized cases would provide better coverage.

Add tests with proper authorization to ensure the controller methods function correctly when a user is authorized. This would provide better confidence in the code's functionality.

For example:

#[tokio::test]
async fn test_create_collection_authorized() {
    let pool = setup_test_db().await;
    let controller = CollectionControllerV1::new(pool);
    
    // Mock authorization
    let auth = Some(Authorization::new("test_user", vec!["user"]));
    
    let result = controller
        .create(
            auth, 
            1, 
            CollectionCreateRequest {
                title: "New Collection Title".to_string(),
            },
        )
        .await;
    
    assert!(result.is_ok());
    let collection = result.unwrap().0;
    assert_eq!(collection.title, "New Collection Title");
}

Comment on lines +150 to +156
let id = uuid::Uuid::max();
let user = User {
id: 1,
email: "j@ff.com".to_string(),
password: "password".to_string(),
};

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Potential security issue with hardcoded credentials.

The test setup uses hardcoded user credentials.

Even for tests, it's better to use randomly generated or environment-provided credentials:

-        let id = uuid::Uuid::max();
+        let id = uuid::Uuid::new_v4();
         let user = User {
             id: 1,
-            email: "j@ff.com".to_string(),
-            password: "password".to_string(),
+            email: format!("test-{}@example.com", id),
+            password: format!("password-{}", uuid::Uuid::new_v4()),
         };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let id = uuid::Uuid::max();
let user = User {
id: 1,
email: "j@ff.com".to_string(),
password: "password".to_string(),
};
let id = uuid::Uuid::new_v4();
let user = User {
id: 1,
email: format!("test-{}@example.com", id),
password: format!("password-{}", uuid::Uuid::new_v4()),
};

Comment on lines 176 to 192
rest_api::add_header("Authorization".to_string(), format!("Bearer {}", user_token.clone()));

let now = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_nanos() as u64;

Ok(TestContext {
pool,
app,
id: id.to_string(),
user_token,
claims,
now: now as i64,
endpoint: "http://localhost:3000".to_string(),
})
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Inconsistent time unit conversion.

There's an inconsistency in time unit conversion when setting the 'now' field.

The function converts system time to nanoseconds but then casts it to i64 for the 'now' field. This could lead to precision issues or overflows:

         let now = SystemTime::now()
             .duration_since(SystemTime::UNIX_EPOCH)
             .unwrap()
-            .as_nanos() as u64;
+            .as_secs();

         Ok(TestContext {
             pool,
             app,
             id: id.to_string(),
             user_token,
             claims,
-            now: now as i64,
+            now: now as i64,
             endpoint: "http://localhost:3000".to_string(),
         })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
rest_api::add_header("Authorization".to_string(), format!("Bearer {}", user_token.clone()));
let now = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_nanos() as u64;
Ok(TestContext {
pool,
app,
id: id.to_string(),
user_token,
claims,
now: now as i64,
endpoint: "http://localhost:3000".to_string(),
})
}
rest_api::add_header("Authorization".to_string(), format!("Bearer {}", user_token.clone()));
let now = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs();
Ok(TestContext {
pool,
app,
id: id.to_string(),
user_token,
claims,
now: now as i64,
endpoint: "http://localhost:3000".to_string(),
})
}

Copy link
Contributor
@RyanCho-0 RyanCho-0 left a comment

Choose a reason for hiding this comment

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

The authentication is already being mocked.
In api/src/main.rs at line 176, the following code is responsible for adding the user's authentication details:
rest_api::add_header("Authorization".to_string(), format!("Bearer {}", user_token.clone()));`

Copy link
Contributor

Choose a reason for hiding this comment

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

Please write it in the "pr-testing.yml" file.
Tests should be executed for every PR.
https://github.com/biyard/voice-korea/blob/main/.github/workflows/pr-workflow.yml

};

#[tokio::test]
async fn test_create_agit() {
Copy link
Contributor

Choose a reason for hiding this comment

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

The test should call the Server(API) as if it were being called from the Client.
Please review the code and update the test accordingly.
Reference

Comment on lines 28 to 29
assert!(result.is_err());
assert_eq!(result.err().unwrap(), ApiError::ServiceError::Unauthorized);
Copy link
Contributor

Choose a reason for hiding this comment

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

Are you checking whether Result is an error because authentication is missing?

If the error is the intended behavior, the function name should be adjusted accordingly.
If the error is caused by another issue, the test should be written to fail in such cases.

models = { workspace = true, features = ["server"] }
schemars = "0.8.22"
uuid = "1.15.1"
rest-api = "0.1.8"
Copy link
Contributor

Choose a reason for hiding this comment

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

use rest-api of rust-sdk submodule instead of crate registry.
Because now, we didn't publish latest version of it.

Refer to Cargo.toml in project root.
you can use as below in Cargo.toml of project root.

rest-api = { path = "deps/rust-sdk/packages/rest-api" }

Then here

Suggested change
rest-api = "0.1.8"
rest-api.workspace = true

@@ -17,6 +17,7 @@ use models::{
},
};
use sqlx::postgres::PgRow;
mod tests;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
mod tests;
#[cfg(test)]
mod tests;

@@ -0,0 +1,58 @@
#![cfg(test)]
Copy link
Contributor

Choose a reason for hiding this comment

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

you can remove this.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 4

♻️ Duplicate comments (1)
packages/api/src/controllers/v1/agit/tests.rs (1)

11-30: 🛠️ Refactor suggestion

Enhance test coverage with positive test cases.

The test is currently only verifying unauthorized access scenarios. While these are important, testing the successful path is also crucial.

Update the test to include both unauthorized and authorized scenarios:

 #[tokio::test]
 async fn test_create_agit() {
     let TestContext {
         ..
     } = setup().await.unwrap();
     let pool = setup_test_db().await;
     let controller = AgitControllerV1::new(pool);
 
+    // Test unauthorized access
     let result = controller
         .create(
             None,
             AgitCreateRequest {
                 title: "New Agit Title".to_string(),
             },
         )
         .await;
 
     assert!(result.is_err());
     assert_eq!(result.err().unwrap(), ApiError::ServiceError::Unauthorized);
+
+    // Test successful creation
+    let auth = Some(by_axum::auth::Authorization::new("test_user", vec!["user"]));
+    let result = controller
+        .create(
+            auth,
+            AgitCreateRequest {
+                title: "New Agit Title".to_string(),
+            },
+        )
+        .await;
+
+    assert!(result.is_ok());
+    let agit = result.unwrap();
+    assert_eq!(agit.title, "New Agit Title");
 }
🧹 Nitpick comments (2)
packages/api/src/main.rs (1)

174-174: Consider making agit_id more dynamic.

The hardcoded value of 1 for agit_id might cause conflicts if multiple tests run concurrently. Consider using a dynamic value or ensuring it's isolated between test runs.

-            agit_id: 1,
+            agit_id: rand::thread_rng().gen_range(1000..10000), // Add rand crate to dependencies
.github/workflows/dev-workflow.yml (1)

39-64: Duplicate test configuration between test-main-ui and test-build-ui.

The test-main-ui and test-build-ui jobs have identical configurations. Consider consolidating them or clearly differentiating their purposes to avoid redundancy.

You could use job templating or a reusable workflow to reduce duplication:

  test-template: &test-template
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive
          ssh-key: ${{ secrets.PULL_KEY_REPO }}
      # ... other common steps ...
      
  test-main-ui:
    <<: *test-template
    # Only add steps unique to main-ui
    
  test-build-ui:
    <<: *test-template
    # Only add steps unique to build-ui
🛑 Comments failed to post (4)
.github/workflows/ pr-workflow.yml (1)

1-118: 🛠️ Refactor suggestion

Good addition of PR workflow, but needs a few improvements.

The PR workflow is a good addition to test changes before merging. However, there are a few issues to address:

  1. The actions/checkout action is using an outdated version (v3)
  2. The file is missing a newline at the end
  3. Consider adding a job dependency flow to optimize the workflow

Here are the suggested fixes:

- uses: actions/checkout@v3
+ uses: actions/checkout@v4

Apply this change at lines 30, 60, and 96.

Also, add a newline at the end of the file at line 118.

Consider adding job dependencies:

  api:
    runs-on: ubuntu-22.04
    needs: [test]
    steps:
      # existing steps

This would ensure the test job passes before running the build jobs.

🧰 Tools
🪛 actionlint (1.7.4)

30-30: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


60-60: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


96-96: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 YAMLlint (1.35.1)

[error] 118-118: no new line character at the end of file

(new-line-at-end-of-file)

packages/api/src/controllers/v1/agit/tests.rs (3)

47-56: 🛠️ Refactor suggestion

Add successful delete test case.

The test only verifies unauthorized access. Add a test for successful deletion with proper authorization.

 #[tokio::test]
 async fn test_delete_agit() {
     let pool = setup_test_db().await;
     let controller = AgitControllerV1::new(pool);
 
+    // Test unauthorized access
     let result = controller.delete(1, None).await;
 
     assert!(result.is_err());
     assert_eq!(result.err().unwrap(), ApiError::ServiceError::Unauthorized);
+
+    // Test successful deletion
+    // First create an agit to delete
+    let auth = Some(by_axum::auth::Authorization::new("test_user", vec!["user"]));
+    let create_result = controller
+        .create(
+            auth.clone(),
+            AgitCreateRequest {
+                title: "Delete Test Agit".to_string(),
+            },
+        )
+        .await;
+    
+    assert!(create_result.is_ok());
+    let agit = create_result.unwrap();
+    
+    // Now delete it
+    let delete_result = controller.delete(agit.id, auth).await;
+    
+    assert!(delete_result.is_ok());
+    let deleted_agit = delete_result.unwrap();
+    assert_eq!(deleted_agit.id, agit.id);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

#[tokio::test]
async fn test_update_agit() {
    let result = client.update(1, "Updated Agit Title".to_string()).await;
    assert!(result.is_ok(), "Failed to update agit: {:?}", result.err());
}

#[tokio::test]
async fn test_delete_agit() {
    let pool = setup_test_db().await;
    let controller = AgitControllerV1::new(pool);

    // Test unauthorized access
    let result = controller.delete(1, None).await;
    assert!(result.is_err());
    assert_eq!(result.err().unwrap(), ApiError::ServiceError::Unauthorized);

    // Test successful deletion
    // First create an agit to delete
    let auth = Some(by_axum::auth::Authorization::new("test_user", vec!["user"]));
    let create_result = controller
        .create(
            auth.clone(),
            AgitCreateRequest {
                title: "Delete Test Agit".to_string(),
            },
        )
        .await;
    
    assert!(create_result.is_ok());
    let agit = create_result.unwrap();
    
    // Now delete it
    let delete_result = controller.delete(agit.id, auth).await;
    assert!(delete_result.is_ok());
    let deleted_agit = delete_result.unwrap();
    assert_eq!(deleted_agit.id, agit.id);
}

32-45: 🛠️ Refactor suggestion

Add successful query test case.

Similar to the create test, this only tests the unauthorized scenario. Add a test for successful query with proper authorization.

 #[tokio::test]
 async fn test_query_agit() {
     let pool = setup_test_db().await;
     let controller = AgitControllerV1::new(pool);
 
     let param = AgitQuery {
         bookmark: None,
         size: 10,
     };
+    // Test unauthorized access
     let result = controller.query(None, param).await;
 
     assert!(result.is_err());
     assert_eq!(result.err().unwrap(), ApiError::ServiceError::Unauthorized);
+
+    // Test successful query
+    let auth = Some(by_axum::auth::Authorization::new("test_user", vec!["user"]));
+    // Create a test agit first
+    let _ = controller
+        .create(
+            auth.clone(),
+            AgitCreateRequest {
+                title: "Query Test Agit".to_string(),
+            },
+        )
+        .await;
+
+    let param = AgitQuery {
+        bookmark: None,
+        size: 10,
+    };
+    let result = controller.query(auth, param).await;
+
+    assert!(result.is_ok());
+    let response = result.unwrap();
+    assert!(response.items.len() > 0);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    let TestContext { endpoint, .. } = setup().await.unwrap();

    let client = Agit::get_client(&endpoint);

    let result = client.delete(1).await;

    assert!(result.is_ok(), "Failed to delete agit: {:?}", result.err());
}

#[tokio::test]
async fn test_update_agit() {
    let TestContext { endpoint, .. } = setup().await.unwrap();

    let client = Agit::get_client(&endpoint);
    // ... existing test_update_agit logic ...
}

#[tokio::test]
async fn test_query_agit() {
    let pool = setup_test_db().await;
    let controller = AgitControllerV1::new(pool);

    let param = AgitQuery {
        bookmark: None,
        size: 10,
    };
    // Test unauthorized access
    let result = controller.query(None, param).await;

    assert!(result.is_err());
    assert_eq!(result.err().unwrap(), ApiError::ServiceError::Unauthorized);

    // Test successful query
    let auth = Some(by_axum::auth::Authorization::new("test_user", vec!["user"]));
    // Create a test agit first
    let _ = controller
        .create(
            auth.clone(),
            AgitCreateRequest {
                title: "Query Test Agit".to_string(),
            },
        )
        .await;

    let param = AgitQuery {
        bookmark: None,
        size: 10,
    };
    let result = controller.query(auth, param).await;

    assert!(result.is_ok());
    let response = result.unwrap();
    assert!(response.items.len() > 0);
}

1-58: 💡 Verification agent

🧩 Analysis chain

Consider testing through API endpoints instead of direct controller methods.

As noted in a previous review comment, tests should ideally call the server API as if being called from a client, rather than directly calling controller methods. This tests the entire request-response flow including routing and middleware.

Consider updating the test approach by examining this reference:


🌐 Web query:

What is the difference between testing controller methods directly versus testing through HTTP endpoints in Rust axum?

💡 Result:

Testing controller methods directly versus testing through HTTP endpoints in Rust Axum involves trade-offs between isolation, speed, and testing scope. Here's a breakdown of key differences:

Direct Controller Testing

Scope: Unit tests targeting individual handler functions
Approach:

  • Invoke handlers directly with mock parameters/extractors
  • Use dependency injection for external services (DB, auth) via traits/mock objects
  • Validate business logic without HTTP serialization

Example Setup ([Source 7][14]):

// Mock database trait
#[automock]
trait UserRepo {
    fn find_user(&self, id: i32) -> Result<User, Error>;
}

// Test with mock
let mut mock_repo = MockUserRepo::new();
mock_repo.expect_find_user()
    .returning(|_| Ok(User::default()));

let response = get_user_handler(Path(123), Extension(mock_repo)).await;

Advantages:

  • Fast execution (no network/HTTP overhead)
  • Precise error type validation
  • Easier to simulate edge cases
  • No routing/middleware interference

HTTP Endpoint Testing

Scope: Integration tests covering full request lifecycle
Approach:

  • Use TestServer from axum-test crate ([Source 1][1])
  • Send real HTTP requests to router instance
  • Test serialization/deserialization
  • Verify headers/cookies/status codes

Example Setup ([Source 5][5]):

let app = router().with_state(store);
let server = TestServer::new(app)?;

let response = server.get("/todos")
    .header("Authorization", "Bearer token")
    .await
    .assert_status_ok();

Advantages:

  • Tests routing configuration
  • Validates middleware stack (CORS, auth)
  • Ensures JSON schema correctness
  • Verifies proper HTTP status code mapping

Key Comparison

Aspect Direct Testing HTTP Testing
Speed Faster (µs) Slower (ms)
Dependencies Mocked via traits Real/Test doubles
Test Scope Isolated units Full system integration
Setup Complexity Medium Higher
Error Visibility Raw error types HTTP status codes

When to Use Each

  1. Direct Controller Tests:

    • Core business logic validation
    • Error handling workflows
    • Data transformation checks
  2. HTTP Endpoint Tests:

    • API contract verification
    • Authentication/authorization flows
    • Content negotiation testing
    • End-to-end happy path validation

Best practice is to combine both approaches - use direct tests for complex business logic ([Source 12][12]) and HTTP tests for API surface validation ([Source 8][8]). The axum-test crate provides utilities for both testing styles while maintaining type safety through Axum's state management system.

Citations:


Action Needed: Extend Testing to Cover the Full HTTP Request Lifecycle

While the current tests effectively validate the core business logic by directly invoking controller methods, they bypass critical aspects of the full API request-response cycle—such as routing, middleware, and proper serialization/deserialization. It’s advisable to supplement these unit tests with integration tests that simulate real HTTP client requests (using tools like the axum-test crate). This combined strategy will help ensure that all layers of your API—from request parsing to response generation—are functioning correctly.

  • Consider adding integration tests that send real HTTP requests to your Axum router to verify routing and middleware behavior.
  • Retain the current direct tests for rapid unit validation, but expand coverage by testing the entire HTTP interface.

@dotandev
Copy link
Contributor Author
dotandev commented Mar 11, 2025

the unused properties caused the fail for the API workflow.

it runs smoothly locally.

Copy link
Contributor

Choose a reason for hiding this comment

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

Is it necessary to modify this file in this PR?

Also, the build-ui deployment code has been removed.
Please check it again.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright, I will check that out.

@dotandev dotandev requested a review from RyanCho-0 March 12, 2025 13:48
Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
packages/api/src/main.rs (2)

147-153: ⚠️ Potential issue

Security issue: Replace hardcoded credentials with random values.

Even in tests, it's best to avoid hardcoded user credentials. Use randomly generated values instead.

-        let id = uuid::Uuid::max();
+        let id = uuid::Uuid::new_v4();
         let user = User {
             id: 1,
-            email: "j@ff.com".to_string(),
-            password: "password".to_string(),
+            email: format!("test-{}@example.com", id),
+            password: format!("password-{}", uuid::Uuid::new_v4()),
         };

160-164: 🛠️ Refactor suggestion

Fix inconsistent time unit conversion.

The time is converted to nanoseconds (as_nanos) and then cast to u64, but later cast to i64 which could lead to potential overflow and precision issues. Using seconds (as_secs) would be more appropriate and consistent.

         let now = SystemTime::now()
             .duration_since(SystemTime::UNIX_EPOCH)
             .unwrap()
-            .as_nanos() as u64;
+            .as_secs();

And then update line 171:

-            now: now as i64,
+            now: now as i64,
🧹 Nitpick comments (5)
packages/api/src/main.rs (5)

75-85: Commented code should be removed.

Line 79 contains a commented out field // pub user: User,. If this field is not needed, remove the comment. If it will be needed in the future, add a TODO comment explaining why it's commented out and when it will be used.

        pub pool: sqlx::Pool<sqlx::Postgres>,
        pub app: Box<dyn ApiService>,
        pub agit_id: i64,
-        // pub user: User,
        pub user_token: String,

93-104: Reduce code duplication in database setup.

The database connection code in setup_test_db() is duplicated in the setup() function. Consider refactoring to call setup_test_db() from within setup() to avoid duplication.

    pub async fn setup() -> models::Result<TestContext> {
        let conf = config::get();
-        let pool = if let DatabaseConfig::Postgres { url, pool_size } = conf.database {
-            PgPoolOptions::new()
-                .max_connections(pool_size)
-                .connect(url)
-                .await
-                .expect("Failed to connect to Postgres")
-        } else {
-            panic!("Database is not initialized. Call init() first.");
-        };
+        let pool = setup_test_db().await;

Also applies to: 121-132


134-142: Consider using migrations for database setup.

The SQL functions for handling timestamps are being created directly in the test setup. Consider moving these to proper database migrations that can be used both in tests and production code.

This would ensure consistent timestamp handling across environments and reduce the chance of differences between test and production behavior.


173-173: Avoid hardcoding IDs.

The agit_id is hardcoded to 1. This could cause test failures if the database already has records or if tests are run in parallel. Consider generating a unique ID for each test run.

-            agit_id: 1,
+            agit_id: rand::thread_rng().gen_range(1000..10000), // Requires rand crate

67-176: Add unit tests for the test setup functions.

The test setup code itself doesn't have tests. Consider adding unit tests for setup_test_db(), setup_jwt_token(), and setup() to ensure they work correctly.

For example, test that:

  1. setup_test_db() returns a valid connection pool
  2. setup_jwt_token() generates valid tokens with the expected claims
  3. setup() creates a complete and valid test context
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 876591a and a2f995b.

📒 Files selected for processing (3)
  • .github/workflows/dev-workflow.yml (1 hunks)
  • packages/api/src/main.rs (3 hunks)
  • packages/api/src/utils/hash.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/api/src/utils/hash.rs
🧰 Additional context used
🪛 YAMLlint (1.35.1)
.github/workflows/dev-workflow.yml

[error] 191-191: no new line character at the end of file

(new-line-at-end-of-file)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: api
🔇 Additional comments (3)
.github/workflows/dev-workflow.yml (1)

1-191: Determine if workflow file changes are necessary for this PR.

Based on previous comments, it seems there were questions about whether modifying this file is necessary for this PR, which was described as focused on "adding test cases and unit tests." Additionally, there was a concern about removed build-ui deployment code, though I can see the build-ui job is still present in the current file.

🧰 Tools
🪛 actionlint (1.7.4)

15-15: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


20-20: the runner of "aws-actions/configure-aws-credentials@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


74-74: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


79-79: the runner of "aws-actions/configure-aws-credentials@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


134-134: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


139-139: the runner of "aws-actions/configure-aws-credentials@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


182-182: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 YAMLlint (1.35.1)

[error] 191-191: no new line character at the end of file

(new-line-at-end-of-file)

packages/api/src/main.rs (2)

12-12:

❓ Verification inconclusive

Verify the purpose of the new utils module.

A new utils module has been added but its contents aren't shown. Ensure that this module is necessary for the tests being added and that it contains appropriate utility functions.


🏁 Script executed:

#!/bin/bash
# Check what's in the utils module
if [ -f "packages/api/src/utils.rs" ]; then
  echo "utils.rs exists as a separate file:"
  cat "packages/api/src/utils.rs" | head -n 20
elif [ -d "packages/api/src/utils" ]; then
  echo "utils exists as a directory module:"
  find "packages/api/src/utils" -name "*.rs" | xargs ls -la
else
  echo "utils module not found as a separate file or directory"
  echo "Looking for mod utils in main.rs:"
  grep -A 10 "mod utils" "packages/api/src/main.rs"
fi

Length of output: 449


Util Module Implementation Verification

The new utils module is implemented as a directory at packages/api/src/utils—it contains three files:

  • hash.rs
  • mod.rs
  • time.rs

Please verify that:

  • The utility functions provided in hash.rs and time.rs are actually leveraged by the new tests.
  • The module’s purpose is clearly documented (consider adding documentation or comments in mod.rs if necessary) to clarify its role in supporting the tests.

145-146:

❓ Verification inconclusive

Verify API adapter conversion.

The app is created with by_axum::new() and then converted with by_axum::into_api_adapter(app). Make sure this conversion maintains all necessary functionality for testing.


🏁 Script executed:

#!/bin/bash
# Check API adapter functionality
grep -r "into_api_adapter" --include="*.rs" .

Length of output: 122


Action Required: Confirm API Adapter Conversion Functionality

The conversion of the app via by_axum::into_api_adapter(app) in packages/api/src/main.rs (lines 145–146) should be reviewed carefully. Given that the app is initially created with by_axum::new(), please ensure that converting it with into_api_adapter maintains all the expected behavior necessary for testing. Verify that no essential functionality is lost during this conversion step, and that all tests relying on the API adapter continue to execute correctly.

@@ -188,4 +188,4 @@ jobs:
with:
base: main
head: dev
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Add newline at end of file.

YAML files should end with a newline character. Currently, this file is missing a newline at the end.


🏁 Script executed:

#!/bin/bash
# Check if file ends with a newline character
if [ "$(tail -c1 .github/workflows/dev-workflow.yml | wc -l)" -eq 0 ]; then
  echo "File does not end with a newline"
else
  echo "File already ends with a newline"
fi

Length of output: 148


Action Required: Append a Newline at the End of the File

The file .github/workflows/dev-workflow.yml currently does not end with a newline, which does not comply with YAML style guidelines. Please update the file to include a newline at the end.

  • Verify that the file ends with an empty newline character.
  • Commit the change to ensure consistent formatting.
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 191-191: no new line character at the end of file

(new-line-at-end-of-file)

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (5)
.github/workflows/ pr-workflow.yml (5)

100-100: Remove Trailing Spaces
Static analysis has flagged trailing spaces on this line. Removing them will help improve YAML linting compliance.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 100-100: trailing spaces

(trailing-spaces)


107-110: Install dioxus-cli Step: Remove Trailing Spaces
The step for installing dioxus-cli is accurate; however, please remove any trailing spaces (notably on line 110) to adhere to YAML formatting best practices.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 110-110: trailing spaces

(trailing-spaces)


111-118: Dioxus Lint Step (Build-UI Job): Fix Indentation and Trailing Spaces
There is an indentation issue on line 113 (expected 10 spaces but found 9) and trailing spaces are flagged on line 118. Please adjust the indentation and remove trailing spaces to comply with YAML lint standards.

🧰 Tools
🪛 YAMLlint (1.35.1)

[warning] 113-113: wrong indentation: expected 10 but found 9

(indentation)


[error] 118-118: trailing spaces

(trailing-spaces)


119-128: Build Test Step (Build-UI Job): Fix Indentation and Trailing Spaces
Static analysis indicates an indentation issue on line 121 (expected 10 spaces but found 9) and trailing spaces on line 127. Please correct these formatting issues.

🧰 Tools
🪛 YAMLlint (1.35.1)

[warning] 121-121: wrong indentation: expected 10 but found 9

(indentation)


[error] 127-127: trailing spaces

(trailing-spaces)


147-154: Ensure Newline at End of File
The file is missing a newline at the end (line 154). Please add a newline to comply with standard file formatting practices.

🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 154-154: no new line character at the end of file

(new-line-at-end-of-file)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a2f995b and 312a4d2.

📒 Files selected for processing (1)
  • .github/workflows/ pr-workflow.yml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.4)
.github/workflows/ pr-workflow.yml

30-30: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


60-60: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


96-96: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


132-132: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 YAMLlint (1.35.1)
.github/workflows/ pr-workflow.yml

[error] 100-100: trailing spaces

(trailing-spaces)


[error] 110-110: trailing spaces

(trailing-spaces)


[warning] 113-113: wrong indentation: expected 10 but found 9

(indentation)


[error] 118-118: trailing spaces

(trailing-spaces)


[warning] 121-121: wrong indentation: expected 10 but found 9

(indentation)


[error] 127-127: trailing spaces

(trailing-spaces)


[error] 154-154: no new line character at the end of file

(new-line-at-end-of-file)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: build-ui
  • GitHub Check: main-ui
  • GitHub Check: api
🔇 Additional comments (10)
.github/workflows/ pr-workflow.yml (10)

1-2: Workflow Name Defined
The workflow name "PR Testing" is clearly set and communicates its purpose.


3-6: Trigger Configuration
The workflow is triggered on key pull request events (opened, synchronize, reopened, ready_for_review), which aligns well with the CI requirements.


7-9: Global Environment Settings
The global environment variable CARGO_TERM_COLOR is configured properly to maintain consistent output formatting.


10-28: Test Job Setup
The configuration for the "test" job is well-structured. The PostgreSQL service is defined with appropriate environment variables, health checks, and port mapping.


35-40: Rust Toolchain Setup (Test Job)
The Rust toolchain is correctly set up with Clippy and Rustfmt, with the appropriate target (wasm32-unknown-unknown), ensuring consistent testing and linting.


40-46: Database Initialization
The steps to install the PostgreSQL client and initialize the database using the provided SQL script are implemented correctly.


47-56: Test Execution Command
The testing command (cd packages/api && make test) and corresponding environment variables for the test run are set appropriately.


65-74: Rust Toolchain & CLI Installation (Main-UI Job)
The toolchain setup and installation of dioxus-cli via cargo-binstall in the "main-ui" job are configured correctly.


75-82: Dioxus Lint Step (Main-UI Job)
The Dioxus linting step is configured with the proper AWS environment variables and command (dx check -p main-ui), ensuring code quality for the main UI.


83-92: Build Test Step (Main-UI Job)
The build step installs Tailwind CSS and invokes the Makefile build process with the correct environment variables. This is set up correctly.

Comment on lines +30 to +34
- uses: actions/checkout@v3
with:
submodules: recursive
ssh-key: ${{ secrets.PULL_KEY_REPO }}

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Update Checkout Action Version (Test Job)
The test job uses actions/checkout@v3, which static analysis flags as outdated. Consider updating to a more recent version (e.g., actions/checkout@v4 if available) for enhanced compatibility.

🧰 Tools
🪛 actionlint (1.7.4)

30-30: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

Comment on lines +60 to +64
- uses: actions/checkout@v3
with:
submodules: recursive
ssh-key: ${{ secrets.PULL_KEY_REPO }}

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Update Checkout Action Version (Main-UI Job)
In the "main-ui" job, the checkout step still uses actions/checkout@v3. Please update this action to a newer version to address the static analysis concerns.

🧰 Tools
🪛 actionlint (1.7.4)

60-60: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

Comment on lines +96 to +99
- uses: actions/checkout@v3
with:
submodules: recursive
ssh-key: ${{ secrets.PULL_KEY_REPO }}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Update Checkout Action Version (Build-UI Job)
The "build-ui" job also uses actions/checkout@v3. As static analysis indicates, consider updating this action to a newer version to avoid potential issues.

🧰 Tools
🪛 actionlint (1.7.4)

96-96: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

Comment on lines +132 to +135
- uses: actions/checkout@v3
with:
submodules: recursive
ssh-key: ${{ secrets.PULL_KEY_REPO }}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Update Checkout Action Version (API Job)
In the "api" job, the workflow repeats the use of actions/checkout@v3. Updating to a newer version is recommended to address static analysis warnings.

🧰 Tools
🪛 actionlint (1.7.4)

132-132: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

@dotandev dotandev merged commit 35cb8a8 into biyard:dev Mar 12, 2025
4 of 5 checks passed
@github-actions github-actions bot mentioned this pull request Apr 14, 2025
31 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0