@redseat/api 0.0.12 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -132
- package/agents.md +275 -275
- package/client.md +318 -318
- package/dist/client.d.ts +0 -1
- package/dist/client.js +0 -3
- package/dist/interfaces.d.ts +25 -0
- package/dist/interfaces.js +17 -0
- package/dist/library.d.ts +2 -4
- package/dist/library.js +18 -1
- package/encryption.md +533 -533
- package/firebase.md +602 -602
- package/libraries.md +1652 -1652
- package/package.json +49 -49
- package/server.md +196 -196
- package/test.md +291 -291
package/test.md
CHANGED
|
@@ -1,291 +1,291 @@
|
|
|
1
|
-
# Testing Guide
|
|
2
|
-
|
|
3
|
-
This document describes how to run tests for the `@redseat/api` package and what each test file covers.
|
|
4
|
-
|
|
5
|
-
## Running Tests
|
|
6
|
-
|
|
7
|
-
### Run All Tests
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm test
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
This runs all tests once and exits.
|
|
14
|
-
|
|
15
|
-
### Run Tests in Watch Mode
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm run test:watch
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
This runs tests in watch mode, automatically re-running tests when files change.
|
|
22
|
-
|
|
23
|
-
### Run Specific Test File
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
npx vitest run src/encryption.test.ts
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### Run Tests with Coverage
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
npx vitest run --coverage
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Test Framework
|
|
36
|
-
|
|
37
|
-
The package uses [Vitest](https://vitest.dev/) as the test framework. Vitest is a fast unit test framework powered by Vite, designed to be compatible with Jest.
|
|
38
|
-
|
|
39
|
-
### Configuration
|
|
40
|
-
|
|
41
|
-
Test configuration is in `vitest.config.ts`:
|
|
42
|
-
- Environment: Node.js
|
|
43
|
-
- Globals: Enabled (no need to import `describe`, `it`, `expect`)
|
|
44
|
-
|
|
45
|
-
## Test Files
|
|
46
|
-
|
|
47
|
-
### `src/encryption.test.ts`
|
|
48
|
-
|
|
49
|
-
Tests for the encryption module (`src/encryption.ts`).
|
|
50
|
-
|
|
51
|
-
**What it tests:**
|
|
52
|
-
- **Key Derivation (`deriveKey`)**
|
|
53
|
-
- Derives text keys from passphrases
|
|
54
|
-
- Derives file keys from passphrases
|
|
55
|
-
- Verifies text and file keys are different (different salts)
|
|
56
|
-
- Verifies same passphrase produces same key
|
|
57
|
-
|
|
58
|
-
- **IV Generation (`getRandomIV`)**
|
|
59
|
-
- Generates 16-byte IVs
|
|
60
|
-
- Generates different IVs on each call
|
|
61
|
-
|
|
62
|
-
- **Text Encryption/Decryption (`encryptText` / `decryptText`)**
|
|
63
|
-
- Encrypts and decrypts text correctly
|
|
64
|
-
- Produces different encrypted output for same text (due to random IV)
|
|
65
|
-
- Handles empty strings
|
|
66
|
-
- Handles special characters and unicode
|
|
67
|
-
- Verifies encrypted format: `${IV}.${encryptedData}` (base64url)
|
|
68
|
-
|
|
69
|
-
- **Buffer Encryption/Decryption (`encryptBuffer` / `decryptBuffer`)**
|
|
70
|
-
- Encrypts and decrypts binary data correctly
|
|
71
|
-
- Requires correct IV for decryption
|
|
72
|
-
- Handles empty buffers
|
|
73
|
-
- Handles large buffers
|
|
74
|
-
|
|
75
|
-
- **File Encryption (`encryptFile`)**
|
|
76
|
-
- Encrypts files with thumbnails
|
|
77
|
-
- Encrypts files without thumbnails
|
|
78
|
-
- Includes correct MIME types in encrypted structure
|
|
79
|
-
- Returns correct IV and thumbnail size
|
|
80
|
-
|
|
81
|
-
- **File Decryption (`decryptFile` / `decryptFileThumb`)**
|
|
82
|
-
- Decrypts file data from encrypted structure
|
|
83
|
-
- Decrypts thumbnail data from encrypted structure
|
|
84
|
-
- Handles files without thumbnails
|
|
85
|
-
- Verifies file format structure (IV, sizes, MIME types, data)
|
|
86
|
-
|
|
87
|
-
- **Filename Encryption (`encryptFilename`)**
|
|
88
|
-
- Encrypts filenames with given IV
|
|
89
|
-
- Returns base64url encoded encrypted filename
|
|
90
|
-
|
|
91
|
-
- **Endianness Compatibility**
|
|
92
|
-
- Handles both big-endian and little-endian size fields
|
|
93
|
-
- Backward compatibility with old file formats
|
|
94
|
-
|
|
95
|
-
**Example test:**
|
|
96
|
-
```typescript
|
|
97
|
-
it('should encrypt and decrypt text correctly', async () => {
|
|
98
|
-
const key = await deriveKey('password', 'text');
|
|
99
|
-
const encrypted = await encryptText(key, 'Hello World');
|
|
100
|
-
const decrypted = await decryptText(key, encrypted);
|
|
101
|
-
expect(decrypted).toBe('Hello World');
|
|
102
|
-
});
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
### `src/crypto.test.ts`
|
|
108
|
-
|
|
109
|
-
Tests for crypto utility functions (`src/crypto.ts`).
|
|
110
|
-
|
|
111
|
-
**What it tests:**
|
|
112
|
-
- **Platform Detection (`getCryptoSubtle` / `getCryptoRandomValues`)**
|
|
113
|
-
- Returns SubtleCrypto instance
|
|
114
|
-
- Returns random number generator function
|
|
115
|
-
- Works in Node.js environment
|
|
116
|
-
|
|
117
|
-
- **Base64 Encoding/Decoding**
|
|
118
|
-
- `uint8ArrayFromBase64`: Converts base64 to Uint8Array
|
|
119
|
-
- `uint8ArrayFromBase64Url`: Converts base64url to Uint8Array
|
|
120
|
-
- `arrayBufferToBase64`: Converts ArrayBuffer to base64
|
|
121
|
-
- Handles padding correctly
|
|
122
|
-
- Handles base64url format (dashes and underscores)
|
|
123
|
-
|
|
124
|
-
- **Base64 URL Conversion**
|
|
125
|
-
- `base64ToBase64Url`: Converts standard base64 to base64url
|
|
126
|
-
- `base64UrlToBase64`: Converts base64url to standard base64
|
|
127
|
-
- Handles character substitution (`+`/`-`, `/`/`_`)
|
|
128
|
-
- Handles padding removal/addition
|
|
129
|
-
|
|
130
|
-
- **String Padding (`padRight`)**
|
|
131
|
-
- Pads strings to specified length
|
|
132
|
-
- Handles strings longer than target length
|
|
133
|
-
- Handles empty strings
|
|
134
|
-
- Uses correct padding character
|
|
135
|
-
|
|
136
|
-
**Example test:**
|
|
137
|
-
```typescript
|
|
138
|
-
it('should convert base64 string to Uint8Array', () => {
|
|
139
|
-
const base64 = 'SGVsbG8gV29ybGQ='; // "Hello World"
|
|
140
|
-
const result = uint8ArrayFromBase64(base64);
|
|
141
|
-
expect(result).toBeInstanceOf(Uint8Array);
|
|
142
|
-
expect(String.fromCharCode(...result)).toBe('Hello World');
|
|
143
|
-
});
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
### `src/library-upload.test.ts`
|
|
149
|
-
|
|
150
|
-
Tests for `LibraryApi.uploadMedia()` method.
|
|
151
|
-
|
|
152
|
-
**What it tests:**
|
|
153
|
-
- **Encrypted Library Uploads**
|
|
154
|
-
- Throws error if encryption key is not set
|
|
155
|
-
- Encrypts data when key is set via `setKey()`
|
|
156
|
-
- Encrypts filename using text encryption
|
|
157
|
-
- Includes IV and thumbnail size in metadata
|
|
158
|
-
- Handles thumbnail encryption
|
|
159
|
-
- Validates thumbnail can only be specified for encrypted libraries
|
|
160
|
-
|
|
161
|
-
- **Non-Encrypted Library Uploads**
|
|
162
|
-
- Uploads without encryption
|
|
163
|
-
- Uses original filename
|
|
164
|
-
- Does not require encryption key
|
|
165
|
-
|
|
166
|
-
- **Input Validation**
|
|
167
|
-
- Handles ArrayBuffer input
|
|
168
|
-
- Handles Uint8Array input
|
|
169
|
-
- Normalizes different buffer types correctly
|
|
170
|
-
- Validates metadata structure
|
|
171
|
-
|
|
172
|
-
- **FormData Structure**
|
|
173
|
-
- Creates FormData with correct structure
|
|
174
|
-
- Info field is first, file field is last
|
|
175
|
-
- Includes correct metadata in info field
|
|
176
|
-
- Uses correct filename in file field
|
|
177
|
-
|
|
178
|
-
- **Progress Callback**
|
|
179
|
-
- Calls progress callback during upload
|
|
180
|
-
- Provides correct loaded/total values
|
|
181
|
-
|
|
182
|
-
- **Error Handling**
|
|
183
|
-
- Throws appropriate errors for missing keys
|
|
184
|
-
- Throws errors for invalid configurations
|
|
185
|
-
- Handles network errors gracefully
|
|
186
|
-
|
|
187
|
-
**Example test:**
|
|
188
|
-
```typescript
|
|
189
|
-
it('should throw error if key is not set', async () => {
|
|
190
|
-
libraryApi = new LibraryApi(client, 'lib1', encryptedLibrary);
|
|
191
|
-
await expect(
|
|
192
|
-
libraryApi.uploadMedia(data, {
|
|
193
|
-
metadata: {},
|
|
194
|
-
fileMime: 'image/jpeg'
|
|
195
|
-
})
|
|
196
|
-
).rejects.toThrow('Encryption key not set');
|
|
197
|
-
});
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
---
|
|
201
|
-
|
|
202
|
-
## Test Structure
|
|
203
|
-
|
|
204
|
-
All test files follow this structure:
|
|
205
|
-
|
|
206
|
-
```typescript
|
|
207
|
-
import { describe, it, expect } from 'vitest';
|
|
208
|
-
import { /* functions to test */ } from './module';
|
|
209
|
-
|
|
210
|
-
describe('Module Name', () => {
|
|
211
|
-
describe('Function Group', () => {
|
|
212
|
-
it('should do something', () => {
|
|
213
|
-
// Test implementation
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
## Writing New Tests
|
|
220
|
-
|
|
221
|
-
When adding new functionality:
|
|
222
|
-
|
|
223
|
-
1. **Add tests to existing file** if testing existing module
|
|
224
|
-
2. **Create new test file** if testing new module (follow naming: `module-name.test.ts`)
|
|
225
|
-
3. **Test both success and error cases**
|
|
226
|
-
4. **Test edge cases** (empty inputs, null values, etc.)
|
|
227
|
-
5. **Use descriptive test names** that explain what is being tested
|
|
228
|
-
|
|
229
|
-
### Example: Adding Test for New Function
|
|
230
|
-
|
|
231
|
-
```typescript
|
|
232
|
-
// In appropriate test file
|
|
233
|
-
describe('newFunction', () => {
|
|
234
|
-
it('should handle normal case', () => {
|
|
235
|
-
const result = newFunction('input');
|
|
236
|
-
expect(result).toBe('expected');
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
it('should handle edge case', () => {
|
|
240
|
-
const result = newFunction('');
|
|
241
|
-
expect(result).toBe('');
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
it('should throw error for invalid input', () => {
|
|
245
|
-
expect(() => newFunction(null)).toThrow();
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## Continuous Integration
|
|
251
|
-
|
|
252
|
-
Tests should be run:
|
|
253
|
-
- Before committing code
|
|
254
|
-
- In CI/CD pipeline
|
|
255
|
-
- Before releasing new versions
|
|
256
|
-
|
|
257
|
-
## Coverage Goals
|
|
258
|
-
|
|
259
|
-
Aim for:
|
|
260
|
-
- **High coverage** on core functionality (encryption, API methods)
|
|
261
|
-
- **Edge case coverage** for error handling
|
|
262
|
-
- **Integration tests** for complex workflows
|
|
263
|
-
|
|
264
|
-
## Debugging Tests
|
|
265
|
-
|
|
266
|
-
### Run Single Test
|
|
267
|
-
|
|
268
|
-
```bash
|
|
269
|
-
npx vitest run -t "test name"
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
### Debug Mode
|
|
273
|
-
|
|
274
|
-
```bash
|
|
275
|
-
node --inspect-brk node_modules/.bin/vitest run
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
Then attach debugger in VS Code or Chrome DevTools.
|
|
279
|
-
|
|
280
|
-
### Verbose Output
|
|
281
|
-
|
|
282
|
-
```bash
|
|
283
|
-
npx vitest run --reporter=verbose
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
## Related Documentation
|
|
287
|
-
|
|
288
|
-
- [Vitest Documentation](https://vitest.dev/)
|
|
289
|
-
- [Encryption Documentation](encryption.md) - Details on encryption functions being tested
|
|
290
|
-
- [README](README.md) - Package overview
|
|
291
|
-
|
|
1
|
+
# Testing Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to run tests for the `@redseat/api` package and what each test file covers.
|
|
4
|
+
|
|
5
|
+
## Running Tests
|
|
6
|
+
|
|
7
|
+
### Run All Tests
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm test
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This runs all tests once and exits.
|
|
14
|
+
|
|
15
|
+
### Run Tests in Watch Mode
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm run test:watch
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This runs tests in watch mode, automatically re-running tests when files change.
|
|
22
|
+
|
|
23
|
+
### Run Specific Test File
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx vitest run src/encryption.test.ts
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Run Tests with Coverage
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx vitest run --coverage
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Test Framework
|
|
36
|
+
|
|
37
|
+
The package uses [Vitest](https://vitest.dev/) as the test framework. Vitest is a fast unit test framework powered by Vite, designed to be compatible with Jest.
|
|
38
|
+
|
|
39
|
+
### Configuration
|
|
40
|
+
|
|
41
|
+
Test configuration is in `vitest.config.ts`:
|
|
42
|
+
- Environment: Node.js
|
|
43
|
+
- Globals: Enabled (no need to import `describe`, `it`, `expect`)
|
|
44
|
+
|
|
45
|
+
## Test Files
|
|
46
|
+
|
|
47
|
+
### `src/encryption.test.ts`
|
|
48
|
+
|
|
49
|
+
Tests for the encryption module (`src/encryption.ts`).
|
|
50
|
+
|
|
51
|
+
**What it tests:**
|
|
52
|
+
- **Key Derivation (`deriveKey`)**
|
|
53
|
+
- Derives text keys from passphrases
|
|
54
|
+
- Derives file keys from passphrases
|
|
55
|
+
- Verifies text and file keys are different (different salts)
|
|
56
|
+
- Verifies same passphrase produces same key
|
|
57
|
+
|
|
58
|
+
- **IV Generation (`getRandomIV`)**
|
|
59
|
+
- Generates 16-byte IVs
|
|
60
|
+
- Generates different IVs on each call
|
|
61
|
+
|
|
62
|
+
- **Text Encryption/Decryption (`encryptText` / `decryptText`)**
|
|
63
|
+
- Encrypts and decrypts text correctly
|
|
64
|
+
- Produces different encrypted output for same text (due to random IV)
|
|
65
|
+
- Handles empty strings
|
|
66
|
+
- Handles special characters and unicode
|
|
67
|
+
- Verifies encrypted format: `${IV}.${encryptedData}` (base64url)
|
|
68
|
+
|
|
69
|
+
- **Buffer Encryption/Decryption (`encryptBuffer` / `decryptBuffer`)**
|
|
70
|
+
- Encrypts and decrypts binary data correctly
|
|
71
|
+
- Requires correct IV for decryption
|
|
72
|
+
- Handles empty buffers
|
|
73
|
+
- Handles large buffers
|
|
74
|
+
|
|
75
|
+
- **File Encryption (`encryptFile`)**
|
|
76
|
+
- Encrypts files with thumbnails
|
|
77
|
+
- Encrypts files without thumbnails
|
|
78
|
+
- Includes correct MIME types in encrypted structure
|
|
79
|
+
- Returns correct IV and thumbnail size
|
|
80
|
+
|
|
81
|
+
- **File Decryption (`decryptFile` / `decryptFileThumb`)**
|
|
82
|
+
- Decrypts file data from encrypted structure
|
|
83
|
+
- Decrypts thumbnail data from encrypted structure
|
|
84
|
+
- Handles files without thumbnails
|
|
85
|
+
- Verifies file format structure (IV, sizes, MIME types, data)
|
|
86
|
+
|
|
87
|
+
- **Filename Encryption (`encryptFilename`)**
|
|
88
|
+
- Encrypts filenames with given IV
|
|
89
|
+
- Returns base64url encoded encrypted filename
|
|
90
|
+
|
|
91
|
+
- **Endianness Compatibility**
|
|
92
|
+
- Handles both big-endian and little-endian size fields
|
|
93
|
+
- Backward compatibility with old file formats
|
|
94
|
+
|
|
95
|
+
**Example test:**
|
|
96
|
+
```typescript
|
|
97
|
+
it('should encrypt and decrypt text correctly', async () => {
|
|
98
|
+
const key = await deriveKey('password', 'text');
|
|
99
|
+
const encrypted = await encryptText(key, 'Hello World');
|
|
100
|
+
const decrypted = await decryptText(key, encrypted);
|
|
101
|
+
expect(decrypted).toBe('Hello World');
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
### `src/crypto.test.ts`
|
|
108
|
+
|
|
109
|
+
Tests for crypto utility functions (`src/crypto.ts`).
|
|
110
|
+
|
|
111
|
+
**What it tests:**
|
|
112
|
+
- **Platform Detection (`getCryptoSubtle` / `getCryptoRandomValues`)**
|
|
113
|
+
- Returns SubtleCrypto instance
|
|
114
|
+
- Returns random number generator function
|
|
115
|
+
- Works in Node.js environment
|
|
116
|
+
|
|
117
|
+
- **Base64 Encoding/Decoding**
|
|
118
|
+
- `uint8ArrayFromBase64`: Converts base64 to Uint8Array
|
|
119
|
+
- `uint8ArrayFromBase64Url`: Converts base64url to Uint8Array
|
|
120
|
+
- `arrayBufferToBase64`: Converts ArrayBuffer to base64
|
|
121
|
+
- Handles padding correctly
|
|
122
|
+
- Handles base64url format (dashes and underscores)
|
|
123
|
+
|
|
124
|
+
- **Base64 URL Conversion**
|
|
125
|
+
- `base64ToBase64Url`: Converts standard base64 to base64url
|
|
126
|
+
- `base64UrlToBase64`: Converts base64url to standard base64
|
|
127
|
+
- Handles character substitution (`+`/`-`, `/`/`_`)
|
|
128
|
+
- Handles padding removal/addition
|
|
129
|
+
|
|
130
|
+
- **String Padding (`padRight`)**
|
|
131
|
+
- Pads strings to specified length
|
|
132
|
+
- Handles strings longer than target length
|
|
133
|
+
- Handles empty strings
|
|
134
|
+
- Uses correct padding character
|
|
135
|
+
|
|
136
|
+
**Example test:**
|
|
137
|
+
```typescript
|
|
138
|
+
it('should convert base64 string to Uint8Array', () => {
|
|
139
|
+
const base64 = 'SGVsbG8gV29ybGQ='; // "Hello World"
|
|
140
|
+
const result = uint8ArrayFromBase64(base64);
|
|
141
|
+
expect(result).toBeInstanceOf(Uint8Array);
|
|
142
|
+
expect(String.fromCharCode(...result)).toBe('Hello World');
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
### `src/library-upload.test.ts`
|
|
149
|
+
|
|
150
|
+
Tests for `LibraryApi.uploadMedia()` method.
|
|
151
|
+
|
|
152
|
+
**What it tests:**
|
|
153
|
+
- **Encrypted Library Uploads**
|
|
154
|
+
- Throws error if encryption key is not set
|
|
155
|
+
- Encrypts data when key is set via `setKey()`
|
|
156
|
+
- Encrypts filename using text encryption
|
|
157
|
+
- Includes IV and thumbnail size in metadata
|
|
158
|
+
- Handles thumbnail encryption
|
|
159
|
+
- Validates thumbnail can only be specified for encrypted libraries
|
|
160
|
+
|
|
161
|
+
- **Non-Encrypted Library Uploads**
|
|
162
|
+
- Uploads without encryption
|
|
163
|
+
- Uses original filename
|
|
164
|
+
- Does not require encryption key
|
|
165
|
+
|
|
166
|
+
- **Input Validation**
|
|
167
|
+
- Handles ArrayBuffer input
|
|
168
|
+
- Handles Uint8Array input
|
|
169
|
+
- Normalizes different buffer types correctly
|
|
170
|
+
- Validates metadata structure
|
|
171
|
+
|
|
172
|
+
- **FormData Structure**
|
|
173
|
+
- Creates FormData with correct structure
|
|
174
|
+
- Info field is first, file field is last
|
|
175
|
+
- Includes correct metadata in info field
|
|
176
|
+
- Uses correct filename in file field
|
|
177
|
+
|
|
178
|
+
- **Progress Callback**
|
|
179
|
+
- Calls progress callback during upload
|
|
180
|
+
- Provides correct loaded/total values
|
|
181
|
+
|
|
182
|
+
- **Error Handling**
|
|
183
|
+
- Throws appropriate errors for missing keys
|
|
184
|
+
- Throws errors for invalid configurations
|
|
185
|
+
- Handles network errors gracefully
|
|
186
|
+
|
|
187
|
+
**Example test:**
|
|
188
|
+
```typescript
|
|
189
|
+
it('should throw error if key is not set', async () => {
|
|
190
|
+
libraryApi = new LibraryApi(client, 'lib1', encryptedLibrary);
|
|
191
|
+
await expect(
|
|
192
|
+
libraryApi.uploadMedia(data, {
|
|
193
|
+
metadata: {},
|
|
194
|
+
fileMime: 'image/jpeg'
|
|
195
|
+
})
|
|
196
|
+
).rejects.toThrow('Encryption key not set');
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Test Structure
|
|
203
|
+
|
|
204
|
+
All test files follow this structure:
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { describe, it, expect } from 'vitest';
|
|
208
|
+
import { /* functions to test */ } from './module';
|
|
209
|
+
|
|
210
|
+
describe('Module Name', () => {
|
|
211
|
+
describe('Function Group', () => {
|
|
212
|
+
it('should do something', () => {
|
|
213
|
+
// Test implementation
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Writing New Tests
|
|
220
|
+
|
|
221
|
+
When adding new functionality:
|
|
222
|
+
|
|
223
|
+
1. **Add tests to existing file** if testing existing module
|
|
224
|
+
2. **Create new test file** if testing new module (follow naming: `module-name.test.ts`)
|
|
225
|
+
3. **Test both success and error cases**
|
|
226
|
+
4. **Test edge cases** (empty inputs, null values, etc.)
|
|
227
|
+
5. **Use descriptive test names** that explain what is being tested
|
|
228
|
+
|
|
229
|
+
### Example: Adding Test for New Function
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
// In appropriate test file
|
|
233
|
+
describe('newFunction', () => {
|
|
234
|
+
it('should handle normal case', () => {
|
|
235
|
+
const result = newFunction('input');
|
|
236
|
+
expect(result).toBe('expected');
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it('should handle edge case', () => {
|
|
240
|
+
const result = newFunction('');
|
|
241
|
+
expect(result).toBe('');
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it('should throw error for invalid input', () => {
|
|
245
|
+
expect(() => newFunction(null)).toThrow();
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Continuous Integration
|
|
251
|
+
|
|
252
|
+
Tests should be run:
|
|
253
|
+
- Before committing code
|
|
254
|
+
- In CI/CD pipeline
|
|
255
|
+
- Before releasing new versions
|
|
256
|
+
|
|
257
|
+
## Coverage Goals
|
|
258
|
+
|
|
259
|
+
Aim for:
|
|
260
|
+
- **High coverage** on core functionality (encryption, API methods)
|
|
261
|
+
- **Edge case coverage** for error handling
|
|
262
|
+
- **Integration tests** for complex workflows
|
|
263
|
+
|
|
264
|
+
## Debugging Tests
|
|
265
|
+
|
|
266
|
+
### Run Single Test
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
npx vitest run -t "test name"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Debug Mode
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
node --inspect-brk node_modules/.bin/vitest run
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Then attach debugger in VS Code or Chrome DevTools.
|
|
279
|
+
|
|
280
|
+
### Verbose Output
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
npx vitest run --reporter=verbose
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Related Documentation
|
|
287
|
+
|
|
288
|
+
- [Vitest Documentation](https://vitest.dev/)
|
|
289
|
+
- [Encryption Documentation](encryption.md) - Details on encryption functions being tested
|
|
290
|
+
- [README](README.md) - Package overview
|
|
291
|
+
|