Skip to content

Conversation

@sushilparajuli
Copy link
Collaborator

@sushilparajuli sushilparajuli commented Nov 14, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Added GitHub Actions CI/CD workflows for automated testing (unit and end-to-end)
    • Introduced comprehensive test coverage across server and client components
    • Added end-to-end testing with Cypress for critical user journeys
  • Documentation

    • Expanded README with project layout, quick start guides, local development setup, and testing instructions
  • Improvements

    • Enhanced UI component accessibility with ARIA attributes and testing identifiers
    • Refactored chart tooltip to shared component for better maintainability
    • Improved error handling with graceful fallbacks using mock data
  • Tests

    • Added Jest unit test configurations and comprehensive test suites
    • Created Cypress E2E test fixtures and configuration

@coderabbitai
Copy link

coderabbitai bot commented Nov 14, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Comprehensive testing and CI/CD infrastructure setup for a full-stack trading application. Introduces Jest configurations and unit tests for server services, entities, and repositories; adds Cypress E2E testing framework with client component tests; establishes GitHub Actions workflows for automated server/client testing and end-to-end testing; and updates source files with minor modifications for test support.

Changes

Cohort / File(s) Summary
GitHub Actions CI/CD Workflows
.github/workflows/ci.yml, .github/workflows/e2e.yml
Added CI workflow with server and client test jobs; added E2E workflow for Cypress tests with artifact upload on failure.
Server Jest Testing Infrastructure
server/market-trading-service/jest.config.ts, server/market-trading-service/package.json
Added Jest TypeScript configuration with ts-jest preset; introduced test, test:watch, and test:coverage scripts with Jest, ts-jest, supertest, and related type definitions.
Server Unit Tests
server/market-trading-service/src/api/controllers/__tests__/TickerController.test.ts, server/market-trading-service/src/core/entities/__tests__/Ticker.test.ts, server/market-trading-service/src/core/services/__tests__/MarketDataService.test.ts, server/market-trading-service/src/core/services/__tests__/PriceSimulator.test.ts, server/market-trading-service/src/infrastructure/repositories/__tests__/TickerRepository.test.ts
Added test suites for TickerController, Ticker entity, MarketDataService, PriceSimulator, and TickerRepository covering core business logic and API endpoints.
Server Source Updates
server/market-trading-service/src/index.ts, server/market-trading-service/src/models/ticker.ts
Updated runtime module aliasing with explicit path setup; replaced manual health response with standardized success response utility; removed legacy Ticker model class.
Client Jest Testing Infrastructure
client/trading-dashboard/jest.config.ts, client/trading-dashboard/jest.setup.ts, client/trading-dashboard/package.json
Added Jest/Next.js configuration with jsdom environment; added jest-dom setup; introduced test scripts and testing dependencies including @testing-library packages and ts-jest.
Client Cypress E2E Testing Infrastructure
client/trading-dashboard/cypress.config.ts, client/trading-dashboard/cypress/support/commands.ts, client/trading-dashboard/cypress/support/e2e.ts, client/trading-dashboard/cypress/fixtures/tickers.json, client/trading-dashboard/cypress/fixtures/ticker-history.json
Added Cypress configuration with e2e baseUrl and spec patterns; added support structure with commands and e2e imports; added fixture data for tickers and historical data.
Client Component Tests
client/trading-dashboard/components/__tests__/PriceChart.test.tsx, client/trading-dashboard/components/__tests__/TickerCard.test.tsx, client/trading-dashboard/components/__tests__/TickerDetails.test.tsx, client/trading-dashboard/components/__tests__/TickerIcon.test.tsx, client/trading-dashboard/components/__tests__/TickerItem.test.tsx, client/trading-dashboard/components/__tests__/Hero.test.tsx, client/trading-dashboard/components/__tests__/NewsFeed.test.tsx, client/trading-dashboard/components/__tests__/TickerGrid.test.tsx, client/trading-dashboard/app/__tests__/page.test.tsx
Added comprehensive test suites for UI components covering rendering, interactions, data display, and accessibility; includes tests for Hero, TickerGrid, PriceChart, and page layout.
Client Hook & Utility Tests
client/trading-dashboard/components/__tests__/useTradingData.test.tsx, client/trading-dashboard/lib/utils.test.ts
Added tests for useTradingData hook with fetch error handling and fallback behavior; added tests for formatCurrency and formatLargeNumber utilities.
Client Cypress E2E Tests
client/trading-dashboard/cypress/e2e/home.cy.ts
Added comprehensive E2E test suite validating hero section, ticker grid rendering, price formatting, responsive behavior, and API interception.
Client Component Refactoring & Testability Updates
client/trading-dashboard/components/PriceChart.tsx, client/trading-dashboard/components/TickerCard.tsx, client/trading-dashboard/components/TickerGrid.tsx, client/trading-dashboard/components/Hero.tsx, client/trading-dashboard/components/ui/CustomTooltip.tsx, client/trading-dashboard/components/ui/LoadingSpinner.tsx, client/trading-dashboard/components/Header.tsx, client/trading-dashboard/components/NewsFeed.tsx, client/trading-dashboard/app/page.tsx, client/trading-dashboard/app/not-found.tsx
Extracted CustomTooltip to shared component; added data-testid attributes for testing; updated component structure for accessibility (ARIA attributes); added NotFound component; converted async page component to synchronous; applied minor styling adjustments; updated news source.
Documentation
README.md
Expanded README with project layout, quick start instructions, local development setup, testing guidelines, and CI/CD notes.

Sequence Diagram(s)

sequenceDiagram
    participant GitHub as GitHub Actions
    participant CI as CI Workflow
    participant Server as Server Tests
    participant E2E as E2E Workflow
    participant Client as Client Build/Tests
    participant Cypress as Cypress Tests
    
    GitHub->>CI: Push/PR triggered
    CI->>Server: Run Jest tests (TickerController, Services, Entities, Repos)
    Server->>CI: Test results (pass/fail)
    CI->>Client: Run Jest unit tests (Components, Hooks, Utils)
    Client->>CI: Test results (pass/fail)
    
    GitHub->>E2E: Push to main/feature triggered
    E2E->>Client: Build client app
    Client->>E2E: Build complete
    E2E->>Cypress: Start Cypress tests (home.cy.ts)
    Cypress->>Client: Intercept /api/tickers, stub with fixture
    Client->>Cypress: Render with mocked data
    Cypress->>Cypress: Validate hero, ticker grid, formatting, responsive UI
    Cypress->>E2E: Test results + artifacts (videos/screenshots on failure)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas requiring extra attention:
    • Server test files: Verify that mocks (MarketDataService, TickerRepository) align with actual service interfaces and repository contracts; ensure test coverage adequately validates business logic for price updates, historical data, and error handling.
    • Client hook test (useTradingData.test.tsx): Confirm fetch error handling, fallback to MOCK_TICKERS, and QueryClient retry configuration are correctly simulating real-world scenarios.
    • Cypress E2E test (home.cy.ts): Validate that API interception patterns and fixture data align with expected server responses; check viewport testing covers target device sizes.
    • Component refactoring (PriceChart, TickerGrid): Verify that extraction of CustomTooltip and removal of LoadingSpinner logic do not introduce regressions; confirm placeholder data behavior in TickerGrid useQuery.
    • Configuration consistency: Ensure jest.config.ts files (both server and client) align with tsconfig.json paths and module resolution; verify Cypress baseUrl and Next.js build expectations.

Possibly related PRs

  • Feat: Server for Trading App #1: Adds core server implementation (Ticker model, PriceSimulator, MarketDataService, controllers) which these tests now comprehensively cover.
  • Feature/front end #2: Modifies client frontend components and hooks; this PR adds corresponding test coverage and E2E validation for those features.

