useDeploymentMode.test.ts96 lines · main
1import { renderHook } from '@testing-library/react'
2import { beforeEach, describe, expect, test, vi } from 'vitest'
3
4import { useDeploymentMode } from '../useDeploymentMode'
5
6const { mockIsPlatform, mockUseDeploymentModeQuery } = vi.hoisted(() => ({
7 mockIsPlatform: { value: false },
8 mockUseDeploymentModeQuery: vi.fn(),
9}))
10
11vi.mock('@/lib/constants', async () => {
12 const actual = await vi.importActual<Record<string, unknown>>('@/lib/constants')
13 return {
14 ...actual,
15 get IS_PLATFORM() {
16 return mockIsPlatform.value
17 },
18 }
19})
20
21vi.mock('@/data/config/deployment-mode-query', () => ({
22 useDeploymentModeQuery: mockUseDeploymentModeQuery,
23}))
24
25describe('useDeploymentMode', () => {
26 beforeEach(() => {
27 mockIsPlatform.value = false
28 mockUseDeploymentModeQuery.mockReset()
29 })
30
31 test('platform build: returns isPlatform regardless of query state', () => {
32 mockIsPlatform.value = true
33 mockUseDeploymentModeQuery.mockReturnValue({ data: undefined })
34
35 const { result } = renderHook(() => useDeploymentMode())
36
37 expect(result.current).toEqual({
38 isPlatform: true,
39 isCli: false,
40 isSelfHosted: false,
41 })
42 })
43
44 test('non-platform, loading window (data undefined): defaults to CLI', () => {
45 // `?? true` flip — see useDeploymentMode for the asymmetry rationale.
46 // `'direct'` is the only universally-valid method, so CLI-during-loading
47 // is the safe guess that avoids pinning an invalid `connectionMethod`.
48 mockUseDeploymentModeQuery.mockReturnValue({ data: undefined })
49
50 const { result } = renderHook(() => useDeploymentMode())
51
52 expect(result.current).toEqual({
53 isPlatform: false,
54 isCli: true,
55 isSelfHosted: false,
56 })
57 })
58
59 test('non-platform, resolved is_cli_mode=true: CLI', () => {
60 mockUseDeploymentModeQuery.mockReturnValue({ data: { is_cli_mode: true } })
61
62 const { result } = renderHook(() => useDeploymentMode())
63
64 expect(result.current).toEqual({
65 isPlatform: false,
66 isCli: true,
67 isSelfHosted: false,
68 })
69 })
70
71 test('non-platform, resolved is_cli_mode=false: self-hosted', () => {
72 mockUseDeploymentModeQuery.mockReturnValue({ data: { is_cli_mode: false } })
73
74 const { result } = renderHook(() => useDeploymentMode())
75
76 expect(result.current).toEqual({
77 isPlatform: false,
78 isCli: false,
79 isSelfHosted: true,
80 })
81 })
82
83 test('returns a stable reference across renders when primitive flags do not change', () => {
84 // Distinct `data` object refs with equal contents — pins memoization on the
85 // primitive flags (`[isCli, isSelfHosted]`), not on the `data` reference.
86 mockUseDeploymentModeQuery
87 .mockReturnValueOnce({ data: { is_cli_mode: false } })
88 .mockReturnValueOnce({ data: { is_cli_mode: false } })
89
90 const { result, rerender } = renderHook(() => useDeploymentMode())
91 const first = result.current
92 rerender()
93
94 expect(result.current).toBe(first)
95 })
96})