@elevasis/core 0.12.0 → 0.14.0
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/dist/index.d.ts +1 -1
- package/dist/index.js +9 -2
- package/dist/organization-model/index.d.ts +1 -1
- package/dist/organization-model/index.js +9 -2
- package/dist/test-utils/index.d.ts +480 -389
- package/dist/test-utils/index.js +28 -2
- package/package.json +1 -1
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +2324 -0
- package/src/auth/multi-tenancy/credentials/__tests__/encryption.test.ts +217 -216
- package/src/auth/multi-tenancy/credentials/server/encryption.ts +5 -19
- package/src/auth/multi-tenancy/credentials/server/kek-loader.ts +3 -13
- package/src/auth/multi-tenancy/permissions.ts +12 -5
- package/src/business/acquisition/activity-events.test.ts +250 -0
- package/src/business/acquisition/activity-events.ts +84 -0
- package/src/business/acquisition/api-schemas.test.ts +1180 -0
- package/src/business/acquisition/api-schemas.ts +456 -235
- package/src/business/acquisition/crm-state-actions.test.ts +160 -0
- package/src/business/acquisition/derive-actions.test.ts +518 -0
- package/src/business/acquisition/derive-actions.ts +103 -0
- package/src/business/acquisition/index.ts +51 -11
- package/src/business/acquisition/stateful.ts +30 -0
- package/src/business/acquisition/types.ts +44 -77
- package/src/execution/engine/index.ts +4 -1
- package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +1 -2
- package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +363 -361
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.test.ts +162 -186
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.test.ts +316 -338
- package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +204 -210
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.test.ts +88 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +141 -134
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +76 -75
- package/src/execution/engine/tools/integration/service.test.ts +34 -9
- package/src/execution/engine/tools/integration/service.ts +6 -3
- package/src/execution/engine/tools/lead-service-types.ts +90 -30
- package/src/execution/engine/tools/platform/acquisition/types.ts +266 -260
- package/src/execution/engine/tools/registry.ts +5 -4
- package/src/execution/engine/tools/tool-maps.ts +43 -21
- package/src/execution/engine/workflow/types.ts +11 -0
- package/src/organization-model/contracts.ts +4 -4
- package/src/organization-model/domains/navigation.ts +62 -62
- package/src/organization-model/domains/sales.ts +272 -0
- package/src/organization-model/organization-graph.mdx +2 -2
- package/src/organization-model/published.ts +21 -21
- package/src/organization-model/resolve.ts +21 -8
- package/src/platform/constants/versions.ts +1 -1
- package/src/reference/_generated/contracts.md +2324 -0
- package/src/scaffold-registry/index.ts +10 -9
- package/src/scaffold-registry/schema.ts +68 -62
- package/src/supabase/database.types.ts +2958 -2884
- package/src/test-utils/rls/RLSTestContext.ts +585 -553
|
@@ -1,361 +1,363 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest'
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
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
|
-
const
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
let
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
console.log(
|
|
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
|
-
expect(result
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const
|
|
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
|
-
expect(result
|
|
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
|
-
expect(result
|
|
167
|
-
expect(result.
|
|
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
|
-
expect(result
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
expect(result
|
|
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
|
-
expect(page1
|
|
247
|
-
expect(page2
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
console.log(
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}
|
|
1
|
+
import { describe as _describe, it, expect, beforeAll, afterAll, vi } from 'vitest'
|
|
2
|
+
|
|
3
|
+
// Attio integration not in use; suite skipped per project decision (2026-04-29).
|
|
4
|
+
const describe = _describe.skip
|
|
5
|
+
import { AttioAdapter } from '../attio-adapter'
|
|
6
|
+
import type { ExecutionContext } from '../../../../../../base/types'
|
|
7
|
+
import { createClient } from '@supabase/supabase-js'
|
|
8
|
+
import type { Database } from '../../../../../../../../supabase/database.types'
|
|
9
|
+
import { decryptCredentialValue } from '../../../../../../../../auth/multi-tenancy/credentials/server/service'
|
|
10
|
+
import type {
|
|
11
|
+
CreateRecordResult,
|
|
12
|
+
UpdateRecordResult,
|
|
13
|
+
GetRecordResult,
|
|
14
|
+
QueryRecordsResult,
|
|
15
|
+
DeleteRecordResult
|
|
16
|
+
} from '../fetch/utils/types'
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Comprehensive CRUD Integration Test Suite for Attio
|
|
20
|
+
*
|
|
21
|
+
* Tests the complete lifecycle:
|
|
22
|
+
* 1. List records (people)
|
|
23
|
+
* 2. Create person record
|
|
24
|
+
* 3. Get record by ID
|
|
25
|
+
* 4. Update record
|
|
26
|
+
* 5. List records with filters
|
|
27
|
+
* 6. Error handling
|
|
28
|
+
*
|
|
29
|
+
* Prerequisites:
|
|
30
|
+
* - Supabase database with credentials table
|
|
31
|
+
* - Credential 'elevasis-attio' with valid Attio API Key
|
|
32
|
+
* - Organization ID: f9aa5a56-8c13-4cd1-9161-8827ae7b452b
|
|
33
|
+
* - SUPABASE_URL and SUPABASE_SERVICE_KEY env vars set
|
|
34
|
+
* - Attio workspace accessible with provided credentials
|
|
35
|
+
*
|
|
36
|
+
* Run: pnpm test attio-crud.integration.test.ts
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
// Attio integration currently unused -- tests skipped unconditionally.
|
|
40
|
+
describe.skip('Attio CRUD Integration Tests', () => {
|
|
41
|
+
const adapter = new AttioAdapter()
|
|
42
|
+
const organizationId = 'f9aa5a56-8c13-4cd1-9161-8827ae7b452b'
|
|
43
|
+
const credentialName = 'elevasis-attio'
|
|
44
|
+
|
|
45
|
+
const context: ExecutionContext = {
|
|
46
|
+
organizationId,
|
|
47
|
+
executionId: 'crud-integration-test',
|
|
48
|
+
resourceId: 'crud-test-agent',
|
|
49
|
+
resourceType: 'agent',
|
|
50
|
+
logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn(), child: vi.fn().mockReturnThis() }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let supabase: ReturnType<typeof createClient<Database>>
|
|
54
|
+
let credentials: Record<string, unknown>
|
|
55
|
+
let createdRecordId: string
|
|
56
|
+
|
|
57
|
+
beforeAll(async () => {
|
|
58
|
+
console.log('\n=== Attio CRUD Integration Test Suite ===')
|
|
59
|
+
console.log(`Organization: ${organizationId}`)
|
|
60
|
+
console.log(`Credential: ${credentialName}\n`)
|
|
61
|
+
|
|
62
|
+
// Initialize Supabase
|
|
63
|
+
supabase = createClient<Database>(process.env.SUPABASE_URL!, process.env.SUPABASE_SERVICE_KEY!)
|
|
64
|
+
|
|
65
|
+
// Fetch credential from database
|
|
66
|
+
const { data: credRow, error } = await supabase
|
|
67
|
+
.from('credentials')
|
|
68
|
+
.select('encrypted_value')
|
|
69
|
+
.eq('organization_id', organizationId)
|
|
70
|
+
.eq('name', credentialName)
|
|
71
|
+
.single()
|
|
72
|
+
|
|
73
|
+
if (error || !credRow) {
|
|
74
|
+
throw new Error(`Credential '${credentialName}' not found for org ${organizationId}. Error: ${error?.message}`)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Decrypt credentials
|
|
78
|
+
credentials = decryptCredentialValue(credRow.encrypted_value)
|
|
79
|
+
|
|
80
|
+
console.log('✓ Credentials loaded and decrypted')
|
|
81
|
+
console.log(`✓ API Key present: ${!!credentials.apiKey}`)
|
|
82
|
+
|
|
83
|
+
// Validate credentials
|
|
84
|
+
const isValid = adapter.validateCredentials(credentials)
|
|
85
|
+
if (!isValid) {
|
|
86
|
+
throw new Error('Credential validation failed')
|
|
87
|
+
}
|
|
88
|
+
console.log('✓ Credentials validated')
|
|
89
|
+
console.log('\n✓ Ready to run tests')
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('should list people records', { timeout: 30000 }, async () => {
|
|
93
|
+
console.log('\n[Test] List people records')
|
|
94
|
+
|
|
95
|
+
const result = (await adapter.call(
|
|
96
|
+
'listRecords',
|
|
97
|
+
{
|
|
98
|
+
object: 'people',
|
|
99
|
+
limit: 10,
|
|
100
|
+
offset: 0
|
|
101
|
+
},
|
|
102
|
+
credentials,
|
|
103
|
+
context
|
|
104
|
+
)) as QueryRecordsResult
|
|
105
|
+
|
|
106
|
+
console.log(`✓ Listed ${result.records.length} people`)
|
|
107
|
+
|
|
108
|
+
expect(result).toBeDefined()
|
|
109
|
+
expect(result.records).toBeInstanceOf(Array)
|
|
110
|
+
expect(result.hasMore).toBeDefined()
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
it('should create a person record', async () => {
|
|
114
|
+
console.log('\n[Test] Create person record')
|
|
115
|
+
|
|
116
|
+
const testEmail = `test-${Date.now()}@example.com`
|
|
117
|
+
|
|
118
|
+
const result = (await adapter.call(
|
|
119
|
+
'createRecord',
|
|
120
|
+
{
|
|
121
|
+
object: 'people',
|
|
122
|
+
values: {
|
|
123
|
+
name: {
|
|
124
|
+
first_name: 'Test',
|
|
125
|
+
last_name: 'User',
|
|
126
|
+
full_name: 'Test User'
|
|
127
|
+
},
|
|
128
|
+
email_addresses: [
|
|
129
|
+
{
|
|
130
|
+
email_address: testEmail
|
|
131
|
+
}
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
credentials,
|
|
136
|
+
context
|
|
137
|
+
)) as CreateRecordResult
|
|
138
|
+
|
|
139
|
+
console.log(`✓ Created person: ${result.recordId}`)
|
|
140
|
+
|
|
141
|
+
expect(result).toBeDefined()
|
|
142
|
+
expect(result.recordId).toBeDefined()
|
|
143
|
+
expect(result.success).toBe(true)
|
|
144
|
+
|
|
145
|
+
// Store for later tests
|
|
146
|
+
createdRecordId = result.recordId
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('should get the created record by ID', async () => {
|
|
150
|
+
console.log('\n[Test] Get record by ID')
|
|
151
|
+
|
|
152
|
+
expect(createdRecordId).toBeDefined()
|
|
153
|
+
|
|
154
|
+
const result = (await adapter.call(
|
|
155
|
+
'getRecord',
|
|
156
|
+
{
|
|
157
|
+
object: 'people',
|
|
158
|
+
recordId: createdRecordId
|
|
159
|
+
},
|
|
160
|
+
credentials,
|
|
161
|
+
context
|
|
162
|
+
)) as GetRecordResult
|
|
163
|
+
|
|
164
|
+
console.log(`✓ Retrieved record: ${result.id}`)
|
|
165
|
+
|
|
166
|
+
expect(result).toBeDefined()
|
|
167
|
+
expect(result.id).toBe(createdRecordId)
|
|
168
|
+
expect(result.values).toBeDefined()
|
|
169
|
+
expect(result.createdAt).toBeDefined()
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
it('should update the created record', async () => {
|
|
173
|
+
console.log('\n[Test] Update record')
|
|
174
|
+
|
|
175
|
+
expect(createdRecordId).toBeDefined()
|
|
176
|
+
|
|
177
|
+
const result = (await adapter.call(
|
|
178
|
+
'updateRecord',
|
|
179
|
+
{
|
|
180
|
+
object: 'people',
|
|
181
|
+
recordId: createdRecordId,
|
|
182
|
+
values: {
|
|
183
|
+
description: 'Updated via integration test'
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
credentials,
|
|
187
|
+
context
|
|
188
|
+
)) as UpdateRecordResult
|
|
189
|
+
|
|
190
|
+
console.log(`✓ Updated record: ${result.recordId}`)
|
|
191
|
+
|
|
192
|
+
expect(result).toBeDefined()
|
|
193
|
+
expect(result.recordId).toBe(createdRecordId)
|
|
194
|
+
expect(result.success).toBe(true)
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
it('should list records with custom limit', async () => {
|
|
198
|
+
console.log('\n[Test] List records with custom limit')
|
|
199
|
+
|
|
200
|
+
const result = (await adapter.call(
|
|
201
|
+
'listRecords',
|
|
202
|
+
{
|
|
203
|
+
object: 'people',
|
|
204
|
+
limit: 5,
|
|
205
|
+
offset: 0
|
|
206
|
+
},
|
|
207
|
+
credentials,
|
|
208
|
+
context
|
|
209
|
+
)) as QueryRecordsResult
|
|
210
|
+
|
|
211
|
+
console.log(`✓ Listed ${result.records.length} people (limit: 5)`)
|
|
212
|
+
|
|
213
|
+
expect(result).toBeDefined()
|
|
214
|
+
expect(result.records).toBeInstanceOf(Array)
|
|
215
|
+
expect(result.records.length).toBeLessThanOrEqual(5)
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
it('should list records with pagination', { timeout: 30000 }, async () => {
|
|
219
|
+
console.log('\n[Test] List records with pagination')
|
|
220
|
+
|
|
221
|
+
const page1 = (await adapter.call(
|
|
222
|
+
'listRecords',
|
|
223
|
+
{
|
|
224
|
+
object: 'people',
|
|
225
|
+
limit: 2,
|
|
226
|
+
offset: 0
|
|
227
|
+
},
|
|
228
|
+
credentials,
|
|
229
|
+
context
|
|
230
|
+
)) as QueryRecordsResult
|
|
231
|
+
|
|
232
|
+
const page2 = (await adapter.call(
|
|
233
|
+
'listRecords',
|
|
234
|
+
{
|
|
235
|
+
object: 'people',
|
|
236
|
+
limit: 2,
|
|
237
|
+
offset: 2
|
|
238
|
+
},
|
|
239
|
+
credentials,
|
|
240
|
+
context
|
|
241
|
+
)) as QueryRecordsResult
|
|
242
|
+
|
|
243
|
+
console.log(`✓ Page 1: ${page1.records.length} records`)
|
|
244
|
+
console.log(`✓ Page 2: ${page2.records.length} records`)
|
|
245
|
+
|
|
246
|
+
expect(page1).toBeDefined()
|
|
247
|
+
expect(page2).toBeDefined()
|
|
248
|
+
expect(page1.records).toBeInstanceOf(Array)
|
|
249
|
+
expect(page2.records).toBeInstanceOf(Array)
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
it('should list records with sorting', async () => {
|
|
253
|
+
console.log('\n[Test] List records with sorting')
|
|
254
|
+
|
|
255
|
+
const result = (await adapter.call(
|
|
256
|
+
'listRecords',
|
|
257
|
+
{
|
|
258
|
+
object: 'people',
|
|
259
|
+
sorts: [
|
|
260
|
+
{
|
|
261
|
+
attribute: 'name',
|
|
262
|
+
field: 'last_name',
|
|
263
|
+
direction: 'asc'
|
|
264
|
+
}
|
|
265
|
+
],
|
|
266
|
+
limit: 10
|
|
267
|
+
},
|
|
268
|
+
credentials,
|
|
269
|
+
context
|
|
270
|
+
)) as QueryRecordsResult
|
|
271
|
+
|
|
272
|
+
console.log(`✓ Listed ${result.records.length} people (sorted by name)`)
|
|
273
|
+
|
|
274
|
+
expect(result).toBeDefined()
|
|
275
|
+
expect(result.records).toBeInstanceOf(Array)
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
it('should handle invalid record ID gracefully', async () => {
|
|
279
|
+
console.log('\n[Test] Handle invalid record ID')
|
|
280
|
+
|
|
281
|
+
await expect(
|
|
282
|
+
adapter.call(
|
|
283
|
+
'getRecord',
|
|
284
|
+
{
|
|
285
|
+
object: 'people',
|
|
286
|
+
recordId: 'invalid-uuid-12345'
|
|
287
|
+
},
|
|
288
|
+
credentials,
|
|
289
|
+
context
|
|
290
|
+
)
|
|
291
|
+
).rejects.toThrow()
|
|
292
|
+
|
|
293
|
+
console.log('✓ Invalid record ID rejected as expected')
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
it('should handle invalid credentials gracefully', async () => {
|
|
297
|
+
console.log('\n[Test] Handle invalid credentials')
|
|
298
|
+
|
|
299
|
+
const invalidCreds = { apiKey: 'invalid-key-12345' }
|
|
300
|
+
|
|
301
|
+
await expect(
|
|
302
|
+
adapter.call(
|
|
303
|
+
'listRecords',
|
|
304
|
+
{
|
|
305
|
+
object: 'people',
|
|
306
|
+
limit: 10
|
|
307
|
+
},
|
|
308
|
+
invalidCreds,
|
|
309
|
+
context
|
|
310
|
+
)
|
|
311
|
+
).rejects.toThrow()
|
|
312
|
+
|
|
313
|
+
console.log('✓ Invalid credentials rejected as expected')
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
it('should work with companies object type', async () => {
|
|
317
|
+
console.log('\n[Test] List companies')
|
|
318
|
+
|
|
319
|
+
const result = (await adapter.call(
|
|
320
|
+
'listRecords',
|
|
321
|
+
{
|
|
322
|
+
object: 'companies',
|
|
323
|
+
limit: 5
|
|
324
|
+
},
|
|
325
|
+
credentials,
|
|
326
|
+
context
|
|
327
|
+
)) as QueryRecordsResult
|
|
328
|
+
|
|
329
|
+
console.log(`✓ Listed ${result.records.length} companies`)
|
|
330
|
+
|
|
331
|
+
expect(result).toBeDefined()
|
|
332
|
+
expect(result.records).toBeInstanceOf(Array)
|
|
333
|
+
})
|
|
334
|
+
|
|
335
|
+
afterAll(async () => {
|
|
336
|
+
// Clean up test data
|
|
337
|
+
if (createdRecordId) {
|
|
338
|
+
console.log('\n=== Cleanup ===')
|
|
339
|
+
console.log(`Deleting test record: ${createdRecordId}`)
|
|
340
|
+
|
|
341
|
+
try {
|
|
342
|
+
const result = (await adapter.call(
|
|
343
|
+
'deleteRecord',
|
|
344
|
+
{
|
|
345
|
+
object: 'people',
|
|
346
|
+
recordId: createdRecordId
|
|
347
|
+
},
|
|
348
|
+
credentials,
|
|
349
|
+
context
|
|
350
|
+
)) as DeleteRecordResult
|
|
351
|
+
|
|
352
|
+
if (result.success) {
|
|
353
|
+
console.log(`✓ Test record deleted: ${createdRecordId}`)
|
|
354
|
+
} else {
|
|
355
|
+
console.log(`⚠️ Delete returned success=false for record: ${createdRecordId}`)
|
|
356
|
+
}
|
|
357
|
+
} catch (error) {
|
|
358
|
+
console.warn('⚠️ Cleanup failed:', error)
|
|
359
|
+
console.warn(` Manual cleanup may be needed for record: ${createdRecordId}`)
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
})
|
|
363
|
+
})
|