Poem

🐰 Testing foundations now in place, with Jest and Cypress keeping pace,
From server services down to UI views, we're hopping through each test with renewed views,
Mock data, fixtures, workflows run—our trading app's test suite has begun! 🎯✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title is overly vague and generic. While it mentions 'testing' and 'github actions,' it doesn't clearly convey the scope or nature of the changes, which include Jest configuration, unit tests, E2E tests, component updates, and fixture files across both server and client. Consider a more specific title that highlights the main changes, such as 'Add comprehensive testing setup with Jest, E2E, and CI/CD workflow' or 'Implement testing infrastructure for server and client applications.'
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c51162 and 64e625f.

📒 Files selected for processing (5)
  • client/trading-dashboard/app/not-found.tsx (1 hunks)
  • client/trading-dashboard/components/PriceChart.tsx (3 hunks)
  • client/trading-dashboard/components/TickerGrid.tsx (3 hunks)
  • client/trading-dashboard/components/__tests__/TickerGrid.test.tsx (1 hunks)
  • client/trading-dashboard/components/ui/CustomTooltip.tsx (1 hunks)

Comment @coderabbitai help to get the list of available commands and usage tips.

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: 2

🧹 Nitpick comments (8)
README.md (1)

23-24: Consider wrapping URLs in angle brackets or code blocks.

The bare URLs trigger markdown linting warnings. While functional, wrapping them improves markdown compliance.

Apply this diff to address the linting warnings:

-  - Frontend: http://localhost:3000
-  - Backend API: http://localhost:3005 (health endpoint: `/health`)
+  - Frontend: <http://localhost:3000>
+  - Backend API: <http://localhost:3005> (health endpoint: `/health`)

Based on static analysis hints.

.github/workflows/ci.yml (1)

39-42: Consider running client and server tests in parallel.

The needs: server-tests creates a sequential dependency, increasing total CI time. Since these are independent unit/integration tests, they could run in parallel for faster feedback.

Remove the needs field to run tests concurrently:

  client-tests:
    name: Client tests (conditional)
    runs-on: ubuntu-latest
-   needs: server-tests
    steps:
server/market-trading-service/src/core/services/__tests__/MarketDataService.test.ts (2)

7-21: Consider adding type safety to the simulator mock.

The mockSimulator is typed as any, which bypasses TypeScript's type checking. Consider creating a proper mock type or using jest.Mocked<IPriceSimulator> for better type safety and IDE support.

  let service: MarketDataService;
  let mockRepo: jest.Mocked<ITickerRepository>;
