@tellescope/sdk 1.237.2 → 1.237.4
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/enduser.d.ts +1 -1
- 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 +173 -11
- package/lib/cjs/tests/api_tests/inbox_thread_assignment_updates.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/inbox_thread_status_preservation.test.d.ts +6 -0
- package/lib/cjs/tests/api_tests/inbox_thread_status_preservation.test.d.ts.map +1 -0
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +30 -3
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/esm/enduser.d.ts +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 +173 -11
- package/lib/esm/tests/api_tests/inbox_thread_assignment_updates.test.js.map +1 -1
- package/lib/esm/tests/api_tests/inbox_thread_status_preservation.test.d.ts +6 -0
- package/lib/esm/tests/api_tests/inbox_thread_status_preservation.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/inbox_thread_status_preservation.test.js +435 -0
- package/lib/esm/tests/api_tests/inbox_thread_status_preservation.test.js.map +1 -0
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +30 -3
- 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 +158 -0
- package/src/tests/tests.ts +23 -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,164 @@ 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
|
+
|
|
583
|
+
// ========== InboxStatus Preservation Tests ==========
|
|
584
|
+
// These tests verify that outbound messages do NOT reset inboxStatus
|
|
585
|
+
|
|
586
|
+
// Test 27: Outbound SMS should NOT reset inboxStatus
|
|
587
|
+
console.log("Testing outbound SMS should NOT reset inboxStatus...")
|
|
588
|
+
|
|
589
|
+
const statusTestSMS1 = await sdk.api.sms_messages.createOne({
|
|
590
|
+
message: "Inbound test message for status test",
|
|
591
|
+
enduserId: testEnduser.id,
|
|
592
|
+
inbound: true,
|
|
593
|
+
phoneNumber: "+15555559999",
|
|
594
|
+
enduserPhoneNumber: "+15555559876",
|
|
595
|
+
logOnly: true,
|
|
596
|
+
})
|
|
597
|
+
|
|
598
|
+
// Build threads using reset_threads + build_threads pattern
|
|
599
|
+
const statusTestFrom = new Date(Date.now() - 60000)
|
|
600
|
+
await sdk.api.inbox_threads.reset_threads()
|
|
601
|
+
await sdk.api.inbox_threads.build_threads({ from: statusTestFrom, to: new Date() })
|
|
602
|
+
|
|
603
|
+
const statusTestThreads = await sdk.api.inbox_threads.load_threads({})
|
|
604
|
+
const statusTestThread = statusTestThreads.threads.find(t =>
|
|
605
|
+
t.type === 'SMS' && t.enduserIds.includes(testEnduser.id) && t.phoneNumber === "+15555559999"
|
|
606
|
+
)
|
|
607
|
+
assert(!!statusTestThread, "Status test SMS thread should be created")
|
|
608
|
+
assert(statusTestThread!.inboxStatus === 'New', `Initial status should be 'New', got '${statusTestThread!.inboxStatus}'`)
|
|
609
|
+
|
|
610
|
+
// Update thread status to "Resolved"
|
|
611
|
+
await sdk.api.inbox_threads.updateOne(statusTestThread!.id, { inboxStatus: "Resolved" })
|
|
612
|
+
|
|
613
|
+
// Create outbound SMS (should NOT reset status)
|
|
614
|
+
const statusTestSMS2 = await sdk.api.sms_messages.createOne({
|
|
615
|
+
message: "Outbound reply - should not reset status",
|
|
616
|
+
enduserId: testEnduser.id,
|
|
617
|
+
inbound: false,
|
|
618
|
+
phoneNumber: "+15555559999",
|
|
619
|
+
enduserPhoneNumber: "+15555559876",
|
|
620
|
+
logOnly: true,
|
|
621
|
+
})
|
|
622
|
+
|
|
623
|
+
// Rebuild threads - status should remain "Resolved"
|
|
624
|
+
await sdk.api.inbox_threads.build_threads({ from: statusTestFrom, to: new Date() })
|
|
625
|
+
|
|
626
|
+
const threadAfterOutbound = (await sdk.api.inbox_threads.load_threads({ ids: [statusTestThread!.id] })).threads[0]
|
|
627
|
+
assert(threadAfterOutbound.inboxStatus === 'Resolved', `Status should remain 'Resolved' after outbound message, got '${threadAfterOutbound.inboxStatus}'`)
|
|
628
|
+
assert(!!threadAfterOutbound.outboundTimestamp, "outboundTimestamp should be set after outbound message")
|
|
629
|
+
|
|
630
|
+
console.log("✅ Outbound SMS does NOT reset inboxStatus test passed")
|
|
631
|
+
|
|
632
|
+
// Test 28: New inbound SMS SHOULD update inboxStatus
|
|
633
|
+
console.log("Testing new inbound SMS SHOULD update inboxStatus...")
|
|
634
|
+
|
|
635
|
+
// Wait to ensure ObjectId timestamps are in different seconds (MongoDB ObjectIds have second-level precision)
|
|
636
|
+
await new Promise(resolve => setTimeout(resolve, 1100))
|
|
637
|
+
|
|
638
|
+
const statusTestSMS3 = await sdk.api.sms_messages.createOne({
|
|
639
|
+
message: "New inbound - should update status",
|
|
640
|
+
enduserId: testEnduser.id,
|
|
641
|
+
inbound: true,
|
|
642
|
+
phoneNumber: "+15555559999",
|
|
643
|
+
enduserPhoneNumber: "+15555559876",
|
|
644
|
+
inboxStatus: "New",
|
|
645
|
+
logOnly: true,
|
|
646
|
+
})
|
|
647
|
+
|
|
648
|
+
// Rebuild threads - status SHOULD be updated from new inbound
|
|
649
|
+
await sdk.api.inbox_threads.build_threads({ from: statusTestFrom, to: new Date() })
|
|
650
|
+
|
|
651
|
+
const threadAfterNewInbound = (await sdk.api.inbox_threads.load_threads({ ids: [statusTestThread!.id] })).threads[0]
|
|
652
|
+
assert(threadAfterNewInbound.inboxStatus === 'New', `Status SHOULD be 'New' after new inbound message, got '${threadAfterNewInbound.inboxStatus}'`)
|
|
653
|
+
|
|
654
|
+
console.log("✅ New inbound SMS DOES update inboxStatus test passed")
|
|
655
|
+
|
|
656
|
+
// Cleanup status preservation test resources
|
|
657
|
+
await Promise.all([
|
|
658
|
+
sdk.api.sms_messages.deleteOne(statusTestSMS1.id),
|
|
659
|
+
sdk.api.sms_messages.deleteOne(statusTestSMS2.id),
|
|
660
|
+
sdk.api.sms_messages.deleteOne(statusTestSMS3.id),
|
|
661
|
+
sdk.api.inbox_threads.deleteOne(statusTestThread!.id),
|
|
662
|
+
])
|
|
663
|
+
|
|
506
664
|
console.log("🎉 All InboxThread assignment update tests passed!")
|
|
507
665
|
|
|
508
666
|
} 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 () => {
|
|
@@ -12364,6 +12368,25 @@ const replace_enduser_template_values_tests = async () => {
|
|
|
12364
12368
|
const d = Date.now()
|
|
12365
12369
|
assert(replace_enduser_template_values(d as any, enduser) === d as any, 'fail non-string', 'non-string')
|
|
12366
12370
|
|
|
12371
|
+
// Test height/weight subfields with values present
|
|
12372
|
+
const enduserWithVitals = await sdk.api.endusers.createOne({
|
|
12373
|
+
fname: "Vitals",
|
|
12374
|
+
height: { value: 72, unit: 'inches' },
|
|
12375
|
+
weight: { value: 180, unit: 'lbs' }
|
|
12376
|
+
})
|
|
12377
|
+
|
|
12378
|
+
assert(replace_enduser_template_values('{{enduser.height.value}}', enduserWithVitals) === '72', 'fail height.value', 'height.value')
|
|
12379
|
+
assert(replace_enduser_template_values('{{enduser.height.unit}}', enduserWithVitals) === 'inches', 'fail height.unit', 'height.unit')
|
|
12380
|
+
assert(replace_enduser_template_values('{{enduser.weight.value}}', enduserWithVitals) === '180', 'fail weight.value', 'weight.value')
|
|
12381
|
+
assert(replace_enduser_template_values('{{enduser.weight.unit}}', enduserWithVitals) === 'lbs', 'fail weight.unit', 'weight.unit')
|
|
12382
|
+
|
|
12383
|
+
// Test undefined safeguards - enduser without height/weight should return empty string
|
|
12384
|
+
assert(replace_enduser_template_values('{{enduser.height.value}}', enduser) === '', 'fail undefined height.value', 'undefined height.value')
|
|
12385
|
+
assert(replace_enduser_template_values('{{enduser.height.unit}}', enduser) === '', 'fail undefined height.unit', 'undefined height.unit')
|
|
12386
|
+
assert(replace_enduser_template_values('{{enduser.weight.value}}', enduser) === '', 'fail undefined weight.value', 'undefined weight.value')
|
|
12387
|
+
assert(replace_enduser_template_values('{{enduser.weight.unit}}', enduser) === '', 'fail undefined weight.unit', 'undefined weight.unit')
|
|
12388
|
+
|
|
12389
|
+
await sdk.api.endusers.deleteOne(enduserWithVitals.id)
|
|
12367
12390
|
await sdk.api.endusers.deleteOne(enduser.id)
|
|
12368
12391
|
}
|
|
12369
12392
|
|
package/test_generated.pdf
CHANGED
|
Binary file
|