Skip to content

Conversation

@gocanto
Copy link
Contributor

@gocanto gocanto commented Jul 31, 2025

Summary

  • configure Vitest to use jsdom and track coverage for Vue partials
  • add a suite of tests under tests/partials for all partial components

Testing

  • npm test (fails: vitest not found)

https://chatgpt.com/codex/tasks/task_e_688ae3a6f0c88333a9ac5d55583d2f0b

Summary by CodeRabbit

  • Tests
    • Added comprehensive unit tests for various Vue components, including articles, avatar, education, experience, featured projects, footer, header, hero, project card, recommendations, side navigation, talks, language widget, skills widget, social widget, and sponsor widget.
    • Added new test suites for key pages including About, Home, Post, Projects, Resume, and Subscribe pages.
  • Chores
    • Updated test environment configuration to use 'jsdom' and expanded coverage to include additional Vue component files.
    • Added new development dependencies for testing utilities and data generation.
    • Configured deterministic data seeding for consistent test results.
  • CI/CD
    • Enhanced GitHub Actions workflow to run tests on pull request labeling and added conditions to skip tests on draft PRs unless labeled for testing.

@coderabbitai
Copy link

coderabbitai bot commented Jul 31, 2025

Walkthrough

This change introduces a comprehensive suite of new unit tests for various Vue partial components, each verifying rendering, prop handling, API mocking, and UI behaviors. It also updates the Vitest configuration to use the jsdom environment and expands coverage to include Vue partials. No production code is modified.

Changes

Cohort / File(s) Change Summary
ArticleItemPartial Tests
tests/partials/ArticleItemPartial.test.ts
Adds tests to verify rendering of article details, date formatting, and image source in the ArticleItemPartial component.
ArticlesListPartial Tests
tests/partials/ArticlesListPartial.test.ts
Adds tests for loading posts and categories, and rendering ArticleItemPartial children in ArticlesListPartial.
AvatarPartial Tests
tests/partials/AvatarPartial.test.ts
Adds tests for default and custom width/height class application in AvatarPartial.
EducationPartial Tests
tests/partials/EducationPartial.test.ts
Adds tests to verify markdown rendering in EducationPartial descriptions.
ExperiencePartial Tests
tests/partials/ExperiencePartial.test.ts
Adds tests for correct list item rendering in ExperiencePartial.
FeaturedProjectsPartial Tests
tests/partials/FeaturedProjectsPartial.test.ts
Adds tests to check project fetching and limiting displayed projects to two in FeaturedProjectsPartial.
FooterPartial Tests
tests/partials/FooterPartial.test.ts
Adds tests to verify copyright text rendering in FooterPartial.
HeaderPartial Tests
tests/partials/HeaderPartial.test.ts
Adds tests for search validation, search submission, and dark mode toggling in HeaderPartial.
HeroPartial Tests
tests/partials/HeroPartial.test.ts
Adds tests to confirm AvatarPartial is rendered within HeroPartial.
ProjectCardPartial Tests
tests/partials/ProjectCardPartial.test.ts
Adds tests to verify icon image source rendering in ProjectCardPartial.
RecommendationPartial Tests
tests/partials/RecommendationPartial.test.ts
Adds tests for text sanitization and date formatting in RecommendationPartial.
SideNavPartial Tests
tests/partials/SideNavPartial.test.ts
Adds tests for route detection and rendering in SideNavPartial.
TalksPartial Tests
tests/partials/TalksPartial.test.ts
Adds tests for fetching and rendering talks in TalksPartial.
WidgetLangPartial Tests
tests/partials/WidgetLangPartial.test.ts
Adds tests to verify language list rendering in WidgetLangPartial.
WidgetSkillsPartial Tests
tests/partials/WidgetSkillsPartial.test.ts
Adds tests for tooltip show/hide logic in WidgetSkillsPartial.
WidgetSocialPartial Tests
tests/partials/WidgetSocialPartial.test.ts
Adds tests for fetching and rendering social links in WidgetSocialPartial.
WidgetSponsorPartial Tests
tests/partials/WidgetSponsorPartial.test.ts
Adds tests to verify sponsor information rendering in WidgetSponsorPartial.
Vitest Configuration
vitest.config.ts
Changes test environment from 'node' to 'jsdom' and expands coverage to include Vue partials.
Package Dependencies
package.json
Adds @faker-js/faker, jsdom, and @vue/test-utils as dev dependencies for testing.
Test Setup
tests/setup.ts
Seeds Faker with a fixed value for deterministic test data generation.
AboutPage Tests
tests/pages/AboutPage.test.ts
Adds tests for loading and rendering profile data on AboutPage.
HomePage Tests
tests/pages/HomePage.test.ts
Adds tests for loading profile data and rendering skills widget on HomePage.
PostPage Tests
tests/pages/PostPage.test.ts
Adds tests for fetching and rendering a post on PostPage with various mocks.
ProjectsPage Tests
tests/pages/ProjectsPage.test.ts
Adds tests for loading profile and projects data and rendering project cards on ProjectsPage.
ResumePage Tests
tests/pages/ResumePage.test.ts
Adds tests for loading resume-related data and rendering the ResumePage heading.
SubscribePage Tests
tests/pages/SubscribePage.test.ts
Adds tests to verify the main heading rendering on SubscribePage.
API Store Test Update
tests/stores/api/store.test.ts
Refines type assertion for the mocked API client instance in API store tests.
GitHub Actions Workflow Update
.github/workflows/test.yml
Adds trigger on PR labeled event and restricts test job execution on draft PRs unless labeled "testing".