- let mockSimulator: any;
+ let mockSimulator: jest.Mocked<IPriceSimulator>;

  beforeEach(() => {
    mockRepo = {
      findAll: jest.fn(),
      findBySymbol: jest.fn(),
      save: jest.fn(),
      update: jest.fn(),
    };

    mockSimulator = {
      start: jest.fn(),
      stop: jest.fn(),
+     stopAll: jest.fn(),
      generateHistoricalData: jest.fn(),
    };

4-53: Test coverage is incomplete for MarketDataService.

The test suite covers getAllTickers, getTicker, and null handling, but the MarketDataService also has startSimulation, getHistoricalData, and stopSimulation methods that lack test coverage. Adding tests for these methods would improve confidence in the service behavior.

Would you like me to generate test cases for the missing methods?

server/market-trading-service/src/infrastructure/repositories/__tests__/TickerRepository.test.ts (1)

3-56: Consider adding edge case tests.

The test suite covers happy paths but could benefit from additional edge cases:

  • Testing findBySymbol with a non-existent symbol
  • Testing case sensitivity (e.g., "aapl" vs "AAPL")
  • Testing update with a non-existent ticker

Example additions:

it("should return null for non-existent symbol", async () => {
  const ticker = await repository.findBySymbol("NONEXISTENT");
  expect(ticker).toBeNull();
});

it("should handle case-insensitive symbol lookup", async () => {
  const ticker = await repository.findBySymbol("aapl");
  expect(ticker).toBeDefined();
  expect(ticker?.symbol).toBe("AAPL");
});
server/market-trading-service/src/api/controllers/__tests__/TickerController.test.ts (3)

18-18: Unused mock method: getQuote.

The getQuote method is included in the mock service but is never used in any test. Consider removing it to keep the mock minimal and focused.

  mockService = {
    getAllTickers: jest.fn(),
    getTicker: jest.fn(),
    getHistoricalData: jest.fn(),
-   getQuote: jest.fn(),
  };

6-55: Consider adding test coverage for the getHistoricalData endpoint.

Based on the relevant code snippets, the TickerController has a getHistoricalData method that handles GET /api/tickers/:symbol/history, but there's no test for this endpoint. Adding test coverage would ensure the historical data endpoint works correctly.

Example test to add:

it("GET /api/tickers/:symbol/history should return historical data", async () => {
  const mockHistoricalData = [
    { date: "2024-01-01", price: 100 },
    { date: "2024-01-02", price: 105 },
  ];
  
  mockService.getHistoricalData.mockResolvedValue(mockHistoricalData);

  const response = await request(app)
    .get("/api/tickers/AAPL/history?days=7")
    .expect(200);

  expect(response.body.success).toBe(true);
  expect(response.body.data).toEqual(mockHistoricalData);
  expect(mockService.getHistoricalData).toHaveBeenCalledWith("AAPL", 7);
});

6-55: Consider adding error handling tests.

The test suite doesn't include scenarios where the service throws errors. Adding tests for error cases would improve confidence in the error handling middleware.

Example error test:

it("GET /api/tickers should handle service errors", async () => {
  mockService.getAllTickers.mockRejectedValue(new Error("Service error"));

  const response = await request(app).get("/api/tickers").expect(500);

  expect(response.body.success).toBe(false);
});
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ecbce28 and f8de2df.

⛔ Files ignored due to path filters (1)
  • server/market-trading-service/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (11)
  • .github/workflows/ci.yml (1 hunks)
  • README.md (1 hunks)
  • server/market-trading-service/jest.config.ts (1 hunks)
  • server/market-trading-service/package.json (2 hunks)
  • server/market-trading-service/src/api/controllers/__tests__/TickerController.test.ts (1 hunks)
  • server/market-trading-service/src/core/entities/__tests__/Ticker.test.ts (1 hunks)
  • server/market-trading-service/src/core/services/__tests__/MarketDataService.test.ts (1 hunks)
  • server/market-trading-service/src/core/services/__tests__/PriceSimulator.test.ts (1 hunks)
  • server/market-trading-service/src/index.ts (2 hunks)
  • server/market-trading-service/src/infrastructure/repositories/__tests__/TickerRepository.test.ts (1 hunks)
  • server/market-trading-service/src/models/ticker.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • server/market-trading-service/src/models/ticker.ts
🧰 Additional context used
🧬 Code graph analysis (6)
server/market-trading-service/src/infrastructure/repositories/__tests__/TickerRepository.test.ts (1)
server/market-trading-service/src/infrastructure/repositories/TickerRepository.ts (1)
  • TickerRepository (4-44)
server/market-trading-service/src/core/services/__tests__/MarketDataService.test.ts (2)
server/market-trading-service/src/core/services/MarketDataService.ts (1)
  • MarketDataService (9-46)
server/market-trading-service/src/core/types/index.ts (1)
  • ITickerRepository (26-31)
server/market-trading-service/src/index.ts (1)
server/market-trading-service/src/utils/index.ts (1)
  • createSuccessResponse (17-22)
server/market-trading-service/jest.config.ts (1)
server/market-trading-service/src/infrastructure/config/Config.ts (1)
  • Config (6-13)
server/market-trading-service/src/api/controllers/__tests__/TickerController.test.ts (2)
server/market-trading-service/src/api/controllers/TickerController.ts (1)
  • TickerController (5-66)
server/market-trading-service/src/api/routes/index.ts (1)
  • createRoutes (4-13)
server/market-trading-service/src/core/services/__tests__/PriceSimulator.test.ts (1)
server/market-trading-service/src/core/services/PriceSimulator.ts (1)
  • PriceSimulator (4-78)
🪛 markdownlint-cli2 (0.18.1)
README.md

23-23: Bare URL used

(MD034, no-bare-urls)


24-24: Bare URL used

(MD034, no-bare-urls)

🔇 Additional comments (18)
server/market-trading-service/package.json (2)

13-15: LGTM! Standard Jest test scripts.

The test scripts follow Jest conventions and provide essential testing workflows (run once, watch mode, coverage generation).


27-34: No issues found — all testing library versions are valid and current.

All specified versions in the package.json match the latest stable releases: jest@30.2.0, @types/jest@30.0.0, ts-jest@29.4.5, and supertest@7.1.4 are all current and stable. The concern that jest 30.x might be ahead of released versions is unfounded.

.github/workflows/ci.yml (2)

1-8: LGTM! Appropriate CI trigger configuration.

The workflow triggers on pushes to main branches and feature branches, plus pull requests to main/master, providing good CI coverage.


10-37: LGTM! Well-configured server test job.

The server test job follows GitHub Actions best practices with appropriate caching, clean dependency installation via npm ci, and silent test execution for cleaner logs.

server/market-trading-service/src/index.ts (2)

1-7: LGTM! Path aliasing properly configured.

The runtime alias registration using __dirname correctly resolves to the current directory whether running from src/ (during development with ts-node) or dist/ (production), and aligns with the Jest configuration.


48-51: LGTM! Standardized health endpoint response.

The health check now uses the createSuccessResponse utility, providing a consistent API response format across the application.

server/market-trading-service/src/core/entities/__tests__/Ticker.test.ts (1)

1-34: LGTM! Well-structured entity tests.

The test suite provides good coverage of the Ticker entity's core functionality: symbol normalization, price updates with change tracking, and JSON serialization. Tests are clear and follow good practices.

server/market-trading-service/src/core/services/__tests__/PriceSimulator.test.ts (2)

7-16: LGTM! Proper test setup with fake timers.

The setup and teardown correctly manage Jest fake timers and simulator cleanup, ensuring tests don't leak timers or state between test cases.


18-45: LGTM! Tests cover core simulation behavior.

The tests effectively verify start/stop simulation behavior using fake timers and validate historical data generation. The test suite provides good coverage of the PriceSimulator's main functionality.

server/market-trading-service/jest.config.ts (2)

3-7: LGTM! Standard Jest configuration for TypeScript.

The configuration uses the appropriate ts-jest preset, Node test environment, and standard test matching patterns for TypeScript projects.


10-12: LGTM! Module aliasing correctly configured.

The module name mapper aligns with the runtime path aliasing setup in src/index.ts, ensuring tests can resolve @/ imports consistently with production code.

server/market-trading-service/src/infrastructure/repositories/__tests__/TickerRepository.test.ts (3)

1-8: LGTM! Clean test setup.

The import and beforeEach setup follows Jest best practices, ensuring each test gets a fresh repository instance.


10-16: LGTM! Appropriate validation for findAll.

The test correctly validates that findAll returns a non-empty array of tickers.


18-23: LGTM! Good use of optional chaining.

The test properly handles the nullable return type from findBySymbol.

server/market-trading-service/src/api/controllers/__tests__/TickerController.test.ts (4)

1-23: LGTM! Well-structured test setup.

The test setup properly initializes an Express app with mocked dependencies and mounts the routes under /api. Using supertest for HTTP testing is the right approach.


25-34: LGTM! Appropriate validation of the tickers endpoint.

The test correctly validates both the response structure and the data payload.


36-46: LGTM! Good test coverage for successful ticker retrieval.

The test properly validates the response for a valid ticker symbol.


48-54: LGTM! Appropriate 404 handling test.

The test correctly validates the error response for invalid ticker symbols.

Comment on lines +8 to +9
collectCoverageFrom: ["src/**/*.ts", "!src/server.ts", "!src/**/index.ts"],
coverageDirectory: "coverage",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Verify coverage exclusions are intentional.

The coverage configuration excludes src/server.ts and all index.ts files. Ensure this is intentional, particularly for src/index.ts which contains the main application entry point and was modified in this PR. Consider whether entry point logic should be tested or if the exclusion is appropriate.


🏁 Script executed:

#!/bin/bash
# Check if server.ts exists and list all index.ts files
echo "=== Checking for server.ts ==="
fd -t f "server.ts" server/market-trading-service/src

echo -e "\n=== Listing all index.ts files ==="
fd -t f "index.ts" server/market-trading-service/src

Length of output: 315


🏁 Script executed:

#!/bin/bash
# Check full jest.config.ts and src/index.ts content
echo "=== Full jest.config.ts ==="
cat server/market-trading-service/jest.config.ts

echo -e "\n=== Content of src/index.ts ==="
cat server/market-trading-service/src/index.ts

echo -e "\n=== Checking if index.ts files are mostly re-exports ==="
head -20 server/market-trading-service/src/api/routes/index.ts
echo "---"
head -20 server/market-trading-service/src/types/index.ts

Length of output: 4991


Remove !src/server.ts from coverage exclusion and reconsider excluding src/index.ts.

  • server.ts does not exist in src/, so the !src/server.ts exclusion is unnecessary and should be removed.
  • src/index.ts contains substantial application setup logic (middleware configuration, error handlers, graceful shutdown, process signal handlers), not just re-exports. The !src/**/index.ts pattern excludes it from coverage; consider whether this logic should be tested or refactored into separately testable modules.
🤖 Prompt for AI Agents
In server/market-trading-service/jest.config.ts around lines 8 to 9, the
coverage exclusions include "!src/server.ts" which is a non-existent path and
should be removed, and the pattern "!src/**/index.ts" currently excludes index
files (including src/index.ts) that contain substantive app setup; remove the
"!src/server.ts" entry and reevaluate or remove the "!src/**/index.ts" exclusion
so src/index.ts is included in coverage (or instead refactor the setup logic
into testable modules and only exclude trivial re-export index files).

Comment on lines +46 to +56
it("should update existing ticker", async () => {
const ticker = await repository.findBySymbol("AAPL");

if (ticker) {
ticker.price = 200;
await repository.update(ticker);

const updated = await repository.findBySymbol("AAPL");
expect(updated?.price).toBe(200);
}
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

The update test may not validate persistence correctly.

The test retrieves a ticker from the repository (which returns a reference to the object in the Map), mutates it directly, then calls update. Since JavaScript objects are passed by reference, the ticker in the Map is already modified before update() is called. This means the test would pass even if the update() method was a no-op.

Consider this refactor to properly test the update method:

  it("should update existing ticker", async () => {
    const ticker = await repository.findBySymbol("AAPL");

    if (ticker) {
-     ticker.price = 200;
-     await repository.update(ticker);
+     const updatedTicker = { ...ticker, price: 200 };
+     await repository.update(updatedTicker);

      const updated = await repository.findBySymbol("AAPL");
      expect(updated?.price).toBe(200);
    }
  });

This creates a new object for the update, ensuring the test validates that the update method actually persists changes rather than just mutating an existing reference.

📝 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
it("should update existing ticker", async () => {
const ticker = await repository.findBySymbol("AAPL");
if (ticker) {
ticker.price = 200;
await repository.update(ticker);
const updated = await repository.findBySymbol("AAPL");
expect(updated?.price).toBe(200);
}
});
it("should update existing ticker", async () => {
const ticker = await repository.findBySymbol("AAPL");
if (ticker) {
const updatedTicker = { ...ticker, price: 200 };
await repository.update(updatedTicker);
const updated = await repository.findBySymbol("AAPL");
expect(updated?.price).toBe(200);
}
});
🤖 Prompt for AI Agents
In
server/market-trading-service/src/infrastructure/repositories/__tests__/TickerRepository.test.ts
around lines 46 to 56, the test mutates the object returned by findBySymbol and
then calls update, which only validates in-memory reference mutation rather than
persistence; instead, assert existence of the fetched ticker, create a new
ticker object (clone the fetched object and set price = 200) and pass that new
object to repository.update, then re-fetch from the repository and assert the
persisted price is 200 so the test verifies update() actually persists changes
rather than relying on reference mutation.

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

🧹 Nitpick comments (3)
client/trading-dashboard/components/__tests__/useTradingData.test.tsx (1)

25-36: Consider typing the mock instead of suppressing errors.

The @ts-expect-error suppressions work but could be improved with proper typing.

Apply this diff to properly type the console.error mock:

 describe("useTradingData", () => {
   let originalFetch: any;
+  let consoleErrorMock: jest.SpyInstance;

   beforeEach(() => {
     originalFetch = global.fetch;
-    jest.spyOn(console, "error");
-    // @ts-expect-error jest.spyOn adds this functionallity
-    console.error.mockImplementation(() => null);
+    consoleErrorMock = jest.spyOn(console, "error").mockImplementation(() => null);
   });

   afterEach(() => {
     global.fetch = originalFetch;
-    // @ts-expect-error jest.spyOn adds this functionallity
-    console.error.mockRestore();
+    consoleErrorMock.mockRestore();
   });
client/trading-dashboard/components/__tests__/PriceChart.test.tsx (1)

19-33: Consider using a more semantic query or test ID.

While querying by className (.animate-spin) works, it's brittle if styling changes. For better resilience:

Option 1: Add a test ID to the Loader2 component:

 // In PriceChart.tsx
-<Loader2 className="animate-spin text-blue-600 w-10 h-10" />
+<Loader2 className="animate-spin text-blue-600 w-10 h-10" data-testid="price-chart-loader" />

Then update the test:

-expect(container.querySelector(".animate-spin")).toBeInTheDocument();
+expect(screen.getByTestId("price-chart-loader")).toBeInTheDocument();

Option 2: Query by role if the loader has accessible attributes, though icons typically don't have semantic roles.

client/trading-dashboard/jest.config.ts (1)

10-25: Remove redundant transform configuration.

The explicit transform config using ts-jest is unnecessary and potentially problematic when using next/jest. Next.js automatically configures TypeScript transformation via its built-in SWC compiler, which is faster and ensures consistency between test and runtime environments. The explicit ts-jest transform overrides this behavior.

Apply this diff to remove the redundant configuration:

 const config: Config = {
   coverageProvider: "v8",
   testEnvironment: "jsdom",
   // Setup testing-library
   setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"],

   // Map path alias
   moduleNameMapper: {
     "^@/(.*)$": "<rootDir>/$1",
   },
-
-  // Transform TS/TSX using ts-jest
-  transform: {
-    "^.+\\.(ts|tsx)$": ["ts-jest", { tsconfig: "<rootDir>/tsconfig.json" }],
-  },
 };

The next/jest wrapper will handle TypeScript transformation automatically.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f8de2df and 0692dbc.

⛔ Files ignored due to path filters (1)
  • client/trading-dashboard/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (10)
  • client/trading-dashboard/components/PriceChart.tsx (1 hunks)
  • client/trading-dashboard/components/__tests__/PriceChart.test.tsx (1 hunks)
  • client/trading-dashboard/components/__tests__/TickerCard.test.tsx (1 hunks)
  • client/trading-dashboard/components/__tests__/TickerDetails.test.tsx (1 hunks)
  • client/trading-dashboard/components/__tests__/TickerIcon.test.tsx (1 hunks)
  • client/trading-dashboard/components/__tests__/TickerItem.test.tsx (1 hunks)
  • client/trading-dashboard/components/__tests__/useTradingData.test.tsx (1 hunks)
  • client/trading-dashboard/jest.config.ts (1 hunks)
  • client/trading-dashboard/jest.setup.ts (1 hunks)
  • client/trading-dashboard/package.json (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
client/trading-dashboard/components/__tests__/TickerDetails.test.tsx (1)
client/trading-dashboard/components/TickerDetails.tsx (1)
  • TickerDetails (12-60)
client/trading-dashboard/components/__tests__/TickerIcon.test.tsx (1)
client/trading-dashboard/components/TickerIcon.tsx (1)
  • TickerIcon (11-37)
client/trading-dashboard/components/__tests__/TickerItem.test.tsx (1)
client/trading-dashboard/components/TickerItem.tsx (1)
  • TickerItem (15-84)
client/trading-dashboard/components/__tests__/PriceChart.test.tsx (1)
client/trading-dashboard/components/PriceChart.tsx (1)
  • PriceChart (56-170)
client/trading-dashboard/components/__tests__/useTradingData.test.tsx (2)
client/trading-dashboard/hooks/useTradingData.ts (1)
  • useTradingData (7-94)
client/trading-dashboard/constants/index.ts (1)
  • MOCK_TICKERS (8-117)
🔇 Additional comments (13)
client/trading-dashboard/jest.setup.ts (1)

1-1: LGTM!

Standard Jest setup that enables extended DOM matchers for testing. This is the correct approach for integrating @testing-library/jest-dom with your test suite.

client/trading-dashboard/components/PriceChart.tsx (1)

105-116: LGTM!

The addition of min-w-0 and the ResponsiveContainer props (minWidth={0}, minHeight={undefined}) properly address flex layout shrinking behavior, ensuring the chart renders correctly within its flex container without overflow issues.

client/trading-dashboard/components/__tests__/TickerCard.test.tsx (1)

1-29: LGTM!

The test provides basic coverage for TickerCard rendering, verifying that key ticker information (symbol, name, price, change, and change percentage) is displayed correctly. The test structure is clear and appropriate.

client/trading-dashboard/package.json (2)

9-11: LGTM!

The test scripts (test and test:watch) are properly configured for Jest.


28-42: LGTM!

The testing dependencies are appropriate and include the standard testing toolkit for React applications:

  • Testing Library suite for component testing
  • Jest and jest-environment-jsdom for test execution
  • ts-jest for TypeScript support
client/trading-dashboard/components/__tests__/TickerIcon.test.tsx (1)

1-21: LGTM!

The tests correctly verify that:

  1. The first letter of the symbol is rendered and the element has the proper aria-hidden="true" attribute
  2. A deterministic color class from the palette is applied based on the symbol

The test logic aligns with the TickerIcon implementation.

client/trading-dashboard/components/__tests__/TickerItem.test.tsx (1)

1-55: LGTM!

The tests provide good coverage for TickerItem:

  1. Verifies rendering of ticker information and proper callback invocation on click
  2. Confirms correct display of negative change values with the minus sign

The use of userEvent for interaction testing is appropriate.

client/trading-dashboard/components/__tests__/TickerDetails.test.tsx (1)

1-26: LGTM!

The test verifies that TickerDetails correctly renders the essential ticker information (name, symbol, formatted price, and change percentage). The test structure is clear and appropriate.

client/trading-dashboard/components/__tests__/useTradingData.test.tsx (1)

38-59: LGTM!

The test correctly verifies the fallback behavior when the tickers fetch fails, ensuring that:

  • MOCK_TICKERS are used as fallback data
  • The first ticker is auto-selected
  • An appropriate error message is displayed

The test setup with QueryClient and fetch mocking is appropriate.

client/trading-dashboard/components/__tests__/PriceChart.test.tsx (2)

1-5: LGTM!

The imports are correctly configured for React component testing with Testing Library and user-event.


35-52: LGTM!

This test properly verifies user interaction using semantic queries and correctly validates the callback behavior. The use of getByRole and userEvent follows React Testing Library best practices.

client/trading-dashboard/jest.config.ts (2)

1-7: LGTM!

The Next.js Jest integration is correctly configured with the appropriate directory path.


27-28: LGTM!

The export pattern correctly wraps the config to allow Next.js to merge its async configuration.

Comment on lines +6 to +17
const makeData = (points = 5) => {
const now = Date.now();
return Array.from({ length: points }).map((_, i) => ({
timestamp: new Date(now - (points - i) * 3600 * 1000),
price: 100 + i * 2,
volume: 1000 + i * 10,
open: 100 + i * 1.5,
high: 100 + i * 2.5,
low: 100 + i * 0.5,
close: 100 + i * 2,
}));
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

Verify timestamp format compatibility with Recharts.

The makeData helper creates Date objects for the timestamp field. Recharts typically expects timestamps as numbers (milliseconds since epoch) or ISO strings, not Date objects. While Recharts may handle Date objects in some cases, using numeric timestamps is more reliable.

Consider this safer implementation:

 const makeData = (points = 5) => {
   const now = Date.now();
   return Array.from({ length: points }).map((_, i) => ({
-    timestamp: new Date(now - (points - i) * 3600 * 1000),
+    timestamp: now - (points - i) * 3600 * 1000,
     price: 100 + i * 2,
     volume: 1000 + i * 10,
     open: 100 + i * 1.5,
     high: 100 + i * 2.5,
     low: 100 + i * 0.5,
     close: 100 + i * 2,
   }));
 };

Run this script to check how timestamps are used elsewhere in the codebase:

Alternatively, verify Recharts documentation for date handling:


🏁 Script executed:

#!/bin/bash
# Search for timestamp field usage in chart-related code
rg -n -C3 --type=tsx --type=ts 'timestamp.*Date|Date.*timestamp' client/trading-dashboard/

Length of output: 27


🌐 Web query:

Does Recharts AreaChart support Date objects as timestamp values in dataKey?

💡 Result:

Short answer: Yes — you can put JS Date objects in your chart data and use them as the X-axis/dataKey, but some Recharts APIs expect primitive string|number values, so you may run into features that require converting the Date to a timestamp or formatted string.

Details:

  • Recharts will pass your data value (a Date object) to XAxis tickFormatter/Tooltip, so formatting functions like moment/date-fns can consume it. [1][4]
  • However, some props and components (e.g., ReferenceLine.x, and internal matching logic) are typed/implemented to accept number|string and will error or fail to match when given a Date; several GitHub issues/discussions recommend converting Dates to numbers/ISO strings for full compatibility. [5][2]
  • Common practice: store x values as timestamps (ms) or ISO strings in data, then use tickFormatter to render human‑readable dates. This gives the most consistent behavior across Recharts features. [7][4]

References:
[1] Example showing Date values used with XAxis and tick formatting.
[2] StackOverflow / tooltip/tick mismatch discussion.
[4] PostHog / Recharts timeseries example (uses date strings).
[5] Recharts GitHub discussion explaining ReferenceLine/x expects number|string.


🏁 Script executed:

#!/bin/bash
# Search for timestamp usage in tsx files using fd and rg
rg -n -C3 'timestamp' --glob='*.tsx' --glob='*.ts' client/trading-dashboard/

Length of output: 3012


🏁 Script executed:

#!/bin/bash
# Check PriceChart.tsx specifically to see how data is used
fd 'PriceChart.tsx' client/trading-dashboard/ -x cat {}

Length of output: 5142


🏁 Script executed:

#!/bin/bash
# Look for ReferenceLine or other Recharts components that may have issues with Date objects
rg -n 'ReferenceLine|CartesianGrid|Tooltip' --glob='*.tsx' client/trading-dashboard/

Length of output: 473


Timestamp format mismatch extends beyond test data—type definition and production code also affected.

The review correctly identifies a timestamp compatibility issue. However, the problem is broader than the test file alone:

  • Type definition (types/index.ts:15): Defines timestamp: Date
  • Production data (lib/utils.ts:45): Creates new Date(...) objects matching the type
  • Component usage (PriceChart.tsx:137, 138): Calls new Date(time).toLocaleDateString(...), expecting numeric timestamps
  • Test data (PriceChart.test.tsx:9): Mirrors production, creating Date objects

While new Date(dateObject) technically works via valueOf(), it's inefficient and fragile. To properly fix this:

  1. Change HistoricalData.timestamp from Date to number (milliseconds)
  2. Update production data generator (lib/utils.ts:45) to remove new Date() wrapper
  3. Update test data (PriceChart.test.tsx:9) as suggested in the review

Without coordinating these changes, the type definition and actual data structure will remain misaligned with component expectations.

🤖 Prompt for AI Agents
In client/trading-dashboard/components/__tests__/PriceChart.test.tsx around
lines 6-17 and in the related files types/index.ts (line ~15) and lib/utils.ts
(line ~45), the timestamp is currently modeled and produced as a Date object
while the component expects a numeric epoch (milliseconds); change the
HistoricalData.timestamp type from Date to number in types/index.ts, update the
production data generator in lib/utils.ts to return timestamp as a number (use
Date.now() or date.getTime() instead of new Date(...)), and modify the test
helper in PriceChart.test.tsx to set timestamp to a numeric value (milliseconds)
so types, production code, and tests all align with the component's numeric
timestamp usage.

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: 3

🧹 Nitpick comments (6)
client/trading-dashboard/components/__tests__/TickerGrid.test.tsx (1)

10-125: Consider adding error handling test coverage.

The current test suite covers loading and success states well. Consider adding a test for fetch failure scenarios to ensure error states are handled gracefully.

Example test to add:

it("handles fetch errors gracefully", async () => {
  (global.fetch as jest.Mock).mockRejectedValueOnce(
    new Error("Network error")
  );

  render(
    <QueryClientProvider client={queryClient}>
      <TickerGrid />
    </QueryClientProvider>
  );

  await waitFor(() => {
    // Assert error message or fallback UI is displayed
    expect(screen.queryByRole("status")).not.toBeInTheDocument();
  });
});
client/trading-dashboard/components/__tests__/Hero.test.tsx (1)

36-41: Optional: Consider testing via data-testid instead of class name.

Testing CSS classes like bg-gradient-to-br can be brittle if styling changes. Since you added data-testid="hero" to the component, consider testing structural elements via semantic queries or test IDs rather than implementation details like class names.

Example alternative:

-  it("has proper section structure with gradient background", () => {
-    const { container } = render(<Hero />);
-
-    const section = container.querySelector("section");
-    expect(section).toHaveClass("bg-gradient-to-br");
-  });
+  it("renders the hero section", () => {
+    render(<Hero />);
+    
+    expect(screen.getByTestId("hero")).toBeInTheDocument();
+  });
client/trading-dashboard/components/__tests__/NewsFeed.test.tsx (1)

69-74: Optional: Testing CSS classes couples tests to implementation details.

Similar to the Hero tests, asserting on CSS class names like bg-secondary/30 makes tests brittle. Consider focusing on semantic structure or add a data-testid to test the section's presence instead.

client/trading-dashboard/lib/utils.test.ts (2)

3-7: formatCurrency tests are aligned; consider a slightly stricter tiny-decimal assertion

The expectations here match the current formatCurrency implementation and typical UI usage. If you want to tighten the tiny-decimal check, you could anchor the regex or assert the full string (e.g. toBe("$0.000123")) so it fails if formatting ever adds/remove extra digits.


9-12: Validate non-abbreviated formatting style and extend coverage if useful

These expectations match the current formatLargeNumber logic (no thousands separator on the non-abbreviated path). Two follow-ups to consider:

  • If visual consistency with formatCurrency is desired, you may want $2,000.00 instead of $2000.00. If the current style is intentional, no change needed.
  • For robustness, you could add tests for the B/T branches and boundary values (e.g. just below/above 1e6, 1e9, 1e12).
client/trading-dashboard/cypress/e2e/home.cy.ts (1)

1-6: LGTM - Good starting point for E2E testing.

The test correctly uses Cypress's built-in retry logic with .should("be.visible") to handle async rendering. This is a solid foundation for E2E coverage.

Consider enhancing test robustness with data-testid attributes:

 describe("Home page", () => {
   it("loads and shows hero text", () => {
     cy.visit("/");
-    cy.contains("Live Market Data").should("be.visible");
+    cy.get('[data-testid="hero-title"]').should("be.visible").and("contain", "Live Market Data");
   });
 });

This makes tests more resilient to text changes and internationalization.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0692dbc and 1047b7f.

⛔ Files ignored due to path filters (1)
  • client/trading-dashboard/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (15)
  • .github/workflows/e2e.yml (1 hunks)
  • client/trading-dashboard/app/__tests__/page.test.tsx (1 hunks)
  • client/trading-dashboard/app/page.tsx (1 hunks)
  • client/trading-dashboard/components/Hero.tsx (1 hunks)
  • client/trading-dashboard/components/NewsFeed.tsx (1 hunks)
  • client/trading-dashboard/components/__tests__/Hero.test.tsx (1 hunks)
  • client/trading-dashboard/components/__tests__/NewsFeed.test.tsx (1 hunks)
  • client/trading-dashboard/components/__tests__/TickerGrid.test.tsx (1 hunks)
  • client/trading-dashboard/components/ui/LoadingSpinner.tsx (1 hunks)
  • client/trading-dashboard/cypress.config.ts (1 hunks)
  • client/trading-dashboard/cypress/e2e/home.cy.ts (1 hunks)
  • client/trading-dashboard/cypress/support/commands.ts (1 hunks)
  • client/trading-dashboard/cypress/support/e2e.ts (1 hunks)
  • client/trading-dashboard/lib/utils.test.ts (1 hunks)
  • client/trading-dashboard/package.json (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • client/trading-dashboard/cypress/support/commands.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • client/trading-dashboard/package.json
🧰 Additional context used
🧬 Code graph analysis (3)
client/trading-dashboard/lib/utils.test.ts (1)
client/trading-dashboard/lib/utils.ts (2)
  • formatCurrency (10-17)
  • formatLargeNumber (19-24)
client/trading-dashboard/app/__tests__/page.test.tsx (1)
client/trading-dashboard/app/page.tsx (1)
  • Index (6-14)
client/trading-dashboard/components/__tests__/TickerGrid.test.tsx (1)
client/trading-dashboard/constants/index.ts (1)
  • MOCK_TICKERS (8-117)
🔇 Additional comments (18)
client/trading-dashboard/components/ui/LoadingSpinner.tsx (1)

13-17: LGTM! Proper accessibility enhancement.

The addition of aria-busy="true" and role="status" attributes follows accessibility best practices for loading indicators, making the loading state properly announced to screen readers.

client/trading-dashboard/components/__tests__/TickerGrid.test.tsx (6)

1-9: LGTM! Clean test setup.

The imports and global fetch mock are properly configured for testing components that use React Query and fetch API.


10-22: LGTM! Proper test isolation.

The QueryClient configuration with retry: false and mock clearing in beforeEach ensures fast, isolated, and predictable tests.


24-36: LGTM! Validates accessibility enhancement.

This test correctly verifies the loading state and validates the role="status" attribute added to LoadingSpinner.tsx, ensuring the accessibility improvement works as expected.


38-84: LGTM! Comprehensive data fetch test.

The test properly mocks the fetch response and validates that ticker data is rendered correctly, checking both symbols and company names.


86-104: LGTM! Validates static content rendering.

This test ensures the section title and description are displayed correctly, independent of the data state.


106-125: LGTM! Grid layout validation looks good.

The test correctly verifies that multiple ticker cards render in a grid structure. Using querySelector for the grid element is acceptable here since you're validating the structure rather than user-facing content.

client/trading-dashboard/components/Hero.tsx (1)

5-8: LGTM! Clean testing support.

The addition of data-testid="hero" follows testing best practices and enables reliable test queries without affecting component behavior.

client/trading-dashboard/components/__tests__/Hero.test.tsx (1)

1-42: LGTM! Comprehensive test coverage.

The test suite provides good coverage of the Hero component's key elements and structure. The tests are well-organized and use appropriate testing patterns.

client/trading-dashboard/components/__tests__/NewsFeed.test.tsx (1)

6-13: LGTM! Proper timer management.

The fake timer setup in beforeEach and cleanup in afterEach correctly stabilizes tests for components with time-based behavior.

client/trading-dashboard/app/page.tsx (1)

5-14: Verify: Was async data fetching intentionally removed?

The conversion from async to synchronous removes the ability to fetch data in this Server Component. While this simplifies testing, ensure that:

  1. No data fetching was previously happening in this component
  2. If data fetching is needed in the future, consider using proper test mocking strategies rather than modifying production code for testability

The comment indicates this was done "so Jest can render it," but Next.js 16 with React 19 should support testing async Server Components with proper setup.

client/trading-dashboard/app/__tests__/page.test.tsx (2)

4-17: LGTM! Proper component mocking pattern.

The mocks are correctly structured with __esModule: true and provide simple test doubles for the child components. The comment on line 3 helpfully explains the importance of mock order.


20-31: LGTM! Appropriate page-level tests.

The tests verify both component composition and layout structure without being overly specific. This strikes a good balance for integration-level tests.

client/trading-dashboard/cypress/support/e2e.ts (1)

1-1: LGTM - Standard Cypress support file setup.

client/trading-dashboard/cypress.config.ts (1)

1-9: LGTM - Standard Cypress configuration.

The configuration correctly sets up E2E testing with appropriate defaults. The baseUrl can be overridden via the CYPRESS_BASE_URL environment variable in CI, which the workflow does set.

.github/workflows/e2e.yml (3)

1-29: LGTM - Well-configured workflow foundation.

The workflow structure follows GitHub Actions best practices:

  • Appropriate triggers for feature branches and PRs
  • Node.js caching reduces build times
  • 20-minute timeout prevents hanging jobs

49-56: LGTM - Good observability on failure.

Uploading Cypress videos and screenshots on failure is essential for debugging flaky tests in CI.


36-48: Mock data fallback mechanism is correctly implemented and tested.

The implementation properly handles the unreachable host scenario:

  • When fetch to 127.0.0.1:59999 fails, the catch block returns MOCK_TICKERS immediately
  • Browser's native fetch fails quickly on connection refused (not waiting for the 120s timeout)
  • Error logging is suppressed in tests via console.error.mockRestore()
  • Polling is throttled at refetchInterval: 2000 to avoid hammering the unreachable host

The fallback logic is validated by the existing test case "falls back to MOCK_TICKERS when tickers fetch fails" in client/trading-dashboard/components/__tests__/useTradingData.test.tsx.

Comment on lines 30 to 34
- name: Install client deps & build
working-directory: client/trading-dashboard
run: |
npm ci
npm run build
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Next.js env vars must be set during build.

Next.js bakes NEXT_PUBLIC_* environment variables at build time, not runtime. Setting NEXT_PUBLIC_MARKET_TRADING_URL in the Cypress step (Line 46) won't affect the already-built application.

Apply this diff to set the environment variable during the build:

       - name: Install client deps & build
         working-directory: client/trading-dashboard
+        env:
+          NEXT_PUBLIC_MARKET_TRADING_URL: http://127.0.0.1:59999
         run: |
           npm ci
           npm run build

Then update the Cypress step to remove the redundant env var from there since it's now baked into the build.

📝 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
- name: Install client deps & build
working-directory: client/trading-dashboard
run: |
npm ci
npm run build
- name: Install client deps & build
working-directory: client/trading-dashboard
env:
NEXT_PUBLIC_MARKET_TRADING_URL: http://127.0.0.1:59999
run: |
npm ci
npm run build
🤖 Prompt for AI Agents
In .github/workflows/e2e.yml around lines 30 to 34, the workflow builds the
Next.js client without exporting NEXT_PUBLIC_MARKET_TRADING_URL, so the public
env var set later in the Cypress step is not baked into the build; update the
"Install client deps & build" step to export NEXT_PUBLIC_MARKET_TRADING_URL
(e.g., set it in the run block or use env: for that job/step) so the value is
available at build time, and then remove the redundant
NEXT_PUBLIC_MARKET_TRADING_URL assignment from the Cypress step (around line 46)
since the built app will already have the correct value.

it("renders news items with source and time", () => {
render(<NewsFeed />);

expect(screen.getByText("Financial Times")).toBeInTheDocument();
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: This test will fail.

Line 45 expects "Financial Times", but NewsFeed.tsx line 52 was changed to "The Guardian". This test assertion is now incorrect and will fail.

Apply this fix:

-    expect(screen.getByText("Financial Times")).toBeInTheDocument();
+    expect(screen.getByText("The Guardian")).toBeInTheDocument();
📝 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
expect(screen.getByText("Financial Times")).toBeInTheDocument();
expect(screen.getByText("The Guardian")).toBeInTheDocument();
🤖 Prompt for AI Agents
In client/trading-dashboard/components/__tests__/NewsFeed.test.tsx around line
45, the assertion expects "Financial Times" but NewsFeed.tsx was updated to
display "The Guardian"; update the test to assert for "The Guardian" instead
(replace the expected string in the getByText call) so the test matches the
component change.

{
title: "Energy Sector Stocks Rise on Supply Chain Improvements",
source: "Financial Times",
source: "The Guardian",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Test will fail due to inconsistent data.

The news source was changed from "Financial Times" to "The Guardian", but the test file at client/trading-dashboard/components/__tests__/NewsFeed.test.tsx line 45 still expects "Financial Times". This will cause the test to fail.

Apply this fix to the test file:

-    expect(screen.getByText("Financial Times")).toBeInTheDocument();
+    expect(screen.getByText("The Guardian")).toBeInTheDocument();

Alternatively, revert this change to keep "Financial Times" if there was no intentional reason for the change.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In client/trading-dashboard/components/NewsFeed.tsx around line 52 the news
source was changed to "The Guardian", but the unit test at
client/trading-dashboard/components/__tests__/NewsFeed.test.tsx line 45 still
expects "Financial Times", causing a test failure; update the test expectation
to "The Guardian" to match the component (or revert the component change back to
"Financial Times" if that was unintended) and run tests to confirm the
inconsistency is resolved.

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: 6

🧹 Nitpick comments (5)
client/trading-dashboard/app/not-found.tsx (2)

13-18: Consider server-side logging or error tracking service.

Client-side console.error is only visible in browser developer tools and won't be captured in production logs or monitoring systems. For production error tracking, consider:

  • Using a monitoring service (e.g., Sentry, LogRocket)
  • Server-side logging in middleware
  • Analytics tracking for 404 events

20-51: Consider adding semantic HTML landmark.

Wrap the 404 content in a <main> element to improve document structure and accessibility. This helps screen readers and search engines understand the page hierarchy.

     <div className="flex min-h-screen items-center justify-center bg-gray-900">
+      <main>
       <div className="mx-4 w-full max-w-md rounded-2xl p-8 text-center shadow-xl bg-gray-800/60 backdrop-blur-sm">
         {/* ... content ... */}
       </div>
+      </main>
     </div>
client/trading-dashboard/components/ui/CutomTooltip.tsx (2)

7-7: Replace any type with a more specific Recharts payload type.

Using any reduces type safety and prevents catching potential issues at compile time.

Apply this diff:

-  payload?: ReadonlyArray<any>;
+  payload?: ReadonlyArray<{ value: number; [key: string]: any }>;

Or better yet, import the proper type from Recharts if available.


19-19: Consider memoizing dark mode state to avoid repeated hook calls.

The useDarkMode hook is called on every tooltip render. Since tooltips can render frequently during chart interactions, this could impact performance.

If performance becomes a concern, consider passing isDarkMode as a prop from the parent component rather than calling the hook directly in the tooltip.

client/trading-dashboard/components/TickerGrid.tsx (1)

9-20: Rename getPosts to getTickers for clarity.

The function name doesn't match its purpose, which can confuse maintainers.

Apply this diff:

-async function getPosts(): Promise<Ticker[]> {
+async function getTickers(): Promise<Ticker[]> {
   const res = await fetch(`${API_BASE_URL}/tickers`);
   if (!res.ok) {
-    throw new Error("Failed to fetch posts");
+    throw new Error("Failed to fetch tickers");
   }

And update the queryFn reference on line 24:

-    queryFn: getPosts,
+    queryFn: getTickers,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f6162f and 2c51162.

📒 Files selected for processing (10)
  • client/trading-dashboard/app/not-found.tsx (1 hunks)
  • client/trading-dashboard/components/Header.tsx (1 hunks)
  • client/trading-dashboard/components/NewsFeed.tsx (2 hunks)
  • client/trading-dashboard/components/PriceChart.tsx (3 hunks)
  • client/trading-dashboard/components/TickerCard.tsx (2 hunks)
  • client/trading-dashboard/components/TickerGrid.tsx (4 hunks)
  • client/trading-dashboard/components/ui/CutomTooltip.tsx (1 hunks)
  • client/trading-dashboard/cypress/e2e/home.cy.ts (1 hunks)
  • client/trading-dashboard/cypress/fixtures/ticker-history.json (1 hunks)
  • client/trading-dashboard/cypress/fixtures/tickers.json (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • client/trading-dashboard/cypress/fixtures/tickers.json
  • client/trading-dashboard/cypress/fixtures/ticker-history.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • client/trading-dashboard/components/PriceChart.tsx
🧰 Additional context used
🧬 Code graph analysis (3)
client/trading-dashboard/components/ui/CutomTooltip.tsx (2)
client/trading-dashboard/hooks/userDarkMode.ts (1)
  • useDarkMode (4-32)
client/trading-dashboard/lib/utils.ts (1)
  • formatCurrency (10-17)
client/trading-dashboard/components/TickerCard.tsx (1)
client/trading-dashboard/components/ui/card.tsx (1)
  • Card (85-85)
client/trading-dashboard/components/TickerGrid.tsx (1)
client/trading-dashboard/constants/index.ts (1)
  • MOCK_TICKERS (8-117)
🔇 Additional comments (6)
client/trading-dashboard/components/NewsFeed.tsx (1)

65-65: No action needed for the interval change.

Tests use fake timers but do not verify the auto-refresh behavior or depend on specific timing values. The interval increase from 2 to 5 seconds will not break any existing tests.

client/trading-dashboard/components/Header.tsx (1)

10-10: LGTM! Padding enhancement improves layout.

The horizontal padding addition creates better spacing for the header content.

client/trading-dashboard/components/TickerCard.tsx (1)

9-11: LGTM! Test identifiers follow good naming conventions.

The data-testid attributes enable precise test targeting and follow a consistent pattern with the symbol as a unique key.

Also applies to: 30-30

client/trading-dashboard/components/TickerGrid.tsx (1)

26-26: LGTM! Placeholder data and test ID improve UX and testability.

The placeholderData provides immediate content while fetching, and the data-testid enables reliable E2E testing.

Also applies to: 48-48

client/trading-dashboard/cypress/e2e/home.cy.ts (2)

11-22: LGTM! Comprehensive E2E test coverage.

The test suite effectively validates:

  • Hero section visibility
  • Ticker grid rendering with correct data
  • Price formatting and visual styling (positive/negative indicators)
  • News section presence
  • Responsive behavior across viewports

Also applies to: 24-43, 45-59


4-8: No changes needed to the intercept pattern.

The review comment's concern is incorrect. The API_BASE_URL constant already includes /api/ in its definition ("http://localhost:3005/api"), and the fetch call in TickerGrid.tsx constructs the full URL as ${API_BASE_URL}/tickers, resulting in http://localhost:3005/api/tickers. The intercept pattern **/api/tickers correctly matches this URL and will work as written.

Likely an incorrect or invalid review comment.

@@ -0,0 +1,55 @@
// src/app/not-found.tsx (or your custom 404 file location)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Update the file path comment to match the actual location.

The comment mentions src/app/not-found.tsx, but the actual file path is client/trading-dashboard/app/not-found.tsx. Update the comment to reflect the correct location.

-// src/app/not-found.tsx (or your custom 404 file location)
+// client/trading-dashboard/app/not-found.tsx
📝 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
// src/app/not-found.tsx (or your custom 404 file location)
// client/trading-dashboard/app/not-found.tsx
🤖 Prompt for AI Agents
In client/trading-dashboard/app/not-found.tsx around lines 1 to 1, the
top-of-file comment incorrectly references src/app/not-found.tsx; update that
comment to read client/trading-dashboard/app/not-found.tsx so the file path in
the header matches the actual location, then save the file.

Comment on lines +21 to +22
<div className="flex min-h-screen items-center justify-center bg-gray-900">
<div className="mx-4 w-full max-w-md rounded-2xl p-8 text-center shadow-xl bg-gray-800/60 dark:backdrop-blur-sm">
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix formatting issues and standardize dark mode handling.

Multiple className strings contain double spaces and inconsistent dark mode class usage:

  1. Double spaces (lines 21, 22, 32): Remove extra whitespace for cleaner code
  2. Inconsistent dark mode (lines 22, 36): The component uses a dark theme by default (bg-gray-900, bg-gray-800/60), but some elements conditionally apply dark: prefix classes. Either commit to a dark-only theme or implement proper light/dark mode support consistently across all elements.
  3. Long className strings (lines 28, 44): Consider using a utility like clsx or cn helper for better readability.

Example fixes:

-    <div className="flex min-h-screen items-center justify-center  bg-gray-900">
+    <div className="flex min-h-screen items-center justify-center bg-gray-900">
-      <div className="mx-4 w-full max-w-md rounded-2xl  p-8 text-center shadow-xl bg-gray-800/60 dark:backdrop-blur-sm">
+      <div className="mx-4 w-full max-w-md rounded-2xl p-8 text-center shadow-xl bg-gray-800/60 backdrop-blur-sm">
-        <h2 className="mt-4 text-2xl font-bold  text-gray-100">
+        <h2 className="mt-4 text-2xl font-bold text-gray-100">

Also applies to: 28-28, 32-32, 36-36, 44-44

🤖 Prompt for AI Agents
In client/trading-dashboard/app/not-found.tsx around lines 21-22 (also affecting
lines 28, 32, 36, 44), clean up extra double spaces in className strings, and
standardize dark mode handling: either treat the component as dark-only (remove
inconsistent dark: prefixes and use dark color classes consistently) or
implement proper light/dark support by adding explicit light-mode classes and
using dark: prefixes consistently for dark overrides; also break very long
className strings into a cn/clsx helper call to improve readability and
maintainability.

);
if (error) return notFound();

if (error) return null;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Display error state instead of silently failing.

Returning null on error provides no feedback to users about why tickers aren't loading. This degrades UX when network issues or API failures occur.

Apply this diff to show an error message:

-  if (error) return null;
+  if (error) {
+    return (
+      <div className="py-16 px-4">
+        <div className="container mx-auto max-w-7xl text-center">
+          <p className="text-destructive">Failed to load market data. Please try again later.</p>
+        </div>
+      </div>
+    );
+  }
📝 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
if (error) return null;
if (error) {
return (
<div className="py-16 px-4">
<div className="container mx-auto max-w-7xl text-center">
<p className="text-destructive">Failed to load market data. Please try again later.</p>
</div>
</div>
);
}

Comment on lines +1 to +51
import { FC } from "react";
import { formatCurrency } from "@/lib/utils";
import { useDarkMode } from "@/hooks/userDarkMode";

interface CustomTooltipProps {
active?: boolean;
payload?: ReadonlyArray<any>;
label?: number;
}

/**
* A custom tooltip component for the Recharts AreaChart.
*/
export const CustomTooltip: FC<CustomTooltipProps> = ({
active,
payload,
label,
}) => {
const { isDarkMode } = useDarkMode();
if (active && payload && payload.length && label) {
return (
<div
className={`${
isDarkMode
? "bg-gray-800 border-gray-700"
: "bg-white border-gray-200"
} border rounded-lg shadow-lg p-3`}
>
<p
className={`text-xs ${
isDarkMode ? "text-gray-400" : "text-gray-500"
} mb-1`}
>
{new Date(label).toLocaleDateString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
})}
</p>
<p
className={`text-lg font-semibold ${
isDarkMode ? "text-white" : "text-gray-900"
}`}
>
{formatCurrency(payload[0].value)}
</p>
</div>
);
}
return null;
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix filename typo: "Cutom" → "Custom".

The filename contains a typo that will impact imports and maintainability throughout the codebase.

Rename the file:

git mv client/trading-dashboard/components/ui/CutomTooltip.tsx client/trading-dashboard/components/ui/CustomTooltip.tsx

Then update all imports that reference this file (e.g., in PriceChart.tsx):

-import { CustomTooltip } from "@/components/ui/CutomTooltip";
+import { CustomTooltip } from "@/components/ui/CustomTooltip";
🤖 Prompt for AI Agents
In client/trading-dashboard/components/ui/CutomTooltip.tsx lines 1-51 there is a
filename typo ("CutomTooltip") that will break imports; fix by renaming the file
to CustomTooltip.tsx and updating all import statements across the codebase to
reference the new filename (e.g., replace any occurrences of CutomTooltip with
CustomTooltip), commit the rename so Git tracks it, and run the project
type-check/build to ensure no remaining references fail.

@sushilparajuli sushilparajuli merged commit 14b7155 into main Nov 15, 2025
6 of 7 checks passed
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.

2 participants