@tellescope/sdk 1.246.1 → 1.247.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/lib/cjs/sdk.d.ts +1 -0
- package/lib/cjs/sdk.d.ts.map +1 -1
- package/lib/cjs/sdk.js.map +1 -1
- package/lib/cjs/tests/api_tests/account_switcher.test.d.ts +6 -0
- package/lib/cjs/tests/api_tests/account_switcher.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/account_switcher.test.js +445 -0
- package/lib/cjs/tests/api_tests/account_switcher.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/calendar_events_bulk_update.test.d.ts +5 -0
- package/lib/cjs/tests/api_tests/calendar_events_bulk_update.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/calendar_events_bulk_update.test.js +483 -0
- package/lib/cjs/tests/api_tests/calendar_events_bulk_update.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/email_utils.test.d.ts +2 -0
- package/lib/cjs/tests/api_tests/email_utils.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/email_utils.test.js +141 -0
- package/lib/cjs/tests/api_tests/email_utils.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/mdb_sort.test.d.ts +6 -0
- package/lib/cjs/tests/api_tests/mdb_sort.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/mdb_sort.test.js +370 -0
- package/lib/cjs/tests/api_tests/mdb_sort.test.js.map +1 -0
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +156 -128
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/esm/sdk.d.ts +1 -0
- package/lib/esm/sdk.d.ts.map +1 -1
- package/lib/esm/sdk.js.map +1 -1
- package/lib/esm/tests/api_tests/account_switcher.test.d.ts +6 -0
- package/lib/esm/tests/api_tests/account_switcher.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/account_switcher.test.js +438 -0
- package/lib/esm/tests/api_tests/account_switcher.test.js.map +1 -0
- package/lib/esm/tests/api_tests/calendar_events_bulk_update.test.d.ts +5 -0
- package/lib/esm/tests/api_tests/calendar_events_bulk_update.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/calendar_events_bulk_update.test.js +479 -0
- package/lib/esm/tests/api_tests/calendar_events_bulk_update.test.js.map +1 -0
- package/lib/esm/tests/api_tests/email_utils.test.d.ts +2 -0
- package/lib/esm/tests/api_tests/email_utils.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/email_utils.test.js +137 -0
- package/lib/esm/tests/api_tests/email_utils.test.js.map +1 -0
- package/lib/esm/tests/api_tests/mdb_sort.test.d.ts +6 -0
- package/lib/esm/tests/api_tests/mdb_sort.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/mdb_sort.test.js +366 -0
- package/lib/esm/tests/api_tests/mdb_sort.test.js.map +1 -0
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +156 -128
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/sdk.ts +1 -0
- package/src/tests/api_tests/calendar_events_bulk_update.test.ts +418 -0
- package/src/tests/api_tests/mdb_sort.test.ts +259 -0
- package/src/tests/api_tests/organization_settings_duplicates.test.ts +201 -0
- package/src/tests/tests.ts +30 -2
- package/test_generated.pdf +0 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
require('source-map-support').install();
|
|
2
|
+
|
|
3
|
+
import { Session } from "../../sdk"
|
|
4
|
+
import {
|
|
5
|
+
async_test,
|
|
6
|
+
log_header,
|
|
7
|
+
} from "@tellescope/testing"
|
|
8
|
+
import { setup_tests } from "../setup"
|
|
9
|
+
|
|
10
|
+
const host = process.env.API_URL || 'http://localhost:8080' as const
|
|
11
|
+
|
|
12
|
+
export const organization_settings_duplicates_tests = async ({ sdk, sdkNonAdmin } : { sdk: Session, sdkNonAdmin: Session }) => {
|
|
13
|
+
log_header("Organization Settings Duplicate Validation Tests")
|
|
14
|
+
|
|
15
|
+
const orgId = sdk.userInfo.businessId
|
|
16
|
+
|
|
17
|
+
// === A. replaceObjectFields: false (merge/push behavior) ===
|
|
18
|
+
|
|
19
|
+
// A1. Duplicate tags via merge
|
|
20
|
+
await sdk.api.organizations.updateOne(orgId, {
|
|
21
|
+
settings: { endusers: { tags: ['tag1', 'tag2'] } }
|
|
22
|
+
}, { replaceObjectFields: true })
|
|
23
|
+
|
|
24
|
+
await async_test(
|
|
25
|
+
"Merge tags rejects duplicates (tag2 appears in both old and new)",
|
|
26
|
+
() => sdk.api.organizations.updateOne(orgId, {
|
|
27
|
+
settings: { endusers: { tags: ['tag2', 'tag3'] } }
|
|
28
|
+
}),
|
|
29
|
+
{ shouldError: true, onError: (e: { message: string }) => e.message.includes('Duplicate value in settings.endusers.tags') }
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
// A2. Duplicate customFields via merge
|
|
33
|
+
await sdk.api.organizations.updateOne(orgId, {
|
|
34
|
+
settings: { endusers: { customFields: [{ type: 'Text' as const, field: 'myField', info: {} }] } }
|
|
35
|
+
}, { replaceObjectFields: true })
|
|
36
|
+
|
|
37
|
+
await async_test(
|
|
38
|
+
"Merge customFields rejects duplicate field name",
|
|
39
|
+
() => sdk.api.organizations.updateOne(orgId, {
|
|
40
|
+
settings: { endusers: { customFields: [{ type: 'Text' as const, field: 'myField', info: {} }] } }
|
|
41
|
+
}),
|
|
42
|
+
{ shouldError: true, onError: (e: { message: string }) => e.message.includes('Duplicate field in settings.endusers.customFields') }
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
// A3. Duplicate builtinFields via merge
|
|
46
|
+
await sdk.api.organizations.updateOne(orgId, {
|
|
47
|
+
settings: { endusers: { builtinFields: [{ field: 'fname', label: 'First Name' }] } }
|
|
48
|
+
}, { replaceObjectFields: true })
|
|
49
|
+
|
|
50
|
+
await async_test(
|
|
51
|
+
"Merge builtinFields rejects duplicate field name",
|
|
52
|
+
() => sdk.api.organizations.updateOne(orgId, {
|
|
53
|
+
settings: { endusers: { builtinFields: [{ field: 'fname', label: 'First Name Copy' }] } }
|
|
54
|
+
}),
|
|
55
|
+
{ shouldError: true, onError: (e: { message: string }) => e.message.includes('Duplicate field in settings.endusers.builtinFields') }
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
// A4. Duplicate dontRecordCallsToPhone via merge
|
|
59
|
+
await sdk.api.organizations.updateOne(orgId, {
|
|
60
|
+
settings: { endusers: { dontRecordCallsToPhone: ['+15551234567'] } }
|
|
61
|
+
}, { replaceObjectFields: true })
|
|
62
|
+
|
|
63
|
+
await async_test(
|
|
64
|
+
"Merge dontRecordCallsToPhone rejects duplicates",
|
|
65
|
+
() => sdk.api.organizations.updateOne(orgId, {
|
|
66
|
+
settings: { endusers: { dontRecordCallsToPhone: ['+15551234567'] } }
|
|
67
|
+
}),
|
|
68
|
+
{ shouldError: true, onError: (e: { message: string }) => e.message.includes('Duplicate value in settings.endusers.dontRecordCallsToPhone') }
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
// A5. Duplicate cancelReasons via merge
|
|
72
|
+
await sdk.api.organizations.updateOne(orgId, {
|
|
73
|
+
settings: { calendar: { cancelReasons: ['No show'] } }
|
|
74
|
+
}, { replaceObjectFields: true })
|
|
75
|
+
|
|
76
|
+
await async_test(
|
|
77
|
+
"Merge cancelReasons rejects duplicates",
|
|
78
|
+
() => sdk.api.organizations.updateOne(orgId, {
|
|
79
|
+
settings: { calendar: { cancelReasons: ['No show'] } }
|
|
80
|
+
}),
|
|
81
|
+
{ shouldError: true, onError: (e: { message: string }) => e.message.includes('Duplicate value in settings.calendar.cancelReasons') }
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
// === B. replaceObjectFields: true (full replacement) ===
|
|
85
|
+
|
|
86
|
+
// B1. Replace that grows the array with dupes should be rejected
|
|
87
|
+
await sdk.api.organizations.updateOne(orgId, {
|
|
88
|
+
settings: { endusers: { tags: ['tag1'] } }
|
|
89
|
+
}, { replaceObjectFields: true })
|
|
90
|
+
|
|
91
|
+
await async_test(
|
|
92
|
+
"Replace tags rejects duplicates when array grows",
|
|
93
|
+
() => sdk.api.organizations.updateOne(orgId, {
|
|
94
|
+
settings: { endusers: { tags: ['tag1', 'tag1', 'tag2'] } }
|
|
95
|
+
}, { replaceObjectFields: true }),
|
|
96
|
+
{ shouldError: true, onError: (e: { message: string }) => e.message.includes('Duplicate value in settings.endusers.tags') }
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
// B2. Replace with dupes that shrinks the array should be allowed
|
|
100
|
+
await sdk.api.organizations.updateOne(orgId, {
|
|
101
|
+
settings: { endusers: { tags: ['a', 'b', 'c'] } }
|
|
102
|
+
}, { replaceObjectFields: true })
|
|
103
|
+
|
|
104
|
+
await async_test(
|
|
105
|
+
"Replace with dupes that shrinks array succeeds",
|
|
106
|
+
() => sdk.api.organizations.updateOne(orgId, {
|
|
107
|
+
settings: { endusers: { tags: ['a', 'a'] } }
|
|
108
|
+
}, { replaceObjectFields: true }),
|
|
109
|
+
{ shouldError: false, onResult: () => true }
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
// B3. Replace with unique values always succeeds
|
|
113
|
+
await async_test(
|
|
114
|
+
"Replace tags succeeds with unique values",
|
|
115
|
+
() => sdk.api.organizations.updateOne(orgId, {
|
|
116
|
+
settings: { endusers: { tags: ['tag1', 'tag2'] } }
|
|
117
|
+
}, { replaceObjectFields: true }),
|
|
118
|
+
{ shouldError: false, onResult: () => true }
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
// === C. Non-duplicate updates still succeed ===
|
|
122
|
+
|
|
123
|
+
// C1. Set initial tags then add different tags via merge
|
|
124
|
+
await sdk.api.organizations.updateOne(orgId, {
|
|
125
|
+
settings: { endusers: { tags: ['tagA', 'tagB'] } }
|
|
126
|
+
}, { replaceObjectFields: true })
|
|
127
|
+
|
|
128
|
+
await async_test(
|
|
129
|
+
"Merge with unique new tags succeeds",
|
|
130
|
+
() => sdk.api.organizations.updateOne(orgId, {
|
|
131
|
+
settings: { endusers: { tags: ['tagC', 'tagD'] } }
|
|
132
|
+
}),
|
|
133
|
+
{ shouldError: false, onResult: () => true }
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
// C2. Replace with unique values
|
|
137
|
+
await async_test(
|
|
138
|
+
"Replace customFields with unique values succeeds",
|
|
139
|
+
() => sdk.api.organizations.updateOne(orgId, {
|
|
140
|
+
settings: { endusers: { customFields: [
|
|
141
|
+
{ type: 'Text' as const, field: 'field1', info: {} },
|
|
142
|
+
{ type: 'Text' as const, field: 'field2', info: {} },
|
|
143
|
+
] } }
|
|
144
|
+
}, { replaceObjectFields: true }),
|
|
145
|
+
{ shouldError: false, onResult: () => true }
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
// C3. Updating another settings field preserves pre-existing duplicates
|
|
149
|
+
// First set tags to a longer array, then shrink to a dupe array (shrinking is allowed)
|
|
150
|
+
await sdk.api.organizations.updateOne(orgId, {
|
|
151
|
+
settings: { endusers: { tags: ['dupeTag', 'otherTag', 'anotherTag'] } }
|
|
152
|
+
}, { replaceObjectFields: true })
|
|
153
|
+
await sdk.api.organizations.updateOne(orgId, {
|
|
154
|
+
settings: { endusers: { tags: ['dupeTag', 'dupeTag'] } }
|
|
155
|
+
}, { replaceObjectFields: true })
|
|
156
|
+
|
|
157
|
+
await async_test(
|
|
158
|
+
"Updating cancelReasons succeeds even when tags has pre-existing duplicates",
|
|
159
|
+
() => sdk.api.organizations.updateOne(orgId, {
|
|
160
|
+
settings: { calendar: { cancelReasons: ['new reason'] } }
|
|
161
|
+
}, { replaceObjectFields: true }),
|
|
162
|
+
{ shouldError: false, onResult: () => true }
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
// Clean up settings to avoid affecting other tests
|
|
166
|
+
await sdk.api.organizations.updateOne(orgId, {
|
|
167
|
+
settings: {
|
|
168
|
+
endusers: {
|
|
169
|
+
tags: [],
|
|
170
|
+
customFields: [],
|
|
171
|
+
builtinFields: [],
|
|
172
|
+
dontRecordCallsToPhone: [],
|
|
173
|
+
},
|
|
174
|
+
calendar: {
|
|
175
|
+
cancelReasons: [],
|
|
176
|
+
},
|
|
177
|
+
}
|
|
178
|
+
}, { replaceObjectFields: true })
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Allow running this test file independently
|
|
182
|
+
if (require.main === module) {
|
|
183
|
+
console.log(`Using API URL: ${host}`)
|
|
184
|
+
const sdk = new Session({ host })
|
|
185
|
+
const sdkNonAdmin = new Session({ host })
|
|
186
|
+
|
|
187
|
+
const runTests = async () => {
|
|
188
|
+
await setup_tests(sdk, sdkNonAdmin)
|
|
189
|
+
await organization_settings_duplicates_tests({ sdk, sdkNonAdmin })
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
runTests()
|
|
193
|
+
.then(() => {
|
|
194
|
+
console.log("✅ Organization settings duplicate validation tests completed successfully")
|
|
195
|
+
process.exit(0)
|
|
196
|
+
})
|
|
197
|
+
.catch((error) => {
|
|
198
|
+
console.error("❌ Organization settings duplicate validation tests failed:", error)
|
|
199
|
+
process.exit(1)
|
|
200
|
+
})
|
|
201
|
+
}
|
package/src/tests/tests.ts
CHANGED
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
import { Session, APIQuery, EnduserSession } from "../sdk"
|
|
38
38
|
import { enduser_observations_acknowledge_tests } from "./api_tests/enduser_observations_acknowledge.test"
|
|
39
39
|
import { get_some_projection_tests } from "./api_tests/get_some_projection.test"
|
|
40
|
+
import { mdb_sort_tests } from "./api_tests/mdb_sort.test"
|
|
40
41
|
import { create_user_notifications_trigger_tests } from "./api_tests/create_user_notifications_trigger.test"
|
|
41
42
|
import { inbox_thread_assignment_updates_tests } from "./api_tests/inbox_thread_assignment_updates.test"
|
|
42
43
|
import { inbox_thread_draft_scheduled_tests } from "./api_tests/inbox_thread_draft_scheduled.test"
|
|
@@ -88,6 +89,8 @@ import { load_team_chat_tests } from "./api_tests/load_team_chat.test";
|
|
|
88
89
|
import { form_started_trigger_tests } from "./api_tests/form_started_trigger.test";
|
|
89
90
|
import { medication_added_trigger_tests } from "./api_tests/medication_added_trigger.test";
|
|
90
91
|
import { elation_user_id_tests } from "./api_tests/elation_user_id.test";
|
|
92
|
+
import { organization_settings_duplicates_tests } from "./api_tests/organization_settings_duplicates.test";
|
|
93
|
+
import { calendar_events_bulk_update_tests } from "./api_tests/calendar_events_bulk_update.test";
|
|
91
94
|
import { openloop_webhooks_tests } from "./api_tests/openloop_webhooks.test";
|
|
92
95
|
import { beluga_pharmacy_mappings_tests } from "./api_tests/beluga_pharmacy_mappings.test";
|
|
93
96
|
|
|
@@ -5212,7 +5215,29 @@ const search_tests = async () => {
|
|
|
5212
5215
|
`Search by email`,
|
|
5213
5216
|
() => sdk.api.endusers.getSome({ search: { query: 'search@tellescope'} }),
|
|
5214
5217
|
{ onResult: es => es.length === 2 },
|
|
5215
|
-
)
|
|
5218
|
+
)
|
|
5219
|
+
|
|
5220
|
+
// minSearchScore parameter tests
|
|
5221
|
+
await async_test(
|
|
5222
|
+
`Search with minSearchScore accepted`,
|
|
5223
|
+
() => sdk.api.endusers.getSome({ search: { query: 'john', minSearchScore: 0.5 } }),
|
|
5224
|
+
{ onResult: es => es.length === 1 && es[0].id === e1.id },
|
|
5225
|
+
)
|
|
5226
|
+
await async_test(
|
|
5227
|
+
`Search with minSearchScore 0 accepted`,
|
|
5228
|
+
() => sdk.api.endusers.getSome({ search: { query: 'john', minSearchScore: 0 } }),
|
|
5229
|
+
{ onResult: es => es.length === 1 && es[0].id === e1.id },
|
|
5230
|
+
)
|
|
5231
|
+
await async_test(
|
|
5232
|
+
`Search with negative minSearchScore rejected`,
|
|
5233
|
+
() => sdk.api.endusers.getSome({ search: { query: 'john', minSearchScore: -1 } }),
|
|
5234
|
+
handleAnyError,
|
|
5235
|
+
)
|
|
5236
|
+
await async_test(
|
|
5237
|
+
`Search with string minSearchScore rejected`,
|
|
5238
|
+
() => sdk.api.endusers.getSome({ search: { query: 'john', minSearchScore: 'high' as any } }),
|
|
5239
|
+
handleAnyError,
|
|
5240
|
+
)
|
|
5216
5241
|
|
|
5217
5242
|
await Promise.all([
|
|
5218
5243
|
sdk.api.endusers.deleteOne(e1.id),
|
|
@@ -14101,6 +14126,9 @@ const ip_address_form_tests = async () => {
|
|
|
14101
14126
|
await replace_enduser_template_values_tests()
|
|
14102
14127
|
await mfa_tests()
|
|
14103
14128
|
await setup_tests(sdk, sdkNonAdmin)
|
|
14129
|
+
await mdb_sort_tests({ sdk, sdkNonAdmin })
|
|
14130
|
+
await organization_settings_duplicates_tests({ sdk, sdkNonAdmin })
|
|
14131
|
+
await search_tests()
|
|
14104
14132
|
await time_tracks_tests({ sdk, sdkNonAdmin })
|
|
14105
14133
|
await time_tracks_historical_tests({ sdk, sdkNonAdmin })
|
|
14106
14134
|
await time_tracks_correction_tests({ sdk, sdkNonAdmin })
|
|
@@ -14147,6 +14175,7 @@ const ip_address_form_tests = async () => {
|
|
|
14147
14175
|
await rate_limit_tests()
|
|
14148
14176
|
await ip_address_form_tests()
|
|
14149
14177
|
await bulk_update_tests()
|
|
14178
|
+
await calendar_events_bulk_update_tests({ sdk })
|
|
14150
14179
|
await cancel_upcoming_appointments_journey_action_test()
|
|
14151
14180
|
await multi_tenant_tests() // should come right after setup tests
|
|
14152
14181
|
await sync_tests_with_access_tags() // should come directly after setup to avoid extra sync values
|
|
@@ -14185,7 +14214,6 @@ const ip_address_form_tests = async () => {
|
|
|
14185
14214
|
await role_based_access_tests()
|
|
14186
14215
|
await enduser_session_tests()
|
|
14187
14216
|
await nextReminderInMS_tests()
|
|
14188
|
-
await search_tests()
|
|
14189
14217
|
await wait_for_trigger_tests()
|
|
14190
14218
|
await pdf_generation()
|
|
14191
14219
|
await remove_from_journey_on_incoming_comms_tests().catch(console.error) // timing is unreliable, uncomment if changing logic
|
package/test_generated.pdf
CHANGED
|
Binary file
|