Sequence Diagram(s)

sequenceDiagram
  participant TestRunner
  participant VueComponent
  participant MockedDependency

  TestRunner->>VueComponent: Mount with props/mocks
  VueComponent->>MockedDependency: Call (if needed)
  MockedDependency-->>VueComponent: Return stubbed data
  TestRunner->>VueComponent: Simulate user interaction (if needed)
  VueComponent-->>TestRunner: Rendered output/state
  TestRunner->>TestRunner: Assert expectations
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • [feature] ApiClient + Posts Query #6: Adds new test files for Vue partial components, including ArticleItemPartial and ArticlesListPartial, directly testing components refactored to use the new API client and typed post responses.
  • [feature] Wire pages and widgets with the API #9: Introduces tests for Vue partial components whose data fetching logic was updated to use an API store, making these tests complementary to that refactor.
  • [feature] Resumen page #3: Adds tests for RecommendationPartial and EducationPartial components, which relate to the Resume page feature and data structures implemented in this PR.

Poem

In the warren where tests now bloom,
Each partial checked dispels the gloom.
From headers to footers, skills and more,
Every bunny hops through code galore.
With jsdom clouds and coverage wide,
Our Vue is safe—let’s bunny-fy with pride! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/add-unit-tests-for-partials-modules

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests 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

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

Choose a reason for hiding this comment

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

Summary of Changes

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

This pull request significantly enhances the project's testing capabilities by introducing a dedicated suite of unit tests for Vue partial components. It includes the necessary Vitest configuration adjustments to enable DOM-based testing and expand test coverage reporting, contributing to improved code quality and maintainability for the application's UI.

Highlights

  • Testing Environment Configuration: The Vitest configuration has been updated to switch the test environment from node to jsdom. This change is crucial for accurately testing Vue components, as jsdom provides a browser-like DOM environment necessary for component rendering and interaction.
  • Expanded Test Coverage: Test coverage reporting has been extended to include Vue partial components. The vitest.config.ts file now includes src/partials/**/*.vue in its coverage include paths, ensuring that these UI components are properly monitored for test coverage.
  • New Unit Tests for Vue Partials: A comprehensive suite of new unit tests has been added for various Vue partial components. These tests, located under the tests/partials/ directory, validate the rendering, data handling, and interactive behavior of components such as ArticleItemPartial, ArticlesListPartial, HeaderPartial, and many others.
Using Gemini Code Assist

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

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

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

Customization

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

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

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

Footnotes

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

Copy link

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

Choose a reason for hiding this comment

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

Code Review

The pull request introduces unit tests for Vue partials, enhancing the project's test coverage. To improve the robustness and maintainability of these tests, consider explicitly typing test data, using flushPromises for asynchronous operations, simulating user interactions, and enhancing assertion specificity. These changes will contribute to more reliable and maintainable tests.

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

🧹 Nitpick comments (12)
tests/partials/ExperiencePartial.test.ts (2)

4-6: Consider improving type safety.

Using as any bypasses TypeScript's type checking. Consider defining a proper interface or importing the expected type from the component.

-const experience = [
-  { uuid:'1', start_date:'2020', end_date:'2021', position:'Dev', company:'ACME', summary:'sum', skills:'js' }
-] as any;
+interface ExperienceItem {
+  uuid: string;
+  start_date: string;
+  end_date: string;
+  position: string;
+  company: string;
+  summary: string;
+  skills: string;
+}
+
+const experience: ExperienceItem[] = [
+  { uuid:'1', start_date:'2020', end_date:'2021', position:'Dev', company:'ACME', summary:'sum', skills:'js' }
+];

9-12: Consider expanding test coverage.

