File size: 3,414 Bytes
5539271
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useDocumentStore } from './store'

vi.mock('./api', () => ({
  fetchDocuments: vi.fn(),
  uploadDocument: vi.fn(),
  deleteDocument: vi.fn(),
}))

import * as api from './api'

describe('useDocumentStore', () => {
  beforeEach(() => {
    setActivePinia(createPinia())
    vi.clearAllMocks()
  })

  it('starts with empty state', () => {
    const store = useDocumentStore()
    expect(store.documents).toEqual([])
    expect(store.selectedId).toBeNull()
    expect(store.uploading).toBe(false)
  })

  it('load() fetches and sets documents', async () => {
    const docs = [
      { id: '1', filename: 'a.pdf' },
      { id: '2', filename: 'b.pdf' },
    ]
    api.fetchDocuments.mockResolvedValue(docs)

    const store = useDocumentStore()
    await store.load()

    expect(store.documents).toEqual(docs)
  })

  it('load() handles errors gracefully', async () => {
    api.fetchDocuments.mockRejectedValue(new Error('network'))
    const spy = vi.spyOn(console, 'error').mockImplementation(() => {})

    const store = useDocumentStore()
    await store.load()

    expect(store.documents).toEqual([])
    spy.mockRestore()
  })

  it('upload() adds document to front of list and selects it', async () => {
    const newDoc = { id: 'new', filename: 'new.pdf' }
    api.uploadDocument.mockResolvedValue(newDoc)

    const store = useDocumentStore()
    store.documents = [{ id: 'old', filename: 'old.pdf' }]

    const result = await store.upload(new File([], 'new.pdf'))

    expect(result).toEqual(newDoc)
    expect(store.documents[0]).toEqual(newDoc)
    expect(store.selectedId).toBe('new')
    expect(store.uploading).toBe(false)
  })

  it('upload() sets uploading to true during upload', async () => {
    let resolveUpload
    api.uploadDocument.mockImplementation(
      () =>
        new Promise((r) => {
          resolveUpload = r
        }),
    )

    const store = useDocumentStore()
    const promise = store.upload(new File([], 'test.pdf'))

    expect(store.uploading).toBe(true)
    resolveUpload({ id: '1', filename: 'test.pdf' })
    await promise
    expect(store.uploading).toBe(false)
  })

  it('upload() resets uploading on error', async () => {
    api.uploadDocument.mockRejectedValue(new Error('fail'))
    vi.spyOn(console, 'error').mockImplementation(() => {})

    const store = useDocumentStore()

    await expect(store.upload(new File([], 'test.pdf'))).rejects.toThrow('fail')
    expect(store.uploading).toBe(false)
  })

  it('remove() deletes document and clears selection if needed', async () => {
    api.deleteDocument.mockResolvedValue(null)

    const store = useDocumentStore()
    store.documents = [{ id: '1' }, { id: '2' }]
    store.selectedId = '1'

    await store.remove('1')

    expect(store.documents).toEqual([{ id: '2' }])
    expect(store.selectedId).toBeNull()
  })

  it('remove() does not clear selection for other documents', async () => {
    api.deleteDocument.mockResolvedValue(null)

    const store = useDocumentStore()
    store.documents = [{ id: '1' }, { id: '2' }]
    store.selectedId = '2'

    await store.remove('1')

    expect(store.selectedId).toBe('2')
  })

  it('select() sets selectedId', () => {
    const store = useDocumentStore()
    store.select('42')
    expect(store.selectedId).toBe('42')
  })
})