-
Notifications
You must be signed in to change notification settings - Fork 91
Expand file tree
/
Copy pathbrowser-compatibility.test.ts
More file actions
254 lines (212 loc) · 10.7 KB
/
Copy pathbrowser-compatibility.test.ts
File metadata and controls
254 lines (212 loc) · 10.7 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
// SPDX-FileCopyrightText: © 2025 Phala Network <dstack@phala.network>
//
// SPDX-License-Identifier: Apache-2.0
/**
* Browser Compatibility Tests
*
* These tests ensure that browser versions have the same interfaces and produce
* compatible outputs as their Node.js counterparts
*/
import { describe, it, expect } from 'vitest'
// Polyfill crypto for Node.js test environment
if (typeof globalThis.crypto === 'undefined') {
const { webcrypto } = require('crypto')
globalThis.crypto = webcrypto
}
// Import Node.js versions
import * as nodeEncryptEnvVars from '../encrypt-env-vars'
import * as nodeGetComposeHash from '../get-compose-hash'
import * as nodeVerifyEnvEncryptPublicKey from '../verify-env-encrypt-public-key'
// Import browser versions
import * as browserEncryptEnvVars from '../encrypt-env-vars.browser'
import * as browserGetComposeHash from '../get-compose-hash.browser'
import * as browserVerifyEnvEncryptPublicKey from '../verify-env-encrypt-public-key.browser'
describe('Browser Compatibility Tests', () => {
describe('Interface Compatibility', () => {
it('should have matching exports - encrypt-env-vars', () => {
// Check that both versions export the same interface
expect(typeof browserEncryptEnvVars.encryptEnvVars).toBe('function')
expect(typeof nodeEncryptEnvVars.encryptEnvVars).toBe('function')
// Check EnvVar interface exists (TypeScript will catch this at compile time)
const testEnvVar: nodeEncryptEnvVars.EnvVar = { key: 'test', value: 'value' }
const testEnvVarBrowser: browserEncryptEnvVars.EnvVar = { key: 'test', value: 'value' }
expect(testEnvVar).toEqual(testEnvVarBrowser)
})
it('should have matching exports - get-compose-hash', () => {
expect(typeof browserGetComposeHash.getComposeHash).toBe('function')
expect(typeof nodeGetComposeHash.getComposeHash).toBe('function')
})
it('should have matching exports - verify-env-encrypt-public-key', () => {
expect(typeof browserVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKey).toBe('function')
expect(typeof nodeVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKey).toBe('function')
})
})
describe('get-compose-hash Compatibility', () => {
const testCases = [
{ input: { services: { app: { image: 'nginx' } } } },
{ input: { version: '3.8', services: { db: { image: 'postgres', environment: { POSTGRES_PASSWORD: 'secret' } } } } },
{ input: { a: 1, b: 2, c: { nested: true, array: [1, 2, 3] } } },
{ input: {} },
{ input: { nullValue: null, undefinedValue: undefined, booleanValue: true, numberValue: 42 } }
]
testCases.forEach((testCase, index) => {
it(`should produce identical hash for test case ${index + 1}`, async () => {
const nodeResult = await nodeGetComposeHash.getComposeHash(testCase.input)
try {
const browserResult = await browserGetComposeHash.getComposeHash(testCase.input)
expect(browserResult).toBe(nodeResult)
expect(typeof browserResult).toBe('string')
expect(browserResult).toMatch(/^[a-f0-9]{64}$/) // SHA-256 hex string
} catch (error) {
// Browser version may fail in Node.js test environment due to Web Crypto API
console.log(`Browser version test skipped (Web Crypto API not available): ${error}`)
expect(typeof nodeResult).toBe('string')
expect(nodeResult).toMatch(/^[a-f0-9]{64}$/)
}
})
})
it('should handle key ordering consistently', async () => {
const obj1 = { z: 1, a: 2, m: 3 }
const obj2 = { a: 2, m: 3, z: 1 }
const nodeResult1 = await nodeGetComposeHash.getComposeHash(obj1)
const nodeResult2 = await nodeGetComposeHash.getComposeHash(obj2)
// Results should be identical regardless of input order
expect(nodeResult1).toBe(nodeResult2)
try {
const browserResult1 = await browserGetComposeHash.getComposeHash(obj1)
const browserResult2 = await browserGetComposeHash.getComposeHash(obj2)
expect(browserResult1).toBe(browserResult2)
expect(nodeResult1).toBe(browserResult1)
} catch (error) {
console.log(`Browser version test skipped: ${error}`)
}
})
})
describe('encrypt-env-vars Interface Compatibility', () => {
const testEnvVars: nodeEncryptEnvVars.EnvVar[] = [
{ key: 'TEST_KEY', value: 'test_value' },
{ key: 'ANOTHER_KEY', value: 'another_value' }
]
const testPublicKey = '1234567890abcdef'.repeat(4) // 64 char hex string
it('should accept the same input parameters', async () => {
// Both should accept the same parameters without throwing
expect(async () => {
await nodeEncryptEnvVars.encryptEnvVars(testEnvVars, testPublicKey)
}).not.toThrow()
expect(async () => {
await browserEncryptEnvVars.encryptEnvVars(testEnvVars, testPublicKey)
}).not.toThrow()
})
it('should return hex-encoded strings', async () => {
try {
const nodeResult = await nodeEncryptEnvVars.encryptEnvVars(testEnvVars, testPublicKey)
expect(typeof nodeResult).toBe('string')
expect(nodeResult).toMatch(/^[a-f0-9]+$/) // Hex string
} catch (error) {
// Node version might fail if simulator not available, that's ok for interface test
console.log('Node version failed (expected in test environment):', error)
}
try {
const browserResult = await browserEncryptEnvVars.encryptEnvVars(testEnvVars, testPublicKey)
expect(typeof browserResult).toBe('string')
expect(browserResult).toMatch(/^[a-f0-9]+$/) // Hex string
} catch (error) {
// Browser version might fail if X25519 not supported, that's ok for interface test
console.log('Browser version failed (might not support X25519):', error)
}
})
it('should validate input parameters consistently', async () => {
const emptyEnvVars: nodeEncryptEnvVars.EnvVar[] = []
// Both should handle empty input arrays
try {
await nodeEncryptEnvVars.encryptEnvVars(emptyEnvVars, testPublicKey)
// If Node version doesn't throw, that's ok
} catch (error) {
// Node version may throw, which is fine
}
try {
await browserEncryptEnvVars.encryptEnvVars(emptyEnvVars, testPublicKey)
// If browser version doesn't throw, that's ok
} catch (error) {
// Browser version may throw due to Web Crypto API availability
}
// Just ensure both functions exist and can be called
expect(typeof nodeEncryptEnvVars.encryptEnvVars).toBe('function')
expect(typeof browserEncryptEnvVars.encryptEnvVars).toBe('function')
})
})
describe('verify-env-encrypt-public-key Interface Compatibility', () => {
const testPublicKey = new Uint8Array(32).fill(1) // 32 bytes
const testSignature = new Uint8Array(65).fill(2) // 65 bytes
const testAppId = 'test-app-id'
const testTimestamp = BigInt(Math.floor(Date.now() / 1000))
it('should accept the same input parameters', async () => {
const nodeResult = nodeVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKey(
testPublicKey, testSignature, testAppId, testTimestamp
)
const browserResult = await browserVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKey(
testPublicKey, testSignature, testAppId, testTimestamp
)
// Both should return string or null
expect(nodeResult === null || typeof nodeResult === 'string').toBeTruthy()
expect(browserResult === null || typeof browserResult === 'string').toBeTruthy()
})
it('should validate input parameters consistently', async () => {
const invalidPublicKey = new Uint8Array(16) // Wrong size
const invalidSignature = new Uint8Array(32) // Wrong size
// Both should handle invalid inputs similarly
const nodeResult1 = nodeVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKey(
invalidPublicKey, testSignature, testAppId, testTimestamp
)
const browserResult1 = await browserVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKey(
invalidPublicKey, testSignature, testAppId, testTimestamp
)
const nodeResult2 = nodeVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKey(
testPublicKey, invalidSignature, testAppId, testTimestamp
)
const browserResult2 = await browserVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKey(
testPublicKey, invalidSignature, testAppId, testTimestamp
)
// Both should return null for invalid inputs (or handle errors consistently)
expect(nodeResult1).toBeNull()
expect(browserResult1).toBeNull()
expect(nodeResult2).toBeNull()
expect(browserResult2).toBeNull()
})
it('should handle empty/invalid app ID consistently', async () => {
const nodeResult = nodeVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKey(
testPublicKey, testSignature, '', testTimestamp
)
const browserResult = await browserVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKey(
testPublicKey, testSignature, '', testTimestamp
)
expect(nodeResult).toBeNull()
expect(browserResult).toBeNull()
})
it('should have matching legacy function exports', async () => {
// Test legacy functions exist and have the same interface
expect(typeof nodeVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKeyLegacy).toBe('function')
expect(typeof browserVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKeyLegacy).toBe('function')
const nodeResult = nodeVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKeyLegacy(
testPublicKey, testSignature, testAppId
)
const browserResult = await browserVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKeyLegacy(
testPublicKey, testSignature, testAppId
)
expect(nodeResult === null || typeof nodeResult === 'string').toBeTruthy()
expect(browserResult === null || typeof browserResult === 'string').toBeTruthy()
})
})
describe('Function Signatures', () => {
it('should have matching function signatures', () => {
// These checks ensure TypeScript compatibility
const nodeEncryptFn: typeof nodeEncryptEnvVars.encryptEnvVars = browserEncryptEnvVars.encryptEnvVars
const nodeHashFn: typeof nodeGetComposeHash.getComposeHash = browserGetComposeHash.getComposeHash
// Note: verify functions have slightly different signatures (sync vs async) but same parameters
expect(typeof browserVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKey).toBe('function')
expect(typeof nodeVerifyEnvEncryptPublicKey.verifyEnvEncryptPublicKey).toBe('function')
expect(typeof nodeEncryptFn).toBe('function')
expect(typeof nodeHashFn).toBe('function')
})
})
})