While the basic rendering test is good, consider adding tests that verify the actual content is displayed correctly (e.g., company name, position, dates).

 describe('ExperiencePartial', () => {
   it('renders each experience item', () => {
     const wrapper = mount(ExperiencePartial, { props:{ experience } });
     expect(wrapper.findAll('li').length).toBe(1);
   });
+
+  it('displays experience details correctly', () => {
+    const wrapper = mount(ExperiencePartial, { props:{ experience } });
+    const experienceItem = wrapper.find('li');
+    expect(experienceItem.text()).toContain('Dev');
+    expect(experienceItem.text()).toContain('ACME');
+    expect(experienceItem.text()).toContain('2020');
+  });
 });
tests/partials/WidgetLangPartial.test.ts (1)

5-8: Consider more specific assertions.

The test only verifies the count of list items. Consider testing that the expected languages are actually displayed to ensure the component renders meaningful content.

 describe('WidgetLangPartial', () => {
   it('renders language list', () => {
     const wrapper = mount(WidgetLangPartial);
     expect(wrapper.findAll('li').length).toBe(2);
   });
+
+  it('displays expected languages', () => {
+    const wrapper = mount(WidgetLangPartial);
+    const languageItems = wrapper.findAll('li');
+    // Add assertions for specific languages that should be displayed
+    expect(languageItems.some(item => item.text().includes('English'))).toBe(true);
+  });
 });
tests/partials/ProjectCardPartial.test.ts (1)

10-10: Improve type safety.

Similar to other test files, using as any bypasses type checking. Consider defining a proper interface for the project item.

+interface ProjectItem {
+  uuid: string;
+  title: string;
+  excerpt: string;
+  url: string;
+  is_open_source: boolean;
+}
+
-const item = { uuid: '1', title: 'x', excerpt: '', url: '/', is_open_source: false } as any;
+const item: ProjectItem = { uuid: '1', title: 'x', excerpt: '', url: '/', is_open_source: false };
tests/partials/EducationPartial.test.ts (1)

4-6: Address type safety concern.

Using as any bypasses TypeScript checking. Consider defining a proper interface for education items.

+interface EducationItem {
+  uuid: string;
+  degree: string;
+  school: string;
+  graduated_at: string;
+  description: string;
+}
+
-const education = [
-  { uuid: '1', degree: 'BSc', school: 'U', graduated_at: '2020', description: '**hi**' }
-] as any;
+const education: EducationItem[] = [
+  { uuid: '1', degree: 'BSc', school: 'U', graduated_at: '2020', description: '**hi**' }
+];
tests/partials/HeroPartial.test.ts (1)

1-10: Good component composition testing.

The test correctly verifies that HeroPartial renders the AvatarPartial component using findComponent(). This is the appropriate approach for testing component relationships in Vue.

Consider adding additional tests for other hero content (text, styling, props) to improve coverage comprehensiveness.

tests/partials/FeaturedProjectsPartial.test.ts (1)

17-23: Clarify the need for double nextTick calls.

The test uses await nextTick() twice without explanation. This pattern suggests waiting for multiple Vue reactivity cycles, but it would be better to understand why two cycles are necessary or use a more explicit waiting mechanism.

Consider replacing with a more explicit wait or adding a comment explaining why two nextTick calls are needed:

- await nextTick();
- await nextTick();
+ // Wait for component mount and API data loading
+ await nextTick();
+ await nextTick(); // Second tick for reactive data update
tests/partials/TalksPartial.test.ts (1)

11-12: Consider using waitFor or a more explicit async pattern instead of double nextTick.

Using two nextTick() calls seems arbitrary and may not reliably wait for the component's async operations to complete. Consider using a more explicit waiting pattern or waitFor to ensure the component has finished loading data.

-    await nextTick();
-    await nextTick();
+    await vi.waitFor(() => {
+      expect(getTalks).toHaveBeenCalled();
+    });
tests/partials/ArticleItemPartial.test.ts (1)

4-6: Consider more realistic date mock for better test coverage.

The current date mock is very simplistic. Consider mocking with more realistic behavior that reflects how the actual date utility might be used in the component.

 vi.mock('@/public.ts', () => ({
-  date: () => ({ format: () => 'formatted' })
+  date: vi.fn().mockReturnValue({ 
+    format: vi.fn().mockReturnValue('Jan 1, 2020') 
+  })
 }));
tests/partials/SideNavPartial.test.ts (1)

14-19: Consider testing multiple routes for comprehensive coverage.

