util.test.ts124 lines · main
1import { beforeEach, describe, expect, it, vi } from 'vitest'
2
3import { assertSelfHosted, encryptString } from './util'
4
5vi.mock('@/lib/constants', () => ({
6 IS_PLATFORM: false,
7}))
8
9vi.mock('crypto-js', () => {
10 const mockEncrypt = vi.fn()
11 return {
12 default: {
13 AES: {
14 encrypt: mockEncrypt,
15 },
16 },
17 AES: {
18 encrypt: mockEncrypt,
19 },
20 }
21})
22
23describe('api/self-hosted/util', () => {
24 beforeEach(() => {
25 vi.clearAllMocks()
26 })
27
28 describe('assertSelfHosted', () => {
29 it('should not throw when IS_PLATFORM is false', async () => {
30 const constants = await import('@/lib/constants')
31 vi.spyOn(constants, 'IS_PLATFORM', 'get').mockReturnValue(false)
32
33 expect(() => assertSelfHosted()).not.toThrow()
34 })
35
36 it('should throw error when IS_PLATFORM is true', async () => {
37 const constants = await import('@/lib/constants')
38 vi.spyOn(constants, 'IS_PLATFORM', 'get').mockReturnValue(true)
39
40 expect(() => assertSelfHosted()).toThrow(
41 'This function can only be called in self-hosted environments'
42 )
43 })
44 })
45
46 describe('encryptString', () => {
47 it('should encrypt string using AES', async () => {
48 const crypto = await import('crypto-js')
49 const mockEncrypted = 'encrypted-string-123'
50 vi.mocked(crypto.default.AES.encrypt).mockReturnValue({
51 toString: () => mockEncrypted,
52 } as any)
53
54 const result = encryptString('my-secret-data')
55
56 expect(crypto.default.AES.encrypt).toHaveBeenCalledWith('my-secret-data', expect.any(String))
57 expect(result).toBe(mockEncrypted)
58 })
59
60 it('should return encrypted string as string', async () => {
61 const crypto = await import('crypto-js')
62 vi.mocked(crypto.default.AES.encrypt).mockReturnValue({
63 toString: () => 'U2FsdGVkX1+abc123',
64 } as any)
65
66 const result = encryptString('test')
67
68 expect(typeof result).toBe('string')
69 expect(result).toBe('U2FsdGVkX1+abc123')
70 })
71 })
72
73 describe('getConnectionString', () => {
74 beforeEach(() => {
75 vi.resetModules()
76 })
77
78 it('should build connection string with read-write user', async () => {
79 vi.stubEnv('POSTGRES_HOST', 'localhost')
80 vi.stubEnv('POSTGRES_PORT', '5432')
81 vi.stubEnv('POSTGRES_DB', 'testdb')
82 vi.stubEnv('POSTGRES_PASSWORD', 'testpass')
83 vi.stubEnv('POSTGRES_USER_READ_WRITE', 'admin_user')
84
85 // Re-import to get updated env values
86 const { getConnectionString } = await import('./util')
87
88 const result = getConnectionString({ readOnly: false })
89
90 expect(result).toBe('postgresql://admin_user:testpass@localhost:5432/testdb')
91 })
92
93 it('should build connection string with read-only user', async () => {
94 vi.stubEnv('POSTGRES_HOST', 'db.example.com')
95 vi.stubEnv('POSTGRES_PORT', '5433')
96 vi.stubEnv('POSTGRES_DB', 'mydb')
97 vi.stubEnv('POSTGRES_PASSWORD', 'secret')
98 vi.stubEnv('POSTGRES_USER_READ_ONLY', 'readonly_user')
99
100 const { getConnectionString } = await import('./util')
101
102 const result = getConnectionString({ readOnly: true })
103
104 expect(result).toBe('postgresql://readonly_user:secret@db.example.com:5433/mydb')
105 })
106
107 it('should use default values when env vars not set', async () => {
108 vi.stubEnv('POSTGRES_HOST', '')
109 vi.stubEnv('POSTGRES_PORT', '')
110 vi.stubEnv('POSTGRES_DB', '')
111 vi.stubEnv('POSTGRES_PASSWORD', '')
112 vi.stubEnv('POSTGRES_USER_READ_WRITE', '')
113 vi.stubEnv('POSTGRES_USER_READ_ONLY', '')
114
115 const { getConnectionString } = await import('./util')
116
117 const resultReadWrite = getConnectionString({ readOnly: false })
118 const resultReadOnly = getConnectionString({ readOnly: true })
119
120 expect(resultReadWrite).toBe('postgresql://briven_admin:postgres@db:5432/postgres')
121 expect(resultReadOnly).toBe('postgresql://briven_read_only_user:postgres@db:5432/postgres')
122 })
123 })
124})