Skip to content

Conversation

@mdatelle
Copy link
Contributor

@mdatelle mdatelle commented Apr 29, 2025

Summary by CodeRabbit

  • New Features
    • Added comprehensive unit tests for components including SsoButton, ThemeSwitcher, UpdateOs, UserProfile, WanIpCheck, WelcomeModal, ActivationModal, ActivationPartnerLogo, ActivationPartnerLogoImg, and ActivationSteps.
  • Tests
    • Enhanced existing test suites for ColorSwitcher, DummyServerSwitcher, and I18nHost to improve test isolation, DOM management, and reliability.
  • Style
    • Made minor typographic correction in ActivationModal description text.
  • Refactor
    • Reorganized import statements in several components for improved code clarity.
  • Chores
    • Added necessary imports in multiple components to support Vue Composition API features.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 29, 2025

Walkthrough

This update adds new and enhanced unit tests for several Vue components, focusing on authentication, theming, activation, user profile, and network status. It also introduces minor import order and typographical corrections in related component files, without modifying their core logic or exported entities.

Changes

File(s) Change Summary
web/__test__/components/SsoButton.test.ts, web/__test__/components/ThemeSwitcher.test.ts,
web/__test__/components/UpdateOs.test.ts, web/__test__/components/UserProfile.test.ts,
web/__test__/components/WanIpCheck.test.ts, web/__test__/components/WelcomeModal.test.ts,
web/__test__/components/Activation/ActivationModal.test.ts,
web/__test__/components/Activation/ActivationPartnerLogo.test.ts,
web/__test__/components/Activation/ActivationPartnerLogoImg.test.ts,
web/__test__/components/Activation/ActivationSteps.test.ts,
web/__test__/components/Activation/WelcomeModal.test.ts
Added comprehensive new unit tests for SSO, theme switching, OS updating, user profile, WAN IP check, welcome modal, and activation components. Tests cover rendering, user interaction, async flows, error handling, and store integration.
web/__test__/components/ColorSwitcher.test.ts, web/__test__/components/DummyServerSwitcher.test.ts Enhanced test environment isolation and cleanup by adding setup/teardown logic for DOM elements and timers.
web/__test__/components/I18nHost.test.ts Updated test component template to use the injected i18n object for locale access instead of $i18n.
web/components/SsoButton.ce.vue, web/components/UserProfile.ce.vue,
web/components/WanIpCheck.ce.vue, web/components/Activation/WelcomeModal.ce.vue
Added or updated import statements for Vue composition API functions (computed, ref, onMounted, onBeforeMount, watch, watchEffect). No logic changes.
web/components/UpdateOs.ce.vue Reordered import statements for clarity; no logic or functional changes.
web/components/Activation/ActivationModal.vue Added computed import and corrected typographic apostrophe in a description string.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ComponentTest
  participant VueComponent
  participant Store
  participant MockedAPI

  User->>ComponentTest: Run test
  ComponentTest->>VueComponent: Mount with props/mocks
  VueComponent->>Store: Access or mutate state
  VueComponent->>MockedAPI: Call/mimic API or browser method
  MockedAPI-->>VueComponent: Return mock response
  VueComponent-->>ComponentTest: Emit events/state changes
  ComponentTest->>User: Assert expected outcome
Loading

Suggested reviewers

  • zackspear
  • pujitm

Poem

🎉
New tests arrive with careful might,
Ensuring code behaves just right.
Imports tidy, logic clear,
Bugs and errors disappear!
With every spec and mock in place,
Our codebase shines—a tested space.
🧪✨


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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 sequence diagram to generate a sequence diagram of the changes in 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
Contributor

@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)
web/__test__/components/SsoButton.test.ts (1)

188-227: Unused wrapper variable in successful callback test.

The test successfully verifies the entire SSO callback flow, but the wrapper variable is declared but never used in assertions.