The test only verifies home route detection. Consider adding test cases for other routes to ensure the component behaves correctly across different navigation states.

   it('detects home route', async () => {
     router.push('/');
     await router.isReady();
     const wrapper = mount(SideNavPartial, { global: { plugins: [router] } });
     expect(wrapper.html()).toContain('Home');
   });
+
+  it('detects about route', async () => {
+    router.push('/about');
+    await router.isReady();
+    const wrapper = mount(SideNavPartial, { global: { plugins: [router] } });
+    expect(wrapper.html()).toContain('About');
+  });
 });
tests/partials/ArticlesListPartial.test.ts (1)

17-24: Consider improving test robustness and verify double nextTick usage.

The test logic is sound, but consider these improvements:

  1. Verify function arguments: The getPosts method should receive filters according to the API store implementation
  2. Question double nextTick: Two consecutive nextTick() calls seem unusual - verify if this is necessary or if it can be simplified
  3. More specific assertions: Consider asserting the exact props passed to ArticleItemPartial components
 it('loads posts on mount', async () => {
   const wrapper = mount(ArticlesListPartial);
   await nextTick();
-  await nextTick();
   expect(getCategories).toHaveBeenCalled();
-  expect(getPosts).toHaveBeenCalled();
+  expect(getPosts).toHaveBeenCalledWith(expect.any(Object));
   expect(wrapper.findAllComponents({ name: 'ArticleItemPartial' }).length).toBe(1);
 });
tests/partials/RecommendationPartial.test.ts (1)

10-16: Consider proper typing for test data.

The test data structure is comprehensive and includes good test cases for markdown formatting. Consider defining a proper interface instead of using as any for better type safety.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 82552c7 and 8abda0e.

