@tellescope/sdk 1.237.2 → 1.237.3
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/lib/cjs/tests/api_tests/database_cascade_delete.test.d.ts +6 -0
- package/lib/cjs/tests/api_tests/database_cascade_delete.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/database_cascade_delete.test.js +298 -0
- package/lib/cjs/tests/api_tests/database_cascade_delete.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/inbox_thread_assignment_updates.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/inbox_thread_assignment_updates.test.js +68 -11
- package/lib/cjs/tests/api_tests/inbox_thread_assignment_updates.test.js.map +1 -1
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +9 -1
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/esm/tests/api_tests/database_cascade_delete.test.d.ts +6 -0
- package/lib/esm/tests/api_tests/database_cascade_delete.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/database_cascade_delete.test.js +294 -0
- package/lib/esm/tests/api_tests/database_cascade_delete.test.js.map +1 -0
- package/lib/esm/tests/api_tests/inbox_thread_assignment_updates.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/inbox_thread_assignment_updates.test.js +68 -11
- package/lib/esm/tests/api_tests/inbox_thread_assignment_updates.test.js.map +1 -1
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +9 -1
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/tests/api_tests/database_cascade_delete.test.ts +193 -0
- package/src/tests/api_tests/inbox_thread_assignment_updates.test.ts +77 -0
- package/src/tests/tests.ts +4 -0
- package/test_generated.pdf +0 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
require('source-map-support').install();
|
|
2
|
+
|
|
3
|
+
import { Session } from "../../sdk"
|
|
4
|
+
import {
|
|
5
|
+
async_test,
|
|
6
|
+
handleAnyError,
|
|
7
|
+
log_header,
|
|
8
|
+
wait,
|
|
9
|
+
} from "@tellescope/testing"
|
|
10
|
+
import { setup_tests } from "../setup"
|
|
11
|
+
|
|
12
|
+
const host = process.env.API_URL || 'http://localhost:8080' as const
|
|
13
|
+
|
|
14
|
+
// Main test function that can be called independently or from main test suite
|
|
15
|
+
export const database_cascade_delete_tests = async ({ sdk, sdkNonAdmin } : { sdk: Session, sdkNonAdmin: Session }) => {
|
|
16
|
+
log_header("Database Cascade Delete Tests")
|
|
17
|
+
|
|
18
|
+
// Test 1: Create database and records, then delete database and verify records are cascade deleted
|
|
19
|
+
await async_test(
|
|
20
|
+
'cascade delete - deleting database deletes all database_records',
|
|
21
|
+
async () => {
|
|
22
|
+
// Create a test database
|
|
23
|
+
const database = await sdk.api.databases.createOne({
|
|
24
|
+
title: `__Test__CascadeDelete_${Date.now()}`,
|
|
25
|
+
fields: [
|
|
26
|
+
{ type: 'Text', label: "Name" },
|
|
27
|
+
{ type: 'Number', label: "Age" },
|
|
28
|
+
],
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
// Create multiple database records
|
|
32
|
+
const records = await sdk.api.database_records.createSome([
|
|
33
|
+
{
|
|
34
|
+
databaseId: database.id,
|
|
35
|
+
values: [
|
|
36
|
+
{ type: 'Text', value: 'Alice', label: 'Name' },
|
|
37
|
+
{ type: 'Number', value: 25, label: 'Age' },
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
databaseId: database.id,
|
|
42
|
+
values: [
|
|
43
|
+
{ type: 'Text', value: 'Bob', label: 'Name' },
|
|
44
|
+
{ type: 'Number', value: 30, label: 'Age' },
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
databaseId: database.id,
|
|
49
|
+
values: [
|
|
50
|
+
{ type: 'Text', value: 'Charlie', label: 'Name' },
|
|
51
|
+
{ type: 'Number', value: 35, label: 'Age' },
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
])
|
|
55
|
+
|
|
56
|
+
const recordIds = records.created.map(r => r.id)
|
|
57
|
+
console.log(`Created database ${database.id} with ${recordIds.length} records`)
|
|
58
|
+
|
|
59
|
+
// Verify records exist before deletion
|
|
60
|
+
const recordsBefore = await sdk.api.database_records.getSome({ filter: { databaseId: database.id } })
|
|
61
|
+
if (recordsBefore.length !== 3) {
|
|
62
|
+
throw new Error(`Expected 3 records before delete, got ${recordsBefore.length}`)
|
|
63
|
+
}
|
|
64
|
+
console.log(`Verified ${recordsBefore.length} records exist before deletion`)
|
|
65
|
+
|
|
66
|
+
// Delete the database
|
|
67
|
+
await sdk.api.databases.deleteOne(database.id)
|
|
68
|
+
console.log(`Deleted database ${database.id}`)
|
|
69
|
+
|
|
70
|
+
// Wait a moment for cascade delete to propagate
|
|
71
|
+
await wait(undefined, 500)
|
|
72
|
+
|
|
73
|
+
// Verify all records were cascade deleted
|
|
74
|
+
const recordsAfter = await sdk.api.database_records.getSome({ filter: { databaseId: database.id } })
|
|
75
|
+
|
|
76
|
+
if (recordsAfter.length !== 0) {
|
|
77
|
+
throw new Error(`Expected 0 records after cascade delete, got ${recordsAfter.length}`)
|
|
78
|
+
}
|
|
79
|
+
console.log(`✓ Verified all records were cascade deleted`)
|
|
80
|
+
|
|
81
|
+
// Also verify individual record fetches return 404
|
|
82
|
+
for (const recordId of recordIds) {
|
|
83
|
+
try {
|
|
84
|
+
await sdk.api.database_records.getOne(recordId)
|
|
85
|
+
throw new Error(`Record ${recordId} should have been deleted but was still found`)
|
|
86
|
+
} catch (err: any) {
|
|
87
|
+
if (!err.message?.includes('Could not find') && !err.message?.includes('404')) {
|
|
88
|
+
throw new Error(`Unexpected error fetching deleted record: ${err.message}`)
|
|
89
|
+
}
|
|
90
|
+
// Expected: record not found
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
console.log(`✓ Verified individual record fetches return not found`)
|
|
94
|
+
|
|
95
|
+
return true
|
|
96
|
+
},
|
|
97
|
+
{ onResult: (result) => result === true }
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
// Test 2: Verify database with no records can be deleted without error
|
|
101
|
+
await async_test(
|
|
102
|
+
'cascade delete - deleting empty database works',
|
|
103
|
+
async () => {
|
|
104
|
+
const database = await sdk.api.databases.createOne({
|
|
105
|
+
title: `__Test__EmptyDB_${Date.now()}`,
|
|
106
|
+
fields: [{ type: 'Text', label: "Field" }],
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
// Delete immediately without adding records
|
|
110
|
+
await sdk.api.databases.deleteOne(database.id)
|
|
111
|
+
|
|
112
|
+
// Verify database is gone
|
|
113
|
+
try {
|
|
114
|
+
await sdk.api.databases.getOne(database.id)
|
|
115
|
+
throw new Error('Database should have been deleted')
|
|
116
|
+
} catch (err: any) {
|
|
117
|
+
if (!err.message?.includes('Could not find') && !err.message?.includes('404')) {
|
|
118
|
+
throw new Error(`Unexpected error: ${err.message}`)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return true
|
|
123
|
+
},
|
|
124
|
+
{ onResult: (result) => result === true }
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
// Test 3: Verify records from other databases are not affected
|
|
128
|
+
await async_test(
|
|
129
|
+
'cascade delete - only affects records from deleted database',
|
|
130
|
+
async () => {
|
|
131
|
+
// Create two databases
|
|
132
|
+
const database1 = await sdk.api.databases.createOne({
|
|
133
|
+
title: `__Test__DB1_${Date.now()}`,
|
|
134
|
+
fields: [{ type: 'Text', label: "Value" }],
|
|
135
|
+
})
|
|
136
|
+
const database2 = await sdk.api.databases.createOne({
|
|
137
|
+
title: `__Test__DB2_${Date.now()}`,
|
|
138
|
+
fields: [{ type: 'Text', label: "Value" }],
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
// Create records in both databases
|
|
142
|
+
await sdk.api.database_records.createOne({
|
|
143
|
+
databaseId: database1.id,
|
|
144
|
+
values: [{ type: 'Text', value: 'DB1 Record', label: 'Value' }],
|
|
145
|
+
})
|
|
146
|
+
const db2Record = await sdk.api.database_records.createOne({
|
|
147
|
+
databaseId: database2.id,
|
|
148
|
+
values: [{ type: 'Text', value: 'DB2 Record', label: 'Value' }],
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
// Delete database1
|
|
152
|
+
await sdk.api.databases.deleteOne(database1.id)
|
|
153
|
+
await wait(undefined, 500)
|
|
154
|
+
|
|
155
|
+
// Verify database2's record still exists
|
|
156
|
+
const db2RecordAfter = await sdk.api.database_records.getOne(db2Record.id)
|
|
157
|
+
if (!db2RecordAfter) {
|
|
158
|
+
throw new Error('Database2 record should still exist')
|
|
159
|
+
}
|
|
160
|
+
console.log(`✓ Verified database2 record was not affected by database1 deletion`)
|
|
161
|
+
|
|
162
|
+
// Cleanup database2
|
|
163
|
+
await sdk.api.databases.deleteOne(database2.id)
|
|
164
|
+
|
|
165
|
+
return true
|
|
166
|
+
},
|
|
167
|
+
{ onResult: (result) => result === true }
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
console.log("✅ All Database Cascade Delete tests passed!")
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Allow running this test file independently
|
|
174
|
+
if (require.main === module) {
|
|
175
|
+
console.log(`🌐 Using API URL: ${host}`)
|
|
176
|
+
const sdk = new Session({ host })
|
|
177
|
+
const sdkNonAdmin = new Session({ host })
|
|
178
|
+
|
|
179
|
+
const runTests = async () => {
|
|
180
|
+
await setup_tests(sdk, sdkNonAdmin)
|
|
181
|
+
await database_cascade_delete_tests({ sdk, sdkNonAdmin })
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
runTests()
|
|
185
|
+
.then(() => {
|
|
186
|
+
console.log("✅ Database cascade delete test suite completed successfully")
|
|
187
|
+
process.exit(0)
|
|
188
|
+
})
|
|
189
|
+
.catch((error) => {
|
|
190
|
+
console.error("❌ Database cascade delete test suite failed:", error)
|
|
191
|
+
process.exit(1)
|
|
192
|
+
})
|
|
193
|
+
}
|
|
@@ -503,6 +503,83 @@ export const inbox_thread_assignment_updates_tests = async ({ sdk, sdkNonAdmin }
|
|
|
503
503
|
assert(emptyIdsResult.threads.length >= 3, 'Empty ids array should not filter (return all threads)')
|
|
504
504
|
console.log("✅ ids filter empty array test passed")
|
|
505
505
|
|
|
506
|
+
// Test 24: sortBy parameter - default behavior (timestamp)
|
|
507
|
+
console.log("Testing sortBy parameter - default behavior...")
|
|
508
|
+
|
|
509
|
+
// Create threads with controlled timestamps for sort testing
|
|
510
|
+
const sortTestBaseTime = Date.now()
|
|
511
|
+
const sortThread1 = await sdk.api.inbox_threads.createOne({
|
|
512
|
+
...defaultThreadFields,
|
|
513
|
+
type: "SMS",
|
|
514
|
+
title: "Sort Test Thread 1",
|
|
515
|
+
threadId: `sort-test-1-${timestamp}`,
|
|
516
|
+
phoneNumber: "+15555550001",
|
|
517
|
+
enduserPhoneNumber: "+15555550002",
|
|
518
|
+
timestamp: new Date(sortTestBaseTime - 3000), // oldest timestamp
|
|
519
|
+
outboundTimestamp: new Date(sortTestBaseTime), // newest outboundTimestamp
|
|
520
|
+
})
|
|
521
|
+
|
|
522
|
+
const sortThread2 = await sdk.api.inbox_threads.createOne({
|
|
523
|
+
...defaultThreadFields,
|
|
524
|
+
type: "SMS",
|
|
525
|
+
title: "Sort Test Thread 2",
|
|
526
|
+
threadId: `sort-test-2-${timestamp}`,
|
|
527
|
+
phoneNumber: "+15555550003",
|
|
528
|
+
enduserPhoneNumber: "+15555550004",
|
|
529
|
+
timestamp: new Date(sortTestBaseTime - 1000), // newest timestamp
|
|
530
|
+
outboundTimestamp: new Date(sortTestBaseTime - 3000), // oldest outboundTimestamp
|
|
531
|
+
})
|
|
532
|
+
|
|
533
|
+
const sortThread3 = await sdk.api.inbox_threads.createOne({
|
|
534
|
+
...defaultThreadFields,
|
|
535
|
+
type: "SMS",
|
|
536
|
+
title: "Sort Test Thread 3",
|
|
537
|
+
threadId: `sort-test-3-${timestamp}`,
|
|
538
|
+
phoneNumber: "+15555550005",
|
|
539
|
+
enduserPhoneNumber: "+15555550006",
|
|
540
|
+
timestamp: new Date(sortTestBaseTime - 2000), // middle timestamp
|
|
541
|
+
outboundTimestamp: new Date(sortTestBaseTime - 2000), // middle outboundTimestamp
|
|
542
|
+
})
|
|
543
|
+
|
|
544
|
+
// Test default sort (should be by timestamp descending)
|
|
545
|
+
const defaultSortResult = await sdk.api.inbox_threads.load_threads({
|
|
546
|
+
ids: [sortThread1.id, sortThread2.id, sortThread3.id]
|
|
547
|
+
})
|
|
548
|
+
assert(defaultSortResult.threads.length === 3, 'Should return 3 sort test threads')
|
|
549
|
+
assert(defaultSortResult.threads[0].id === sortThread2.id, 'Default sort: newest timestamp should be first')
|
|
550
|
+
assert(defaultSortResult.threads[1].id === sortThread3.id, 'Default sort: middle timestamp should be second')
|
|
551
|
+
assert(defaultSortResult.threads[2].id === sortThread1.id, 'Default sort: oldest timestamp should be last')
|
|
552
|
+
console.log("✅ sortBy default behavior test passed")
|
|
553
|
+
|
|
554
|
+
// Test 25: sortBy='timestamp' explicit
|
|
555
|
+
console.log("Testing sortBy='timestamp' explicit...")
|
|
556
|
+
const timestampSortResult = await sdk.api.inbox_threads.load_threads({
|
|
557
|
+
ids: [sortThread1.id, sortThread2.id, sortThread3.id],
|
|
558
|
+
sortBy: 'timestamp'
|
|
559
|
+
})
|
|
560
|
+
assert(timestampSortResult.threads[0].id === sortThread2.id, 'Explicit timestamp sort: newest should be first')
|
|
561
|
+
assert(timestampSortResult.threads[1].id === sortThread3.id, 'Explicit timestamp sort: middle should be second')
|
|
562
|
+
assert(timestampSortResult.threads[2].id === sortThread1.id, 'Explicit timestamp sort: oldest should be last')
|
|
563
|
+
console.log("✅ sortBy='timestamp' test passed")
|
|
564
|
+
|
|
565
|
+
// Test 26: sortBy='outboundTimestamp'
|
|
566
|
+
console.log("Testing sortBy='outboundTimestamp'...")
|
|
567
|
+
const outboundSortResult = await sdk.api.inbox_threads.load_threads({
|
|
568
|
+
ids: [sortThread1.id, sortThread2.id, sortThread3.id],
|
|
569
|
+
sortBy: 'outboundTimestamp'
|
|
570
|
+
})
|
|
571
|
+
assert(outboundSortResult.threads[0].id === sortThread1.id, 'OutboundTimestamp sort: newest outbound should be first')
|
|
572
|
+
assert(outboundSortResult.threads[1].id === sortThread3.id, 'OutboundTimestamp sort: middle outbound should be second')
|
|
573
|
+
assert(outboundSortResult.threads[2].id === sortThread2.id, 'OutboundTimestamp sort: oldest outbound should be last')
|
|
574
|
+
console.log("✅ sortBy='outboundTimestamp' test passed")
|
|
575
|
+
|
|
576
|
+
// Cleanup sort test threads
|
|
577
|
+
await Promise.all([
|
|
578
|
+
sdk.api.inbox_threads.deleteOne(sortThread1.id),
|
|
579
|
+
sdk.api.inbox_threads.deleteOne(sortThread2.id),
|
|
580
|
+
sdk.api.inbox_threads.deleteOne(sortThread3.id),
|
|
581
|
+
])
|
|
582
|
+
|
|
506
583
|
console.log("🎉 All InboxThread assignment update tests passed!")
|
|
507
584
|
|
|
508
585
|
} finally {
|
package/src/tests/tests.ts
CHANGED
|
@@ -77,6 +77,7 @@ import { custom_aggregation_tests } from "./api_tests/custom_aggregation.test";
|
|
|
77
77
|
import { bulk_assignment_tests } from "./api_tests/bulk_assignment.test";
|
|
78
78
|
import { managed_content_enduser_access_tests } from "./api_tests/managed_content_enduser_access.test";
|
|
79
79
|
import { auto_merge_form_submission_tests } from "./api_tests/auto_merge_form_submission.test";
|
|
80
|
+
import { database_cascade_delete_tests } from "./api_tests/database_cascade_delete.test";
|
|
80
81
|
|
|
81
82
|
const UniquenessViolationMessage = 'Uniqueness Violation'
|
|
82
83
|
|
|
@@ -5835,6 +5836,9 @@ export const databases_tests = async () => {
|
|
|
5835
5836
|
sdk.api.databases.deleteOne(database.id),
|
|
5836
5837
|
sdk.api.databases.deleteOne(databaseNoRead.id),
|
|
5837
5838
|
])
|
|
5839
|
+
|
|
5840
|
+
// Run cascade delete tests
|
|
5841
|
+
await database_cascade_delete_tests({ sdk, sdkNonAdmin })
|
|
5838
5842
|
}
|
|
5839
5843
|
|
|
5840
5844
|
export const filter_by_date_tests = async () => {
|
package/test_generated.pdf
CHANGED
|
Binary file
|