-    const wrapper = mount(SsoButton, {
+    mount(SsoButton, {
       props: { ssoenabled: true },
       global: {
         stubs: { BrandButton: BrandButtonStub },
       },
     });
🧰 Tools
🪛 GitHub Check: Build Web App

[failure] 200-200:
'wrapper' is assigned a value but never used. Allowed unused vars must match /^_/u

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 32c6fe6 and 02e1664.

📒 Files selected for processing (2)
  • web/__test__/components/SsoButton.test.ts (1 hunks)
  • web/components/SsoButton.ce.vue (1 hunks)
🧰 Additional context used
🪛 GitHub Check: Build Web App
web/__test__/components/SsoButton.test.ts

[failure] 200-200:
'wrapper' is assigned a value but never used. Allowed unused vars must match /^_/u

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Test API
  • GitHub Check: Build API
  • GitHub Check: Build API
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (8)
web/components/SsoButton.ce.vue (1)

2-3: Added necessary Vue API imports.

Good addition of the missing computed, onMounted, and ref imports that the component was already using. This makes the dependencies explicit and follows Vue best practices.

web/__test__/components/SsoButton.test.ts (7)

1-21: Well-structured test file setup with clear mocking.

The test file is properly organized with imports, stub components, and mocked dependencies. The ACCOUNT URL mock ensures tests run in isolation from external services.


22-52: Comprehensive mocking of browser APIs.

Excellent job setting up all the necessary browser API mocks for sessionStorage, crypto, location, URL handling, and history. This ensures the component can be fully tested in isolation.


53-90: Clean DOM interaction mocking.

Good approach for mocking form elements and DOM queries. The beforeEach setup ensures tests start with a clean state and consistent mock behavior.


91-95: Proper test cleanup.

The afterEach hook properly restores all mocks, preventing test pollution between test cases.


96-162: Thorough prop handling tests.

These tests properly verify component rendering based on different prop configurations, covering both boolean and string variants of the enabled state as well as the absence of props.


164-186: Solid button click interaction test.

This test effectively verifies the navigation logic, state token generation, and URL construction when the SSO button is clicked.


229-265: Comprehensive error handling test.

Great job testing the error path in the SSO callback, verifying error display, button text updates, and form visibility restoration.

Copy link
Contributor

@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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 02e1664 and 9297e9a.

📒 Files selected for processing (1)
  • web/__test__/components/SsoButton.test.ts (1 hunks)
🧰 Additional context used
🪛 GitHub Check: Build Web App
web/__test__/components/SsoButton.test.ts

[failure] 202-202: test/components/SsoButton.test.ts > SsoButton.ce.vue > handles SSO callback in onMounted hook successfully
AssertionError: expected "spy" to be called with arguments: [ 'sso_state' ]

Received:

Number of calls: 0

test/components/SsoButton.test.ts:202:36

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build API
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (6)
web/__test__/components/SsoButton.test.ts (6)

1-10: Well-structured test file with comprehensive coverage

The test file provides complete coverage for the SsoButton component with proper test organization and clear test cases for conditional rendering, button interaction, and SSO authentication flows.


22-52: Thorough mocking of browser APIs

The test properly mocks all required browser APIs (fetch, sessionStorage, crypto, location, history) that the component interacts with, making the tests reliable and environment-independent.


53-90: Good DOM interaction mocking approach

The mocking of DOM elements and querySelector is well-implemented, making it easy to test the component's DOM interactions without relying on an actual DOM.


96-162: Complete coverage of rendering conditions

These tests comprehensively verify the conditional rendering logic for both prop naming variants (ssoenabled and ssoEnabled) and different value formats (boolean and string), ensuring backward compatibility and proper rendering behavior.


164-186: Effective testing of SSO navigation flow

This test properly verifies the button click behavior, state management in sessionStorage, and URL construction for the SSO redirection flow.


222-258: Comprehensive error handling test

The error test case correctly verifies error display, form visibility, button text changes, and console logging when the SSO flow fails.

Copy link
Contributor

@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 (1)
web/__test__/components/ThemeSwitcher.test.ts (1)

59-60: Consider removing redundant restoreAllMocks call

There's a vi.restoreAllMocks() call in both the beforeEach and afterEach hooks. This is redundant and could potentially lead to unexpected behavior if mocks are created within individual tests. Consider keeping it only in the afterEach hook which is the more conventional place for cleanup.

beforeEach(async () => {
  ThemeSwitcher = (await import('~/components/ThemeSwitcher.ce.vue')).default;

  vi.useFakeTimers();
  vi.clearAllMocks();
-  vi.restoreAllMocks();

  // Rest of the setup...
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between b5a233d and 2b6b7ff.

📒 Files selected for processing (1)
  • web/__test__/components/ThemeSwitcher.test.ts (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
web/__test__/components/ThemeSwitcher.test.ts

[error] 200-200: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Test API
  • GitHub Check: Build API
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (5)
web/__test__/components/ThemeSwitcher.test.ts (5)

116-123: Strong test setup approach

Good practice setting up the component rendering condition once in a nested describe block. This ensures all tests within this context can focus on their specific behaviors without repeating setup code.


125-159: Thorough theme rendering tests

These tests effectively verify component rendering with different inputs:

  • Default theme options
  • Array-based themes
  • JSON string themes

The assertions are clear and comprehensive, ensuring both option count and values are verified.


188-227: Well-structured success path test

This test effectively verifies the theme change workflow:

  1. Component selects a new theme
  2. Form submission is triggered with correct parameters
  3. The select is disabled during the process
  4. Page reload is triggered after a delay

Good use of timer advancement to test async behavior without actual waiting.

🧰 Tools
🪛 Biome (1.9.4)

[error] 200-200: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)


229-271: Comprehensive error handling test

Excellent test coverage for the error scenario. The test verifies:

  • Error logging behavior
  • Global error handler invocation
  • Error message content
  • UI state maintenance (select remains disabled)
  • No page reload occurs

The thorough verification ensures robust error handling in the component.


76-80: Best practice for timer cleanup

Good practice using both vi.runOnlyPendingTimers() and vi.useRealTimers() in the afterEach hook. This ensures no leftover timers affect subsequent tests and restores the original timer behavior.

Copy link
Contributor

@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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between a9711c4 and 916fba3.

📒 Files selected for processing (2)
  • web/__test__/components/UserProfile.test.ts (1 hunks)
  • web/components/UserProfile.ce.vue (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
web/__test__/components/UserProfile.test.ts

[error] 127-127: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)


[error] 130-132: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

🪛 GitHub Check: Build Web App
web/__test__/components/UserProfile.test.ts

[failure] 3-3:
Imports "VueWrapper" are only used as type


[failure] 19-19:
'source' is defined but never used. Allowed unused args must match /^_/u


[failure] 105-105:
Unexpected any. Specify a different type


[failure] 109-109:
Unexpected any. Specify a different type


[failure] 126-126:
Unexpected class with only a constructor


[failure] 127-127:
Useless constructor


[failure] 127-127:
'type' is defined but never used. Allowed unused args must match /^_/u


[failure] 127-127:
'options' is defined but never used. Allowed unused args must match /^_/u


[failure] 130-130:
Useless constructor

web/components/UserProfile.ce.vue

[failure] 2-2:
'computed' is defined but never used. Allowed unused vars must match /^_/u

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Build API
  • GitHub Check: Test API
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (1)
web/__test__/components/UserProfile.test.ts (1)

1-359: The test suite is comprehensive and well-structured.

Great work on creating a thorough test suite for the UserProfile component. The tests cover all the key functionality including:

  • Initial rendering
  • Server store interaction
  • Clipboard functionality
  • Conditional rendering based on store state
  • Error handling

The use of mocks for child components, stores, and browser APIs helps isolate the component for testing.

🧰 Tools
🪛 Biome (1.9.4)

[error] 127-127: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)


[error] 130-132: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

🪛 GitHub Check: Build Web App

[failure] 3-3:
Imports "VueWrapper" are only used as type


[failure] 19-19:
'source' is defined but never used. Allowed unused args must match /^_/u


[failure] 105-105:
Unexpected any. Specify a different type


[failure] 109-109:
Unexpected any. Specify a different type


[failure] 126-126:
Unexpected class with only a constructor


[failure] 127-127:
Useless constructor


[failure] 127-127:
'type' is defined but never used. Allowed unused args must match /^_/u


[failure] 127-127:
'options' is defined but never used. Allowed unused args must match /^_/u


[failure] 130-130:
Useless constructor

Copy link
Contributor

@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 (2)
web/__test__/components/UserProfile.test.ts (2)

45-63: Duplicate stubs add maintenance overhead

The same child components are stubbed twice: once via vi.mock(...) (lines 45-63) and again as local constants (lines 93-103).
Keeping only one of these mechanisms is enough and reduces noise.

Possible fix – drop the local constants and reference the already-mocked components:

-const UpcUptimeExpire = { /* … */ }
-const UpcServerState  = { /* … */ }
-const NotificationsSidebar = { /* … */ }
-const UpcDropdownMenu = { /* … */ }
-const UpcDropdownTrigger = { /* … */ }
-
-// …
-        stubs: {
-          UpcUptimeExpire,
-          UpcServerState,
-          NotificationsSidebar,
-          UpcDropdownMenu,
-          UpcDropdownTrigger,
+// …
+        stubs: {},          // child imports are already vi.mock-ed above

Also applies to: 93-103


127-128: Empty mock classes trigger linter errors – replace or remove

Static analysis flags the empty MockEvent / MockMouseEvent classes as “unexpected empty class”.
If you only need the constructor signatures, a simple interface or class {} is sufficient; otherwise, fall back to the native classes directly.

-// Define mock Event classes
-class MockEvent {}
-class MockMouseEvent extends MockEvent {}
+// Use native classes when available, otherwise minimal shim
+class MockEvent {}            // eslint-disable-line @typescript-eslint/no-extraneous-class
+class MockMouseEvent extends MockEvent {}

Or remove them entirely and rely on the real browser classes provided by js-dom.

🧰 Tools
🪛 GitHub Check: Build Web App

[failure] 127-127:
Unexpected empty class

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 916fba3 and fc2761b.

📒 Files selected for processing (2)
  • web/__test__/components/UserProfile.test.ts (1 hunks)
  • web/components/UserProfile.ce.vue (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/components/UserProfile.ce.vue
🧰 Additional context used
🧬 Code Graph Analysis (1)
web/__test__/components/UserProfile.test.ts (3)
web/types/server.ts (1)
  • ServerconnectPluginInstalled (36-36)
web/store/server.ts (1)
  • useServerStore (61-1399)
web/store/theme.ts (1)
  • useThemeStore (18-128)
🪛 GitHub Check: Build Web App
web/__test__/components/UserProfile.test.ts

[failure] 127-127:
Unexpected empty class

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Test API
  • GitHub Check: Build API
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (1)
web/__test__/components/UserProfile.test.ts (1)

170-176: Minor: calling vi.clearAllMocks() erases call history you create right above

You spy on serverStore.setServer (line 171) and then immediately clear all mocks (line 176).
This keeps the spy in place but resets its call counters, so the first invocation inside mount starts at zero.
If that’s intentional, no action is needed; otherwise, move vi.clearAllMocks() to the very top of beforeEach to avoid wiping freshly-created spies.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
web/__test__/components/UserProfile.test.ts (1)

187-196: Move shallow: false out of stubs

The shallow option is a top-level configuration option for mount(), not a stub component. When placed inside stubs, it registers a stub for a component literally named "shallow" rather than controlling the mounting behavior.

      global: {
        plugins: [pinia],
        stubs: {
          UpcUptimeExpire,
          UpcServerState,
          NotificationsSidebar,
          UpcDropdownMenu,
          UpcDropdownTrigger,
-          shallow: false,
        },
+        shallow: false,
      },
🧹 Nitpick comments (3)
web/__test__/components/UserProfile.test.ts (3)

129-130: Simplify mock implementation by using empty functions

The functions should be directly initialized with vi.fn() without unnecessary variable assignments.

-    const MockEvent = vi.fn();
-    const MockMouseEvent = vi.fn();
+    const MockEvent = vi.fn();
+    const MockMouseEvent = vi.fn();

115-122: Consider using a more concise approach for console spies

You can simplify the console spies setup using an array of console methods.

-    consoleSpies = [
-      vi.spyOn(console, 'log').mockImplementation(() => {}),
-      vi.spyOn(console, 'warn').mockImplementation(() => {}),
-      vi.spyOn(console, 'debug').mockImplementation(() => {}),
-      vi.spyOn(console, 'info').mockImplementation(() => {}),
-      vi.spyOn(console, 'error').mockImplementation(() => {}),
-    ];
+    const consoleMethods = ['log', 'warn', 'debug', 'info', 'error'];
+    consoleSpies = consoleMethods.map(method => 
+      vi.spyOn(console, method as keyof Console).mockImplementation(() => {})
+    );

263-263: Use proper TypeScript casting with as syntax

The current casting approach using as unknown as is verbose and potentially risky. Consider defining the expected component instance type or accessing methods more directly.

-    const copyLanIpSpy = vi.spyOn(wrapper.vm as unknown as { copyLanIp: () => void }, 'copyLanIp');
+    const copyLanIpSpy = vi.spyOn(wrapper.vm as any, 'copyLanIp');

Alternatively, if you want to maintain more type safety:

type UserProfileInstance = InstanceType<typeof UserProfile> & { copyLanIp: () => void };
const copyLanIpSpy = vi.spyOn(wrapper.vm as UserProfileInstance, 'copyLanIp');
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 19d62e4 and dbe6841.

📒 Files selected for processing (1)
  • web/__test__/components/UserProfile.test.ts (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
web/__test__/components/UserProfile.test.ts

[error] 128-129: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)


[error] 132-135: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build Web App
  • GitHub Check: Build API
  • GitHub Check: Test API
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (3)
web/__test__/components/UserProfile.test.ts (3)

200-205: Good job fixing the global stubs cleanup

The addition of vi.unstubAllGlobals?.() in the afterEach hook correctly addresses the issue with not restoring global stubs after tests, which prevents test pollution.


1-11: Well-structured imports with proper type declarations

The imports are well-organized, with a clear separation between runtime imports and type-only imports. This follows good TypeScript practices.


207-222: Comprehensive initial state test

This test effectively verifies that the component renders correctly based on the provided props and store state, checking both the data values and the presence of child components.

Copy link
Contributor

@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)
web/__test__/components/WanIpCheck.test.ts (1)

42-43: Replace any type with a more specific type signature.

The any type disables type checking, which could lead to unintended behavior or type errors at runtime.

-    url: (...args: any[]) => {
+    url: (...args: string[]) => {
🧰 Tools
🪛 GitHub Check: Build Web App

[failure] 42-42:
Unexpected any. Specify a different type

web/__test__/components/UserProfile.test.ts (1)

235-235: Type assertion could be improved for better type safety.

The component instance type assertion using unknown as an intermediary is not type-safe.

-    const copyLanIpSpy = vi.spyOn(wrapper.vm as unknown as { copyLanIp: () => void }, 'copyLanIp');
+    const copyLanIpSpy = vi.spyOn(wrapper.vm as InstanceType<typeof UserProfile>, 'copyLanIp');

Same applies to line 256.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 168a285 and b4a1b00.

📒 Files selected for processing (3)
  • web/__test__/components/UserProfile.test.ts (1 hunks)
  • web/__test__/components/WanIpCheck.test.ts (1 hunks)
  • web/components/WanIpCheck.ce.vue (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • web/components/WanIpCheck.ce.vue
🧰 Additional context used
🪛 GitHub Check: Build Web App
web/__test__/components/WanIpCheck.test.ts

[failure] 42-42:
Unexpected any. Specify a different type

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Build API
  • GitHub Check: Test API
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (12)
web/__test__/components/WanIpCheck.test.ts (4)

1-3: Good job with comprehensive test coverage documentation!

Starting the file with clear documentation about what's being tested provides excellent context.


50-94: Well-structured stub component that isolates test logic.

The WanIpCheckStub component effectively replicates real component behavior while allowing precise control of test conditions. The clean separation of rendering logic for different states (DNS error, loading, fetch error, and IP comparisons) makes tests focused and maintainable.


95-109: Good test setup with proper reset between tests.

The beforeEach hook correctly resets all mocks and test state, preventing test pollution.


111-126: Thorough test coverage for all component states and conditions.

The test suite comprehensively covers all possible component states:

  • Loading state
  • DNS error handling
  • Cached IP usage
  • Fetch error handling
  • Matching IPs display
  • Non-matching IPs with appropriate warnings
  • Remote access mode behavior

Each test validates both the presence of the correct UI elements and the displayed text content.

Also applies to: 128-140, 142-160, 162-178, 180-198, 200-225, 227-248

web/__test__/components/UserProfile.test.ts (8)

1-15: Well-organized imports with proper type imports.

Good job using type imports for better code organization and following TypeScript best practices.


16-36: Excellent mock implementation for clipboard functionality.

The clipboard mock effectively simulates both successful and unsuccessful clipboard operations, enabling comprehensive testing of the component's copy feature.


109-110: Good simplification of mock Event objects.

Using vi.fn() instead of classes with constructors is a cleaner approach that avoids the unnecessary constructor issue.


112-126: Proper window stubbing with global restoration.

The window stubbing is well implemented, preserving necessary window properties while overriding just what's needed for testing.


172-177: Complete test cleanup with global unstubbing.

The afterEach hook properly unmounts components, restores mocks, and unstubs globals, preventing test pollution.


179-193: Comprehensive testing of component initialization and prop handling.

The tests thoroughly verify:

  • Initial state rendering
  • Store interaction on mount
  • Support for different prop formats (string/object)
  • Error handling for missing props

Also applies to: 195-199, 201-216, 218-232


234-253: Thorough testing of clipboard functionality.

The tests effectively verify clipboard behavior in multiple scenarios:

  • Successful copy operations show confirmation
  • Unsupported clipboard shows appropriate fallback

Also applies to: 255-273


275-295: Good testing of conditional rendering based on store state.

The tests properly verify that UI elements conditionally render based on store state:

  • Description visibility toggles with theme setting
  • Notifications sidebar depends on plugin installation
  • Banner display changes with theme settings

Also applies to: 297-304, 306-330

Copy link
Contributor

@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)
web/__test__/components/WelcomeModal.test.ts (3)

105-124: Improve mock DOM implementation

The test simulates DOM behavior but doesn't clearly show what it's replacing in the actual component. Consider using jsdom or restructuring to make the test relationship to the component clearer.

  it('sets font-size to 62.5% when modal is shown and confirmPassword exists', () => {
+    // Mock document.querySelector for component simulation
+    document.querySelector = mockQuerySelector;
+    document.documentElement.style.setProperty = mockSetProperty;
+
    mockQuerySelector.mockImplementation((selector: string) => {
      if (selector === '#confirmPassword') {
        return { exists: true };
      }
      return null;
    });

    // Call a function that simulates the watchEffect
    const setDocumentFontSize = (showModal = true) => {
      if (showModal && mockQuerySelector('#confirmPassword')) {
        mockSetProperty('font-size', '62.5%');
      } else {
        mockSetProperty('font-size', '100%');
      }
    };

    setDocumentFontSize(true);
    expect(mockSetProperty).toHaveBeenCalledWith('font-size', '62.5%');
  });

66-71: Consider testing the mounted component

Current tests focus on individual functions but don't test the actual component mounting and complete behavior. Consider adding Vue Test Utils to test the full component lifecycle.

+import { mount } from '@vue/test-utils';
+import WelcomeModal from '~/components/WelcomeModal.ce.vue';

 describe('WelcomeModal.ce.vue', () => {
   beforeEach(() => {
     vi.clearAllMocks();
     mockPartnerName.mockReturnValue(null);
     mockPartnerLogo.mockReturnValue(null);
   });
+
+  it('mounts and renders the component correctly', () => {
+    // Mock global properties needed for mounting
+    const wrapper = mount(WelcomeModal, {
+      global: {
+        mocks: {
+          $store: {
+            useServerStore: () => ({
+              setServer: mockSetServer
+            }),
+            useActivationCodeStore: () => ({
+              partnerName: mockPartnerName,
+              partnerLogo: mockPartnerLogo
+            })
+          }
+        }
+      },
+      props: {
+        server: mockServer
+      }
+    });
+    
+    expect(wrapper.exists()).toBe(true);
+    expect(mockSetServer).toHaveBeenCalled();
+  });

162-177: Test actual event triggers

The test simulates the method being called but doesn't test the actual event that would trigger it in the component. Consider testing the click event directly.

  it('hides modal when BrandButton is clicked', () => {
    let showModal = true;

    // Simulate the dropdownHide method from the component
    const dropdownHide = () => {
      showModal = false;
      mockSetProperty('font-size', '100%');
    };

    expect(showModal).toBe(true);

    dropdownHide();

    expect(showModal).toBe(false);
    expect(mockSetProperty).toHaveBeenCalledWith('font-size', '100%');
+
+    // Alternative approach: test the click event directly
+    // This would typically be done when mounting the component
+    // const wrapper = mount(WelcomeModal);
+    // const button = wrapper.find('.brand-button');
+    // button.trigger('click');
+    // expect(wrapper.vm.showModal).toBe(false);
  });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 6800bf5 and d589276.

📒 Files selected for processing (2)
  • web/__test__/components/WelcomeModal.test.ts (1 hunks)
  • web/components/WelcomeModal.ce.vue (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • web/components/WelcomeModal.ce.vue
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build Web App
  • GitHub Check: Build API
  • GitHub Check: Test API
  • GitHub Check: Cloudflare Pages

Copy link
Contributor

@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 (3)
web/__test__/components/Activation/Modal.test.ts (3)

102-134: Text rendering tests could verify URLs as well.

The tests verify text translation but don't check that the documentation links have the correct URLs.

Consider adding assertions for the URLs of the documentation links to ensure they point to the correct resources:

  it('provides documentation links with correct URLs', () => {
-   mount(ActivationModal, {
+   const wrapper = mount(ActivationModal, {
      props: { t: mockT as unknown as ComposerTranslation },
    });

    const licensingText = mockT('More about Licensing');
    const accountsText = mockT('More about Unraid.net Accounts');

    expect(licensingText).toBe('More about Licensing');
    expect(accountsText).toBe('More about Unraid.net Accounts');
+   
+   // Verify the URLs
+   const buttons = wrapper.findAll('[data-testid="brand-button"]');
+   const licensingButton = buttons.find(b => b.text().includes('More about Licensing'));
+   const accountsButton = buttons.find(b => b.text().includes('More about Unraid.net Accounts'));
+   
+   expect(licensingButton.attributes('href')).toBe('https://docs.unraid.net/unraid-os/manual/licensing');
+   expect(accountsButton.attributes('href')).toBe('https://docs.unraid.net/unraid-os/manual/unraid-accounts');
  });

136-147: Partner logo test should also verify the negative case.

The test checks that the partner logo is displayed when available, but doesn't verify it's absent when not available.

Consider adding a test for when the partner logo is not available:

  it('displays the partner logo when available', () => {
    mockActivationCodeStore.partnerLogo.value = 'partner-logo-url';

    const wrapper = mount(ActivationModal, {
      props: { t: mockT as unknown as ComposerTranslation },
    });

    const modalHeader = wrapper.find('[data-testid="modal-header"]');

    expect(modalHeader.exists()).toBe(true);
    expect(wrapper.find('[data-testid="partner-logo"]').exists()).toBe(true);
  });
+
+  it('does not display the partner logo when not available', () => {
+    mockActivationCodeStore.partnerLogo.value = null;
+
+    const wrapper = mount(ActivationModal, {
+      props: { t: mockT as unknown as ComposerTranslation },
+    });
+
+    expect(wrapper.find('[data-testid="partner-logo"]').exists()).toBe(false);
+  });

1-244: Consider adding a test for initial modal visibility.

While there's a test for when the modal is hidden, there's no explicit test verifying that the modal is initially visible when the store value is true.

Consider adding a test to verify the initial visibility:

it('renders the modal when showActivationModal is true', () => {
  mockActivationCodeStore.showActivationModal.value = true;

  const wrapper = mount(ActivationModal, {
    props: { t: mockT as unknown as ComposerTranslation },
  });

  expect(wrapper.find('[data-testid="modal-header"]').exists()).toBe(true);
  expect(wrapper.find('[data-testid="modal-body"]').exists()).toBe(true);
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between eeea3e0 and bfb5e65.

📒 Files selected for processing (5)
  • web/__test__/components/Activation/Modal.test.ts (1 hunks)
  • web/__test__/components/Activation/PartnerLogo.test.ts (1 hunks)
  • web/__test__/components/Activation/PartnerLogoImg.test.ts (1 hunks)
  • web/__test__/components/Activation/Steps.test.ts (1 hunks)
  • web/components/Activation/Modal.vue (4 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
web/__test__/components/Activation/PartnerLogo.test.ts (1)
web/store/activationCode.ts (1)
  • useActivationCodeStore (26-80)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Test API
  • GitHub Check: Build Web App
  • GitHub Check: Build API
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (27)
web/__test__/components/Activation/PartnerLogo.test.ts (3)

1-38: Well-structured test cases for conditional rendering.

The test suite thoroughly verifies the different rendering scenarios based on store values. The mocking approach is clean and efficient.


39-54: Good verification of link attributes.

The test comprehensively checks not only the existence of the link but also all security-related attributes like target="_blank" and rel="noopener noreferrer" which are important for external links.


56-67: Complete test coverage for rendering scenarios.

This test case completes the coverage by testing the third possible state (logo without URL), ensuring all conditional rendering paths are verified.

web/__test__/components/Activation/PartnerLogoImg.test.ts (4)

14-24: Effective store mocking implementation.

The mocks for both stores are well-implemented, providing the necessary reactive references that the component depends on.


27-41: Good test for light mode rendering.

The tests effectively verify both the presence of expected classes and the absence of conditional classes.


43-53: Thorough verification of dark mode styling.

The test properly reconfigures the mock to test the dark mode state and verifies the conditional addition of the 'invert' class.


55-63: Complete test for empty logo URL edge case.

This test ensures the component handles the case when no logo URL is provided, confirming the component doesn't render an img element in this scenario.

web/components/Activation/Modal.vue (6)

2-2: Explicit imports improve code clarity.

Adding explicit imports for Vue composition API functions is a good practice that makes dependencies clearer.


12-13: Well-structured component composition.

Importing and using specialized components like ActivationSteps and Modal improves modularity and reuse.


30-30: Improved text formatting.

Replacing the typographic apostrophe with a straight one ensures consistent text rendering across different environments.


80-80: Proper endpoint for registration redirect.

The redirection to '/Tools/Registration' after activating the Konami code sequence is correctly implemented.


84-90: Proper event cleanup.

The component correctly adds event listeners on mount and removes them on unmount, preventing memory leaks.


94-131: Well-structured modal implementation.

The modal template is well organized with appropriate sections for header, footer, and sub-footer, with clear conditional rendering logic.

web/__test__/components/Activation/Steps.test.ts (6)

11-26: Comprehensive mocking of UI components.

The mock implementations for UI components are well-structured, preserving the essential props and behaviors needed for testing.


35-45: Effective icon component mocking.

Mocking both outline and solid icon variants ensures proper testing of conditional icon rendering.


48-64: Good default state testing.

This test verifies both the content rendering and the default active step value, ensuring the component behaves correctly out of the box.


66-77: Proper props testing.

The test confirms that the component correctly accepts and applies custom props like activeStep.


79-89: Structure validation.

Confirming the exact number of step items is important to ensure the component structure remains consistent.


91-107: Complete content verification.

The test thoroughly verifies all expected content is present, including both titles and descriptions for each step.

web/__test__/components/Activation/Modal.test.ts (8)

1-20: Well-structured test setup with clear organization.

The test file has a clear organization with imports logically grouped, and the mock for translations is implemented properly.


22-38: Good use of ref and mock functions for store testing.

The store mocks are well implemented, using Vue's ref for reactive properties and vitest's mock functions for actions.


40-87: Comprehensive component mocking.

The component mocks are detailed enough to test interactions without depending on their implementation details. The Modal mock is particularly well-done with named slots that match the actual component.


89-100: Good test isolation with proper setup and teardown.

The beforeEach hook correctly resets mocks and store values, and safely handles the window.location reset to ensure test isolation.


149-161: Button click test is well implemented.

The test properly verifies that clicking the "Activate Now" button calls the activate method from the purchase store.


163-217: Thorough testing of the Konami code functionality.

The tests for the Konami code easter egg are comprehensive, covering both the successful sequence and an incorrect sequence.


219-228: Modal visibility test is clear and concise.

The test verifies that the modal is not rendered when the store value is false.


230-243: Steps component test verifies correct active step.

The test confirms that the activation steps component is rendered with the correct active step attribute.

@mdatelle mdatelle marked this pull request as ready for review May 1, 2025 19:27
@mdatelle mdatelle force-pushed the test/create-tests-for-components-batch-3 branch from bfb5e65 to e550518 Compare May 6, 2025 21:17
Copy link
Contributor

@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 (5)
web/components/Activation/WelcomeModal.ce.vue (1)

2-2: Remove or apply the unused onBeforeMount import
The static analyzer flagged that onBeforeMount is imported but never used. To clean up, either drop it from the import list or leverage it to run the theme‐setting logic at the proper lifecycle hook.

Option A – remove the unused import:

-import { computed, onBeforeMount, ref, watchEffect } from 'vue';
+import { computed, ref, watchEffect } from 'vue';

Option B – refactor the IIFE into an onBeforeMount hook:

-import { computed, onBeforeMount, ref, watchEffect } from 'vue';
+import { computed, onBeforeMount, ref, watchEffect } from 'vue';

-(async () => {
-  try {
-    await setTheme();
-  } catch (error) {
-    console.error('Error setting theme:', error);
-  }
-})();
+onBeforeMount(async () => {
+  try {
+    await setTheme();
+  } catch (error) {
+    console.error('Error setting theme:', error);
+  }
+});
🧰 Tools
🪛 GitHub Check: Build Web App

[failure] 2-2:
'onBeforeMount' is defined but never used. Allowed unused vars must match /^_/u

web/__test__/components/UserProfile.test.ts (4)

92-92: Initialize variable without redundant assignment

The consoleSpies variable is initialized with an empty array but immediately reassigned in beforeEach. This is unnecessary.

-  let consoleSpies: Array<ReturnType<typeof vi.spyOn>> = [];
+  let consoleSpies: Array<ReturnType<typeof vi.spyOn>>;

219-231: Avoid redundant console spy mocking

You're creating a new console.error spy here, but console outputs are already mocked in the beforeEach hook. This creates unnecessary complexity.

-    const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
-
     expect(() =>
       mount(UserProfile, {
         props: {},
         global: {
           plugins: [pinia],
           stubs,
         },
       })
     ).toThrow('Server data not present');
-
-    consoleErrorSpy.mockRestore();

235-235: Use a more type-safe approach for component method access

Using type assertion to access component methods bypasses TypeScript's type checking. Consider exposing the method for testing or testing the behavior rather than the implementation.

-    const copyLanIpSpy = vi.spyOn(wrapper.vm as unknown as { copyLanIp: () => void }, 'copyLanIp');
+    // Option 1: Access through wrapper methods
+    const copyLanIpSpy = vi.spyOn(wrapper.vm, 'copyLanIp');
+    
+    // Option 2: Test behavior instead of implementation
+    // Remove this spy and just verify the results

279-279: Avoid non-null assertion operator

Using the ! non-null assertion operator bypasses TypeScript's type checking. Consider checking if the value exists first.

-    serverStore.description = initialServerData.description!;
+    if (initialServerData.description) {
+      serverStore.description = initialServerData.description;
+    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between bfb5e65 and e550518.

📒 Files selected for processing (19)
  • web/__test__/components/Activation/Modal.test.ts (1 hunks)
  • web/__test__/components/Activation/PartnerLogo.test.ts (1 hunks)
  • web/__test__/components/Activation/PartnerLogoImg.test.ts (1 hunks)
  • web/__test__/components/Activation/Steps.test.ts (1 hunks)
  • web/__test__/components/ColorSwitcher.test.ts (2 hunks)
  • web/__test__/components/DummyServerSwitcher.test.ts (3 hunks)
  • web/__test__/components/I18nHost.test.ts (1 hunks)
  • web/__test__/components/SsoButton.test.ts (1 hunks)
  • web/__test__/components/ThemeSwitcher.test.ts (1 hunks)
  • web/__test__/components/UpdateOs.test.ts (1 hunks)
  • web/__test__/components/UserProfile.test.ts (1 hunks)
  • web/__test__/components/WanIpCheck.test.ts (1 hunks)
  • web/__test__/components/WelcomeModal.test.ts (1 hunks)
  • web/components/Activation/ActivationModal.vue (2 hunks)
  • web/components/Activation/WelcomeModal.ce.vue (1 hunks)
  • web/components/SsoButton.ce.vue (1 hunks)
  • web/components/UpdateOs.ce.vue (1 hunks)
  • web/components/UserProfile.ce.vue (1 hunks)
  • web/components/WanIpCheck.ce.vue (1 hunks)
✅ Files skipped from review due to trivial changes (4)
  • web/components/WanIpCheck.ce.vue
  • web/components/UserProfile.ce.vue
  • web/components/UpdateOs.ce.vue
  • web/components/Activation/ActivationModal.vue
🚧 Files skipped from review as they are similar to previous changes (13)
  • web/test/components/I18nHost.test.ts
  • web/components/SsoButton.ce.vue
  • web/test/components/Activation/PartnerLogo.test.ts
  • web/test/components/DummyServerSwitcher.test.ts
  • web/test/components/ColorSwitcher.test.ts
  • web/test/components/Activation/PartnerLogoImg.test.ts
  • web/test/components/ThemeSwitcher.test.ts
  • web/test/components/WanIpCheck.test.ts
  • web/test/components/UpdateOs.test.ts
  • web/test/components/Activation/Steps.test.ts
  • web/test/components/SsoButton.test.ts
  • web/test/components/Activation/Modal.test.ts
  • web/test/components/WelcomeModal.test.ts
🧰 Additional context used
🪛 GitHub Check: Build Web App
web/components/Activation/WelcomeModal.ce.vue

[failure] 2-2:
'onBeforeMount' is defined but never used. Allowed unused vars must match /^_/u

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Build API
  • GitHub Check: Test API
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (1)
web/__test__/components/UserProfile.test.ts (1)

87-331: Great comprehensive test coverage

This test suite thoroughly covers all important aspects of the UserProfile component, including:

  • Rendering and props handling
  • Store interactions
  • Conditional rendering based on different states
  • User interactions with clipboard functionality
  • Error handling

The tests are well-structured with proper setup and teardown, and cover both happy paths and edge cases.

Copy link
Contributor

@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)
web/__test__/components/Activation/ActivationModal.test.ts (2)

114-120: Consider adding cleanup for the event listener mock

While the event listener mock works well for capturing keyboard events, it would be better to restore the original addEventListener after tests complete.

+ const originalRemoveEventListener = window.removeEventListener;
+ 
+ afterAll(() => {
+   window.addEventListener = originalAddEventListener;
+   window.removeEventListener = originalRemoveEventListener;
+ });

200-243: Thorough Konami code sequence testing

Both the successful and unsuccessful Konami code sequence tests are well implemented. Consider making the error messages more specific to help with debugging.

- expect(mockActivationCodeModalStore.setIsHidden).toHaveBeenCalledWith(true);
+ expect(mockActivationCodeModalStore.setIsHidden).toHaveBeenCalledWith(true, 
+   'Konami code should trigger modal hiding');

- expect(mockActivationCodeModalStore.setIsHidden).not.toHaveBeenCalled();
+ expect(mockActivationCodeModalStore.setIsHidden).not.toHaveBeenCalled(
+   'Incorrect sequence should not trigger Konami code action');
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between df06e28 and 13a2c0d.

📒 Files selected for processing (5)
  • web/__test__/components/Activation/ActivationModal.test.ts (1 hunks)
  • web/__test__/components/Activation/ActivationPartnerLogo.test.ts (1 hunks)
  • web/__test__/components/Activation/ActivationPartnerLogoImg.test.ts (1 hunks)
  • web/__test__/components/Activation/ActivationSteps.test.ts (1 hunks)
  • web/__test__/components/Activation/WelcomeModal.test.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build API
  • GitHub Check: Build Web App
  • GitHub Check: Test API
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (33)
web/__test__/components/Activation/ActivationSteps.test.ts (6)

1-57: Well organized test setup with comprehensive mocks

The test file sets up all necessary mocks for UI components and icons, creating isolated test conditions for the ActivationSteps component. The mock implementation details for each component are thorough and include data-testid attributes which make element selection reliable.


58-64: Good test structure with reusable mount function

The test suite has a well-designed mountComponent helper function that encapsulates component creation with props, making the tests more readable and maintainable.


65-81: Thorough verification of component content

This test effectively verifies that all three steps render with the correct titles and descriptions, providing comprehensive coverage of the component's core content.


83-87: Good default prop testing

This test correctly verifies the default activeStep behavior when no prop is provided.


89-93: Proper prop value verification

The test confirms that the component correctly uses the provided activeStep prop value.


95-101: Complete structural verification

This test ensures that separators between steps are correctly rendered, completing the structural verification of the component.

web/__test__/components/Activation/ActivationPartnerLogo.test.ts (5)

1-25: Effective store and component mocking

The test properly mocks both the child component and the reactive store, creating a controlled test environment for the ActivationPartnerLogo component.


26-43: Good test setup with state reset

The beforeEach hook correctly resets mocks and state between tests, preventing test interdependencies. The mountComponent helper function is well-structured.


44-58: Comprehensive link attribute verification

This test thoroughly verifies all important aspects of the rendered link: existence, href value, security attributes (target, rel), and child component rendering.


60-67: Proper negative case testing

The test correctly verifies that no elements are rendered when partnerUrl is not present, covering the conditional rendering logic.


69-81: Complete CSS class verification

This test ensures that all opacity-related CSS classes are applied correctly, covering the styling aspects of the component.

web/__test__/components/Activation/WelcomeModal.test.ts (8)

1-82: Comprehensive setup with thorough mocking

The test file includes well-structured mocks for translations, child components, and stores. The Modal component mock is particularly detailed, including slots and props that enable thorough testing.


83-121: Robust test environment preparation

The test suite includes thorough setup and teardown with fake timers, DOM method mocking, and state reset between tests. The mountComponent helper function properly sets up the component with necessary props and stubs.


122-150: Good text content verification

These tests verify that the correct title and description texts are used based on partner information, ensuring proper content display.


152-161: Proper conditional rendering test

This test confirms that the partner logo is displayed only when partner information is available, validating the conditional rendering logic.


162-188: Complete interaction and state testing

These tests verify button click behavior, disabled state during loading, and proper rendering of activation steps with the correct step value.


190-210: Thorough theme handling and error testing

The tests properly verify theme setting behavior and gracefully handle potential errors, including console error spying for validation.


212-245: Comprehensive font size adjustment testing

This test group thoroughly verifies font size adjustment logic based on DOM state and component lifecycle, including proper cleanup when the modal is hidden.


247-273: Complete modal configuration and accessibility testing

These tests ensure that all modal properties are correctly set and that proper accessibility attributes are applied, supporting a11y requirements.

web/__test__/components/Activation/ActivationPartnerLogoImg.test.ts (5)

1-30: Proper store mocking setup

The test correctly mocks both the activation code data store and theme store, allowing controlled testing of reactive state dependencies.


31-44: Clean test initialization

The test suite includes proper state reset in beforeEach and a simple, focused mountComponent helper function.


45-58: Thorough image rendering verification

This test confirms that the image is rendered with the correct source and CSS class when partner logo information is available.


59-64: Good negative case testing

The test verifies that no image is rendered when the partner logo URL is null, covering the conditional rendering logic.


66-104: Comprehensive dark mode styling tests

These tests thoroughly verify the application of the 'invert' class under various combinations of dark mode and partner logo availability, ensuring proper theme-dependent styling.

web/__test__/components/Activation/ActivationModal.test.ts (9)

1-13: Well-structured component test setup

The test file begins with clear imports and proper organization. Good job on documenting the purpose of the test file in the header comments.


14-55: Comprehensive mock components implementation

The mock implementation of components is thorough and covers all required functionality for testing. I particularly like the detailed Modal component mock that includes all relevant props and slots.


57-80: Well-designed store mocks

The store mocks effectively simulate the behavior needed for testing, including reactive references and function mocks. This allows for proper isolation of the component under test.


81-113: Complete dependency mocking

All necessary dependencies are properly mocked, including i18n, component stores, and icons. This ensures the tests run in isolation without external dependencies.


122-150: Good test suite setup with proper state reset

The beforeEach block effectively resets the state between tests, and the mountComponent helper function provides a clean way to instantiate the component consistently.


151-176: Effective text content verification tests

The tests for title, description, and documentation links verify that the component renders the expected text content. This is important for ensuring the user interface communicates correctly.


178-188: Good conditional rendering test

The test for partner logo display properly verifies conditional rendering based on store state. This ensures the component correctly responds to different application states.


189-198: Effective user interaction test

The test for the Activate Now button click verifies that user interactions trigger the expected actions. This is crucial for ensuring the component's interactive elements work as intended.


245-257: Complete component state testing

The tests for modal visibility and activation steps rendering verify that the component correctly responds to different states and renders the appropriate UI elements.

@github-actions
Copy link
Contributor

github-actions bot commented May 7, 2025

This plugin has been deployed to Cloudflare R2 and is available for testing.
Download it at this URL:

https://preview.dl.unraid.net/unraid-api/tag/PR1374/dynamix.unraid.net.plg

@mdatelle mdatelle merged commit a5f48da into main May 7, 2025
9 checks passed
@mdatelle mdatelle deleted the test/create-tests-for-components-batch-3 branch May 7, 2025 20:21
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