-
Couldn't load subscription status.
- Fork 11
test: create tests for components batch 3 #1374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis 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
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
Suggested reviewers
Poem
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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
wrappervariable 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
📒 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, andrefimports 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.
There was a problem hiding this 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)
📒 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 coverageThe 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 APIsThe 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 approachThe 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 conditionsThese tests comprehensively verify the conditional rendering logic for both prop naming variants (
ssoenabledandssoEnabled) and different value formats (boolean and string), ensuring backward compatibility and proper rendering behavior.
164-186: Effective testing of SSO navigation flowThis test properly verifies the button click behavior, state management in sessionStorage, and URL construction for the SSO redirection flow.
222-258: Comprehensive error handling testThe error test case correctly verifies error display, form visibility, button text changes, and console logging when the SSO flow fails.
There was a problem hiding this 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 callThere'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)
📒 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 approachGood 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 testsThese 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 testThis test effectively verifies the theme change workflow:
- Component selects a new theme
- Form submission is triggered with correct parameters
- The select is disabled during the process
- 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 testExcellent 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 cleanupGood practice using both
vi.runOnlyPendingTimers()andvi.useRealTimers()in the afterEach hook. This ensures no leftover timers affect subsequent tests and restores the original timer behavior.
There was a problem hiding this 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)
📒 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
There was a problem hiding this 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 overheadThe 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 aboveAlso applies to: 93-103
127-128: Empty mock classes trigger linter errors – replace or removeStatic analysis flags the empty
MockEvent/MockMouseEventclasses as “unexpected empty class”.
If you only need the constructor signatures, a simple interface orclass {}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)
📒 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: callingvi.clearAllMocks()erases call history you create right aboveYou 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 insidemountstarts at zero.
If that’s intentional, no action is needed; otherwise, movevi.clearAllMocks()to the very top ofbeforeEachto avoid wiping freshly-created spies.
There was a problem hiding this 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: Moveshallow: falseout ofstubsThe
shallowoption is a top-level configuration option formount(), not a stub component. When placed insidestubs, 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 functionsThe 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 spiesYou 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 withassyntaxThe current casting approach using
as unknown asis 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)
📒 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 cleanupThe 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 declarationsThe 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 testThis 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.
There was a problem hiding this 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: Replaceanytype with a more specific type signature.The
anytype 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 typeweb/__test__/components/UserProfile.test.ts (1)
235-235: Type assertion could be improved for better type safety.The component instance type assertion using
unknownas 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)
📒 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
There was a problem hiding this 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 implementationThe 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 componentCurrent 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 triggersThe 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)
📒 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
There was a problem hiding this 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)
📒 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"andrel="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
ActivationStepsandModalimproves 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.
bfb5e65 to
e550518
Compare
There was a problem hiding this 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 unusedonBeforeMountimport
The static analyzer flagged thatonBeforeMountis 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
onBeforeMounthook:-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 /^_/uweb/__test__/components/UserProfile.test.ts (4)
92-92: Initialize variable without redundant assignmentThe
consoleSpiesvariable is initialized with an empty array but immediately reassigned inbeforeEach. This is unnecessary.- let consoleSpies: Array<ReturnType<typeof vi.spyOn>> = []; + let consoleSpies: Array<ReturnType<typeof vi.spyOn>>;
219-231: Avoid redundant console spy mockingYou'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 accessUsing 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 operatorUsing 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)
📒 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 coverageThis 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.
There was a problem hiding this 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 mockWhile 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 testingBoth 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)
📒 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 mocksThe 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 functionThe 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 contentThis 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 testingThis test correctly verifies the default activeStep behavior when no prop is provided.
89-93: Proper prop value verificationThe test confirms that the component correctly uses the provided activeStep prop value.
95-101: Complete structural verificationThis 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 mockingThe 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 resetThe beforeEach hook correctly resets mocks and state between tests, preventing test interdependencies. The mountComponent helper function is well-structured.
44-58: Comprehensive link attribute verificationThis 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 testingThe test correctly verifies that no elements are rendered when partnerUrl is not present, covering the conditional rendering logic.
69-81: Complete CSS class verificationThis 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 mockingThe 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 preparationThe 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 verificationThese tests verify that the correct title and description texts are used based on partner information, ensuring proper content display.
152-161: Proper conditional rendering testThis 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 testingThese 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 testingThe tests properly verify theme setting behavior and gracefully handle potential errors, including console error spying for validation.
212-245: Comprehensive font size adjustment testingThis 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 testingThese 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 setupThe test correctly mocks both the activation code data store and theme store, allowing controlled testing of reactive state dependencies.
31-44: Clean test initializationThe test suite includes proper state reset in beforeEach and a simple, focused mountComponent helper function.
45-58: Thorough image rendering verificationThis 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 testingThe 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 testsThese 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 setupThe 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 implementationThe 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 mocksThe 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 mockingAll 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 resetThe 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 testsThe 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 testThe 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 testThe 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 testingThe tests for modal visibility and activation steps rendering verify that the component correctly responds to different states and renders the appropriate UI elements.
|
This plugin has been deployed to Cloudflare R2 and is available for testing. |
Summary by CodeRabbit