From e21be9e8fe669b8cd073ce7fccdbfa934898e8ab Mon Sep 17 00:00:00 2001 From: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Date: Mon, 25 May 2026 21:13:04 +0800 Subject: [PATCH] update --- .../__tests__/channels-section.spec.tsx | 84 +++++++++++++++++++ .../__tests__/developer-api-section.spec.tsx | 24 +++++- .../settings-tab/access/channels-section.tsx | 1 + .../access/developer-api-section.tsx | 1 + 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 web/features/deployments/detail/settings-tab/access/__tests__/channels-section.spec.tsx diff --git a/web/features/deployments/detail/settings-tab/access/__tests__/channels-section.spec.tsx b/web/features/deployments/detail/settings-tab/access/__tests__/channels-section.spec.tsx new file mode 100644 index 0000000000..2ef275b571 --- /dev/null +++ b/web/features/deployments/detail/settings-tab/access/__tests__/channels-section.spec.tsx @@ -0,0 +1,84 @@ +import { render, screen } from '@testing-library/react' +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { AccessChannelsSection } from '../channels-section' + +type QueryOptions = { + queryKey?: string[] +} + +type QueryResult = { + data?: unknown + isLoading: boolean + isError: boolean +} + +const mockUseQuery = vi.fn<(options: QueryOptions) => QueryResult>() +let mockUpdateAccessChannelsPending = false + +vi.mock('@tanstack/react-query', () => ({ + useMutation: () => ({ + mutate: vi.fn(), + isPending: mockUpdateAccessChannelsPending, + }), + useQuery: (options: QueryOptions) => mockUseQuery(options), +})) + +vi.mock('@/service/client', () => ({ + consoleQuery: { + enterprise: { + accessService: { + getAccessChannels: { + queryOptions: () => ({ queryKey: ['access-channels'] }), + }, + updateAccessChannels: { + mutationOptions: () => ({ mutationKey: ['update-access-channels'] }), + }, + }, + deploymentService: { + listEnvironmentDeployments: { + queryOptions: () => ({ queryKey: ['environment-deployments'] }), + }, + }, + }, + }, +})) + +function queryResult(overrides: Partial = {}): QueryResult { + return { + data: undefined, + isLoading: false, + isError: false, + ...overrides, + } +} + +describe('AccessChannelsSection', () => { + beforeEach(() => { + vi.clearAllMocks() + mockUpdateAccessChannelsPending = false + mockUseQuery.mockImplementation((options: QueryOptions) => { + switch (options.queryKey?.[0]) { + case 'access-channels': + return queryResult({ data: { accessChannels: { webAppEnabled: false } } }) + case 'environment-deployments': + return queryResult({ data: { data: [] } }) + default: + return queryResult() + } + }) + }) + + it('should show loading feedback on the access channel switch while toggling', () => { + // Arrange + mockUpdateAccessChannelsPending = true + + // Act + const { container } = render() + + // Assert + const switchElement = screen.getByRole('switch') + expect(switchElement).toHaveAttribute('aria-busy', 'true') + expect(switchElement).toHaveAttribute('data-disabled', '') + expect(container.querySelector('.i-ri-loader-2-line')).toBeInTheDocument() + }) +}) diff --git a/web/features/deployments/detail/settings-tab/access/__tests__/developer-api-section.spec.tsx b/web/features/deployments/detail/settings-tab/access/__tests__/developer-api-section.spec.tsx index 176303d23f..19cc98b905 100644 --- a/web/features/deployments/detail/settings-tab/access/__tests__/developer-api-section.spec.tsx +++ b/web/features/deployments/detail/settings-tab/access/__tests__/developer-api-section.spec.tsx @@ -2,7 +2,7 @@ import type { ReactNode } from 'react' import { fireEvent, render, screen, waitFor, within } from '@testing-library/react' import { createStore, Provider as JotaiProvider } from 'jotai' import { beforeEach, describe, expect, it, vi } from 'vitest' -import { DeveloperApiHeaderActions, DeveloperApiSection } from '../developer-api-section' +import { DeveloperApiHeaderActions, DeveloperApiHeaderSwitch, DeveloperApiSection } from '../developer-api-section' type QueryOptions = { queryKey?: string[] @@ -19,6 +19,7 @@ type MutationOptions = { } const mockUseQuery = vi.fn<(options: QueryOptions) => QueryResult>() +let mockUpdateAccessChannelsPending = false vi.mock('@tanstack/react-query', () => ({ useMutation: (options: MutationOptions) => ({ @@ -26,6 +27,9 @@ vi.mock('@tanstack/react-query', () => ({ if (options.mutationKey?.[0] === 'create-api-key') callbacks?.onSuccess?.({ token: 'app-created-token' }) }), + isPending: options.mutationKey?.[0] === 'update-access-channels' + ? mockUpdateAccessChannelsPending + : false, }), useQueries: () => [], useQuery: (options: QueryOptions) => mockUseQuery(options), @@ -80,6 +84,24 @@ function renderWithJotai(node: ReactNode) { describe('DeveloperApiSection', () => { beforeEach(() => { vi.clearAllMocks() + mockUpdateAccessChannelsPending = false + }) + + describe('Header switch', () => { + it('should show loading feedback while toggling developer API access', () => { + // Arrange + mockUpdateAccessChannelsPending = true + mockUseQuery.mockReturnValue(queryResult({ data: { accessChannels: { developerApiEnabled: false } } })) + + // Act + const { container } = render() + + // Assert + const switchElement = screen.getByRole('switch') + expect(switchElement).toHaveAttribute('aria-busy', 'true') + expect(switchElement).toHaveAttribute('data-disabled', '') + expect(container.querySelector('.i-ri-loader-2-line')).toBeInTheDocument() + }) }) // Loading should reserve the same shape as the enabled API key list. diff --git a/web/features/deployments/detail/settings-tab/access/channels-section.tsx b/web/features/deployments/detail/settings-tab/access/channels-section.tsx index 7285e74013..b553aed5c8 100644 --- a/web/features/deployments/detail/settings-tab/access/channels-section.tsx +++ b/web/features/deployments/detail/settings-tab/access/channels-section.tsx @@ -29,6 +29,7 @@ function AccessChannelsSwitch({ appInstanceId, checked, disabled }: { { toggleAccessChannel.mutate({ params: { appInstanceId }, diff --git a/web/features/deployments/detail/settings-tab/access/developer-api-section.tsx b/web/features/deployments/detail/settings-tab/access/developer-api-section.tsx index bdecb8e9fa..01020d2ca0 100644 --- a/web/features/deployments/detail/settings-tab/access/developer-api-section.tsx +++ b/web/features/deployments/detail/settings-tab/access/developer-api-section.tsx @@ -104,6 +104,7 @@ function DeveloperApiSwitch({ appInstanceId, checked, disabled }: { { toggleDeveloperAPI.mutate({ params: { appInstanceId },