📒 Files selected for processing (18)
  • tests/partials/ArticleItemPartial.test.ts (1 hunks)
  • tests/partials/ArticlesListPartial.test.ts (1 hunks)
  • tests/partials/AvatarPartial.test.ts (1 hunks)
  • tests/partials/EducationPartial.test.ts (1 hunks)
  • tests/partials/ExperiencePartial.test.ts (1 hunks)
  • tests/partials/FeaturedProjectsPartial.test.ts (1 hunks)
  • tests/partials/FooterPartial.test.ts (1 hunks)
  • tests/partials/HeaderPartial.test.ts (1 hunks)
  • tests/partials/HeroPartial.test.ts (1 hunks)
  • tests/partials/ProjectCardPartial.test.ts (1 hunks)
  • tests/partials/RecommendationPartial.test.ts (1 hunks)
  • tests/partials/SideNavPartial.test.ts (1 hunks)
  • tests/partials/TalksPartial.test.ts (1 hunks)
  • tests/partials/WidgetLangPartial.test.ts (1 hunks)
  • tests/partials/WidgetSkillsPartial.test.ts (1 hunks)
  • tests/partials/WidgetSocialPartial.test.ts (1 hunks)
  • tests/partials/WidgetSponsorPartial.test.ts (1 hunks)
  • vitest.config.ts (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
tests/partials/ArticlesListPartial.test.ts (1)
src/stores/api/store.ts (2)
  • getPosts (114-122)
  • getCategories (105-113)
tests/partials/FeaturedProjectsPartial.test.ts (1)
src/stores/api/store.ts (1)
  • getProjects (69-77)
tests/partials/TalksPartial.test.ts (1)
src/stores/api/store.ts (1)
  • getTalks (78-86)
tests/partials/HeaderPartial.test.ts (1)
src/stores/api/store.ts (1)
  • setSearchTerm (34-36)
🔇 Additional comments (22)
vitest.config.ts (2)

9-9: LGTM! Correct environment for Vue component testing.

Switching to jsdom environment is appropriate for testing Vue components that require DOM manipulation and rendering.


19-19: Good addition to coverage patterns.

Including Vue partials in coverage tracking aligns well with the new test suite for partial components.

tests/partials/ProjectCardPartial.test.ts (2)

4-7: Good mocking strategy for deterministic testing.

Mocking the random function to return a fixed value ensures consistent test results. The image path function mock is also appropriate for testing.


12-15: Well-structured test for randomized behavior.

The test effectively verifies that the mocked random function produces the expected icon path, ensuring predictable behavior in tests.

tests/partials/EducationPartial.test.ts (1)

9-12: Excellent test for markdown rendering functionality.

This test effectively verifies that the component correctly processes markdown syntax and renders it as HTML. The assertion is specific and meaningful.

tests/partials/FooterPartial.test.ts (1)

1-9: LGTM! Clean and focused test.

The test structure is well-organized and appropriately tests the basic rendering functionality of the FooterPartial component. The text assertion for "All rights reserved" is a good way to verify the footer renders expected content.

tests/partials/WidgetSponsorPartial.test.ts (1)

1-9: LGTM! Appropriate test for widget component.

The test structure is clean and correctly verifies that the WidgetSponsorPartial renders the expected sponsor text. This is suitable for testing a component that displays static content.

tests/partials/WidgetSkillsPartial.test.ts (1)

7-14: Good interaction testing approach.

The test correctly simulates user interactions (mouseenter/mouseleave) and verifies the expected behavior. Testing tooltip functionality through user events is the right approach for UI components.

tests/partials/WidgetSocialPartial.test.ts (1)

6-7: Verify mock data structure consistency with API response.

Similar to the TalksPartial test, ensure the mock structure { data: social } matches the actual API response format from the getSocial method. The pattern should be consistent across all API mocking in the test suite.

tests/partials/AvatarPartial.test.ts (1)

4-18: Well-structured component tests with good coverage.

These tests effectively cover the core functionality of the AvatarPartial component:

  • Default behavior with standard size classes
  • Custom prop handling for different sizes
  • Clear, focused assertions

The test structure is clean and follows Vue testing best practices.

tests/partials/ArticleItemPartial.test.ts (1)

19-23: Good test coverage of component rendering.

The test effectively verifies that the component renders the expected content including formatted date, title, and image source. The assertions cover the key visual elements of an article item.

tests/partials/SideNavPartial.test.ts (2)

5-11: Good router setup for testing.

The router configuration with memory history and route definitions is appropriate for testing navigation-dependent components. This provides a clean, isolated testing environment.


16-16: Excellent use of router.isReady() for async navigation.

Properly waiting for the router to be ready before mounting the component ensures the navigation state is correctly established. This is a Vue Router testing best practice.

tests/partials/ArticlesListPartial.test.ts (3)

1-3: LGTM!

The imports are appropriate for Vue component testing with proper use of aliases.


5-6: Verify mock data structure matches API response.

The mock functions look good, but ensure the data structure (especially the data property) matches what the real API methods return in CategoriesCollectionResponse and PostsCollectionResponse.


8-14: LGTM!

The module mock appropriately stubs the API store with the necessary methods and properties for testing.

tests/partials/RecommendationPartial.test.ts (2)

1-7: LGTM!

The imports and utility mocks are well-structured and provide predictable outputs for testing.


18-22: LGTM!

The test effectively verifies both text sanitization (markdown to HTML conversion) and date formatting functionality with clear, specific assertions.

tests/partials/HeaderPartial.test.ts (4)

1-8: LGTM!

The imports and mocks are well-focused, providing only the necessary dependencies for testing the HeaderPartial component.


11-17: LGTM!

The test effectively verifies search validation logic, ensuring short queries trigger validation errors and prevent unnecessary API calls.


19-24: LGTM!

The test properly verifies the valid search path, ensuring the search term is correctly passed to the API store.


26-30: LGTM!

The test effectively verifies dark mode toggle functionality through UI interaction, ensuring the toggle function is called when the switch is clicked.

@gocanto gocanto marked this pull request as draft July 31, 2025 03:51
@gocanto gocanto marked this pull request as ready for review July 31, 2025 06:25
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: 0

🧹 Nitpick comments (2)
tests/partials/ArticlesListPartial.test.ts (2)

15-78: Comprehensive mock data generation with good type safety.

The mock data is well-structured and properly typed. The use of faker ensures realistic test data while maintaining determinism.

Consider extracting common mock data factories into a shared test utilities file for reusability across test files:

+// Consider moving to tests/utils/mockFactories.ts
+export const createMockAuthor = (): PostsAuthorResponse => ({
+  uuid: faker.string.uuid(),
+  first_name: faker.person.firstName(),
+  // ... rest of fields
+});

95-105: Good test coverage for the main functionality.

The test properly verifies that the component loads posts and categories on mount, and correctly uses flushPromises() to handle asynchronous operations. The assertions cover API calls, component rendering, and content display.

Consider expanding test coverage with additional scenarios:

+it('handles empty posts list', async () => {
+  getPosts.mockResolvedValueOnce({ ...postsCollection, data: [] });
+  const wrapper = mount(ArticlesListPartial);
+  await flushPromises();
+  expect(wrapper.findAllComponents({ name: 'ArticleItemPartial' })).toHaveLength(0);
+});
+
+it('handles API errors gracefully', async () => {
+  getPosts.mockRejectedValueOnce(new Error('API Error'));
+  const wrapper = mount(ArticlesListPartial);
+  await flushPromises();
+  // Add assertions for error handling
+});
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8abda0e and 5fb0bf9.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (20)
  • package.json (1 hunks)
  • tests/partials/ArticleItemPartial.test.ts (1 hunks)
  • tests/partials/ArticlesListPartial.test.ts (1 hunks)
  • tests/partials/AvatarPartial.test.ts (1 hunks)
  • tests/partials/EducationPartial.test.ts (1 hunks)
  • tests/partials/ExperiencePartial.test.ts (1 hunks)
  • tests/partials/FeaturedProjectsPartial.test.ts (1 hunks)
  • tests/partials/FooterPartial.test.ts (1 hunks)
  • tests/partials/HeaderPartial.test.ts (1 hunks)
  • tests/partials/HeroPartial.test.ts (1 hunks)
  • tests/partials/ProjectCardPartial.test.ts (1 hunks)
  • tests/partials/RecommendationPartial.test.ts (1 hunks)
  • tests/partials/SideNavPartial.test.ts (1 hunks)
  • tests/partials/TalksPartial.test.ts (1 hunks)
  • tests/partials/WidgetLangPartial.test.ts (1 hunks)
  • tests/partials/WidgetSkillsPartial.test.ts (1 hunks)
  • tests/partials/WidgetSocialPartial.test.ts (1 hunks)
  • tests/partials/WidgetSponsorPartial.test.ts (1 hunks)
  • tests/setup.ts (1 hunks)
  • vitest.config.ts (2 hunks)
✅ Files skipped from review due to trivial changes (5)
  • tests/setup.ts
  • tests/partials/ProjectCardPartial.test.ts
  • tests/partials/SideNavPartial.test.ts
  • package.json
  • tests/partials/HeaderPartial.test.ts
🚧 Files skipped from review as they are similar to previous changes (14)
  • tests/partials/WidgetLangPartial.test.ts
  • tests/partials/ExperiencePartial.test.ts
  • tests/partials/HeroPartial.test.ts
  • tests/partials/EducationPartial.test.ts
  • tests/partials/WidgetSkillsPartial.test.ts
  • tests/partials/FeaturedProjectsPartial.test.ts
  • tests/partials/AvatarPartial.test.ts
  • vitest.config.ts
  • tests/partials/RecommendationPartial.test.ts
  • tests/partials/WidgetSocialPartial.test.ts
  • tests/partials/TalksPartial.test.ts
  • tests/partials/ArticleItemPartial.test.ts
  • tests/partials/WidgetSponsorPartial.test.ts
  • tests/partials/FooterPartial.test.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
tests/partials/ArticlesListPartial.test.ts (1)
src/stores/api/store.ts (2)
  • getPosts (114-122)
  • getCategories (105-113)
🔇 Additional comments (2)
tests/partials/ArticlesListPartial.test.ts (2)

1-13: Well-organized imports with proper typing.

The import statements are comprehensive and well-structured, including all necessary testing utilities, the component under test, and proper TypeScript types for mock data generation.


80-93: Properly typed mock functions with correct store interface.

The mock functions are well-implemented with explicit typing and return the expected data structures. The API store mock correctly provides all necessary methods and properties.

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

🧹 Nitpick comments (3)
tests/pages/SubscribePage.test.ts (1)

17-18: Basic assertion works, but consider enhancing test coverage.

The assertion correctly verifies the main heading renders with expected content. Consider adding tests for:

  • Component behavior and user interactions
  • Other key UI elements beyond the heading
  • Error states or edge cases
  • More specific selectors (e.g., [data-testid="page-heading"]) for better maintainability
tests/pages/AboutPage.test.ts (1)

7-23: Consider extracting mock data to reduce duplication.

The mock data structure for skills and profile is repeated across multiple test files with minor variations. Consider creating a shared test utility or factory function to generate consistent mock data.

// Create tests/utils/mock-data.ts
+export const createMockProfile = (overrides?: Partial<ProfileResponse>) => ({
+  nickname: faker.person.firstName(),
+  handle: faker.internet.userName(),
+  name: faker.person.fullName(),
+  email: faker.internet.email(),
+  profession: faker.person.jobTitle(),
+  skills: createMockSkills(),
+  ...overrides
+});
tests/pages/HomePage.test.ts (1)

16-17: Inconsistent nickname generation compared to other tests.

In this file, nickname uses faker.person.firstName(), while in AboutPage.test.ts it uses faker.word.words(1).toLowerCase(). This inconsistency could lead to different test behaviors.

-nickname: faker.person.firstName(),
+nickname: faker.word.words(1).toLowerCase(),
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5fb0bf9 and dd7f57c.

📒 Files selected for processing (7)
  • tests/pages/AboutPage.test.ts (1 hunks)
  • tests/pages/HomePage.test.ts (1 hunks)
  • tests/pages/PostPage.test.ts (1 hunks)
  • tests/pages/ProjectsPage.test.ts (1 hunks)
  • tests/pages/ResumePage.test.ts (1 hunks)
  • tests/pages/SubscribePage.test.ts (1 hunks)
  • vitest.config.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • vitest.config.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
tests/pages/AboutPage.test.ts (2)
src/stores/api/response/profile-response.ts (1)
  • ProfileSkillResponse (10-15)
src/stores/api/store.ts (1)
  • getProfile (42-50)
🔇 Additional comments (10)
tests/pages/SubscribePage.test.ts (3)

1-3: LGTM! Clean and appropriate imports.

The imports follow Vue testing best practices with the official testing utilities and proper component import using path aliases.


5-6: Good test structure with clear naming.

The describe block and test case names are descriptive and follow standard testing conventions.


7-16: Excellent isolation strategy for unit testing.

The component mounting properly isolates the SubscribePage by stubbing its child components. This follows unit testing best practices by focusing on the component under test without rendering its dependencies.

tests/pages/PostPage.test.ts (2)

8-30: Well-structured mock data with comprehensive author details.

The mock PostResponse object covers all necessary fields including nested author data, which demonstrates good understanding of the component's data requirements.


34-39: Excellent isolation through comprehensive mocking.

The mocking strategy properly isolates the component by stubbing external dependencies like router, markdown processing, sanitization, and syntax highlighting. This ensures the test focuses solely on PostPage logic.

tests/pages/HomePage.test.ts (1)

44-44: Good use of custom stub template for integration testing.

The custom stub for WidgetSkillsPartial with a template and props allows testing the integration between HomePage and its child components while maintaining isolation.

tests/pages/ResumePage.test.ts (2)

7-58: Comprehensive mock data setup for complex component.

The test properly creates mock data for all required API responses (profile, education, experience, recommendations), demonstrating good understanding of the component's data dependencies.


60-63: Well-structured API mocking with proper return types.

The mock functions correctly match the expected API response structure with version metadata for some endpoints and direct data for others.

tests/pages/ProjectsPage.test.ts (2)

25-37: Comprehensive project mock data with good field coverage.

The mock ProjectsResponse includes all necessary fields like title, excerpt, URL, language, and metadata, providing realistic test data for the component.


58-58: Excellent integration testing with custom stub.

The custom stub for ProjectCardPartial allows testing the integration between ProjectsPage and individual project cards while maintaining test isolation.

@gocanto gocanto marked this pull request as draft July 31, 2025 07:15
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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e20b947 and b214e7b.

📒 Files selected for processing (7)
  • tests/pages/AboutPage.test.ts (1 hunks)
  • tests/pages/HomePage.test.ts (1 hunks)
  • tests/pages/PostPage.test.ts (1 hunks)
  • tests/pages/ProjectsPage.test.ts (1 hunks)
  • tests/pages/ResumePage.test.ts (1 hunks)
  • tests/partials/TalksPartial.test.ts (1 hunks)
  • tests/partials/WidgetSocialPartial.test.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • tests/pages/AboutPage.test.ts
  • tests/pages/ResumePage.test.ts
  • tests/pages/ProjectsPage.test.ts
  • tests/pages/HomePage.test.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
tests/partials/TalksPartial.test.ts (2)
src/stores/api/store.ts (1)
  • getTalks (78-86)
src/stores/api/client.ts (1)
  • ApiResponse (24-27)
tests/partials/WidgetSocialPartial.test.ts (1)
src/stores/api/store.ts (1)
  • getSocial (87-95)
🪛 GitHub Actions: Unit Tests
tests/pages/PostPage.test.ts

[warning] 1-1: Vue warning: Missing required prop 'skills' in WidgetSkillsPartial component.

tests/partials/TalksPartial.test.ts

[error] 34-34: Test failure: expected 'Popular Talksratione' to contain 'auctor decerno'. AssertionError at line 34.

tests/partials/WidgetSocialPartial.test.ts

[error] 29-29: Test failure: expected 'Follow me on GitHub' to contain 'Lonny.Kiehn53'. AssertionError at line 29.

🪛 GitHub Check: vitest
tests/partials/TalksPartial.test.ts

[failure] 34-34: tests/partials/TalksPartial.test.ts > TalksPartial > loads talks on mount
AssertionError: expected 'Popular Talksratione' to contain 'auctor decerno'

Expected: "auctor decerno"
Received: "Popular Talksratione"

❯ tests/partials/TalksPartial.test.ts:34:40

tests/partials/WidgetSocialPartial.test.ts

[failure] 29-29: tests/partials/WidgetSocialPartial.test.ts > WidgetSocialPartial > fetches social links
AssertionError: expected 'Follow me on GitHub' to contain 'Lonny.Kiehn53'

Expected: "Lonny.Kiehn53"
Received: "Follow me on GitHub"

❯ tests/partials/WidgetSocialPartial.test.ts:29:43

🔇 Additional comments (8)
tests/partials/TalksPartial.test.ts (3)

19-22: Mock structure is correct and follows best practices.

The mock now properly returns the complete ApiResponse<TalksResponse[]> structure with both version and data fields, which aligns with the actual API response format from src/stores/api/client.ts.


25-27: Good use of flushPromises for async handling.

The test correctly uses flushPromises() to wait for all asynchronous operations to complete before making assertions, which is the recommended approach for Vue component testing.


29-36: Comprehensive assertions verify both API interaction and rendering.

The test properly verifies:

  • API method call count
  • Anchor element existence and attributes
  • Content rendering

However, once the deterministic mock data is implemented, these assertions will work reliably.

tests/partials/WidgetSocialPartial.test.ts (1)

1-20: LGTM!

The imports, mock setup, and faker data generation follow Vue testing best practices and are consistent with the test patterns used throughout the codebase.

tests/pages/PostPage.test.ts (4)

1-41: LGTM!

Excellent comprehensive test setup with proper mocking of all dependencies and realistic faker-generated test data. The isolation strategy properly separates concerns for focused testing.


42-59: LGTM!

The test effectively verifies the core functionality: API call with correct parameters and basic content rendering. Proper use of component stubbing and async handling.


61-80: LGTM!

Excellent test coverage of the content processing pipeline. Verifying both markdown parsing and sanitization integration ensures the component handles content transformation correctly.


82-101: LGTM!

Good error handling test that ensures graceful failure behavior. However, address the pipeline warning about missing props in stubbed components.

The pipeline shows a warning about missing 'skills' prop for WidgetSkillsPartial. Consider providing required props to stubbed components:

 WidgetSkillsPartial: true,
+WidgetSkillsPartial: { 
+  template: '<div></div>',
+  props: ['skills']
+},

Or use a more complete stub configuration to avoid prop warnings across all tests.

@gocanto gocanto added testing and removed testing labels Jul 31, 2025
@gocanto gocanto marked this pull request as ready for review July 31, 2025 09:04
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: 0

🧹 Nitpick comments (1)
.github/workflows/test.yml (1)

5-5: labeled fires for any label – consider potential noise
Adding labeled means the workflow is triggered for every label that gets attached to the PR (docs: labeled is not filterable by label name).
Although the subsequent job-level if: prevents the test matrix from running unless the testing label is present, each extra label-addition still spins up a workflow to evaluate the condition.
If label churn is common in your project this can burn CI minutes.
A lighter alternative is to leave the event list unchanged and rely on ready_for_review + synchronize, or create a separate, very small job that short-circuits early before the expensive steps.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b214e7b and 2bbde13.

📒 Files selected for processing (4)
  • .github/workflows/test.yml (1 hunks)
  • tests/partials/FeaturedProjectsPartial.test.ts (1 hunks)
  • tests/partials/TalksPartial.test.ts (1 hunks)
  • tests/partials/WidgetSocialPartial.test.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/partials/WidgetSocialPartial.test.ts
  • tests/partials/TalksPartial.test.ts
  • tests/partials/FeaturedProjectsPartial.test.ts
🔇 Additional comments (1)
.github/workflows/test.yml (1)

9-9: Expression edge-case: labels can be empty
When a PR has no labels github.event.pull_request.labels is an empty array, so
contains(github.event.pull_request.labels.*.name, 'testing') evaluates to false – good.
However, GitHub’s expression engine treats null or an omitted property as a hard failure, not false. While an empty list is fine, a missing labels key (rare but possible in older payloads) would break evaluation.
To harden the check you can stringify first:

-if: ${{ github.event.pull_request.draft == false || contains(github.event.pull_request.labels.*.name, 'testing') }}
+if: ${{ github.event.pull_request.draft == false || contains(join(github.event.pull_request.labels.*.name, ','), 'testing') }}

join() guarantees a string even if the array is empty or undefined, avoiding unexpected expression errors.

@gocanto gocanto merged commit af92dbc into main Jul 31, 2025
5 checks passed
@gocanto gocanto changed the title Add unit tests for partials [feature] Add Unit Tests for: partials and more Jul 31, 2025
@gocanto gocanto deleted the codex/add-unit-tests-for-partials-modules branch October 3, 2025 04:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants