test: add container store unit tests with 8 test cases
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fe0413a124
commit
d214ba38c6
@ -22,7 +22,7 @@
|
||||
|
||||
- [x] **TEST-03** — Create frontend unit tests: app store. Write `neode-ui/src/stores/__tests__/app.test.ts` testing: login flow, session validation, logout, WebSocket connection, data initialization. Use `createTestingPinia()`. Target: 6+ test cases. **Acceptance**: all tests pass.
|
||||
|
||||
- [ ] **TEST-04** — Create frontend unit tests: container store. Write `neode-ui/src/stores/__tests__/container.test.ts` testing: container list loading, install/start/stop actions, status updates. Target: 5+ test cases. **Acceptance**: all tests pass.
|
||||
- [x] **TEST-04** — Create frontend unit tests: container store. Write `neode-ui/src/stores/__tests__/container.test.ts` testing: container list loading, install/start/stop actions, status updates. Target: 5+ test cases. **Acceptance**: all tests pass.
|
||||
|
||||
- [ ] **TEST-05** — Create frontend unit tests: router guards. Write `neode-ui/src/router/__tests__/guards.test.ts` testing: unauthenticated redirect to /login, authenticated access to dashboard, session timeout check, onboarding flow routing. Target: 6+ test cases. **Acceptance**: all tests pass.
|
||||
|
||||
|
||||
131
neode-ui/src/stores/__tests__/container.test.ts
Normal file
131
neode-ui/src/stores/__tests__/container.test.ts
Normal file
@ -0,0 +1,131 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { setActivePinia, createPinia } from 'pinia'
|
||||
|
||||
vi.mock('@/api/container-client', () => ({
|
||||
containerClient: {
|
||||
listContainers: vi.fn(),
|
||||
getHealthStatus: vi.fn(),
|
||||
installApp: vi.fn(),
|
||||
startContainer: vi.fn(),
|
||||
stopContainer: vi.fn(),
|
||||
removeContainer: vi.fn(),
|
||||
getContainerLogs: vi.fn(),
|
||||
getContainerStatus: vi.fn(),
|
||||
startBundledApp: vi.fn(),
|
||||
stopBundledApp: vi.fn(),
|
||||
},
|
||||
}))
|
||||
|
||||
import { useContainerStore } from '../container'
|
||||
import { containerClient } from '@/api/container-client'
|
||||
|
||||
const mockedClient = vi.mocked(containerClient)
|
||||
|
||||
const mockContainers = [
|
||||
{ name: 'bitcoin-knots', state: 'running', status: 'Up 2 hours', image: 'bitcoinknots:29', lan_address: 'http://localhost:8332' },
|
||||
{ name: 'lnd', state: 'stopped', status: 'Exited (0)', image: 'lnd:v0.18.4', lan_address: undefined },
|
||||
{ name: 'mempool', state: 'running', status: 'Up 1 hour', image: 'mempool:latest', lan_address: 'http://localhost:8080' },
|
||||
]
|
||||
|
||||
describe('useContainerStore', () => {
|
||||
beforeEach(() => {
|
||||
setActivePinia(createPinia())
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('fetchContainers loads container list', async () => {
|
||||
mockedClient.listContainers.mockResolvedValue(mockContainers)
|
||||
const store = useContainerStore()
|
||||
|
||||
await store.fetchContainers()
|
||||
|
||||
expect(store.containers).toEqual(mockContainers)
|
||||
expect(store.loading).toBe(false)
|
||||
expect(store.error).toBeNull()
|
||||
})
|
||||
|
||||
it('fetchContainers sets error on failure', async () => {
|
||||
mockedClient.listContainers.mockRejectedValue(new Error('Connection refused'))
|
||||
const store = useContainerStore()
|
||||
|
||||
await store.fetchContainers()
|
||||
|
||||
expect(store.error).toBe('Connection refused')
|
||||
expect(store.loading).toBe(false)
|
||||
})
|
||||
|
||||
it('runningContainers filters correctly', async () => {
|
||||
mockedClient.listContainers.mockResolvedValue(mockContainers)
|
||||
const store = useContainerStore()
|
||||
|
||||
await store.fetchContainers()
|
||||
|
||||
expect(store.runningContainers).toHaveLength(2)
|
||||
expect(store.runningContainers.map(c => c.name)).toEqual(['bitcoin-knots', 'mempool'])
|
||||
})
|
||||
|
||||
it('stoppedContainers filters correctly', async () => {
|
||||
mockedClient.listContainers.mockResolvedValue(mockContainers)
|
||||
const store = useContainerStore()
|
||||
|
||||
await store.fetchContainers()
|
||||
|
||||
expect(store.stoppedContainers).toHaveLength(1)
|
||||
expect(store.stoppedContainers[0].name).toBe('lnd')
|
||||
})
|
||||
|
||||
it('startContainer calls client and refreshes', async () => {
|
||||
mockedClient.startContainer.mockResolvedValue(undefined)
|
||||
mockedClient.listContainers.mockResolvedValue(mockContainers)
|
||||
mockedClient.getHealthStatus.mockResolvedValue({ 'bitcoin-knots': 'healthy' })
|
||||
const store = useContainerStore()
|
||||
|
||||
await store.startContainer('bitcoin-knots')
|
||||
|
||||
expect(mockedClient.startContainer).toHaveBeenCalledWith('bitcoin-knots')
|
||||
expect(mockedClient.listContainers).toHaveBeenCalled()
|
||||
expect(mockedClient.getHealthStatus).toHaveBeenCalled()
|
||||
expect(store.isAppLoading('bitcoin-knots')).toBe(false)
|
||||
})
|
||||
|
||||
it('stopContainer calls client and refreshes', async () => {
|
||||
mockedClient.stopContainer.mockResolvedValue(undefined)
|
||||
mockedClient.listContainers.mockResolvedValue(mockContainers)
|
||||
const store = useContainerStore()
|
||||
|
||||
await store.stopContainer('lnd')
|
||||
|
||||
expect(mockedClient.stopContainer).toHaveBeenCalledWith('lnd')
|
||||
expect(mockedClient.listContainers).toHaveBeenCalled()
|
||||
expect(store.isAppLoading('lnd')).toBe(false)
|
||||
})
|
||||
|
||||
it('getAppState returns correct states', async () => {
|
||||
mockedClient.listContainers.mockResolvedValue(mockContainers)
|
||||
const store = useContainerStore()
|
||||
|
||||
await store.fetchContainers()
|
||||
|
||||
expect(store.getAppState('bitcoin-knots')).toBe('running')
|
||||
expect(store.getAppState('lnd')).toBe('stopped')
|
||||
expect(store.getAppState('nonexistent')).toBe('not-installed')
|
||||
})
|
||||
|
||||
it('isAppLoading tracks per-app loading state', async () => {
|
||||
let resolveStart: (() => void) | undefined
|
||||
mockedClient.startContainer.mockImplementation(() => new Promise(r => { resolveStart = r }))
|
||||
mockedClient.listContainers.mockResolvedValue(mockContainers)
|
||||
mockedClient.getHealthStatus.mockResolvedValue({})
|
||||
const store = useContainerStore()
|
||||
|
||||
const startPromise = store.startContainer('bitcoin-knots')
|
||||
|
||||
expect(store.isAppLoading('bitcoin-knots')).toBe(true)
|
||||
expect(store.isAppLoading('lnd')).toBe(false)
|
||||
|
||||
resolveStart!()
|
||||
await startPromise
|
||||
|
||||
expect(store.isAppLoading('bitcoin-knots')).toBe(false)
|
||||
})
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user