@tellescope/sdk 1.246.2 → 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/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 +136 -124
- 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/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 +136 -124
- 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 +6 -0
- 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
|
|
|
@@ -14123,6 +14126,8 @@ const ip_address_form_tests = async () => {
|
|
|
14123
14126
|
await replace_enduser_template_values_tests()
|
|
14124
14127
|
await mfa_tests()
|
|
14125
14128
|
await setup_tests(sdk, sdkNonAdmin)
|
|
14129
|
+
await mdb_sort_tests({ sdk, sdkNonAdmin })
|
|
14130
|
+
await organization_settings_duplicates_tests({ sdk, sdkNonAdmin })
|
|
14126
14131
|
await search_tests()
|
|
14127
14132
|
await time_tracks_tests({ sdk, sdkNonAdmin })
|
|
14128
14133
|
await time_tracks_historical_tests({ sdk, sdkNonAdmin })
|
|
@@ -14170,6 +14175,7 @@ const ip_address_form_tests = async () => {
|
|
|
14170
14175
|
await rate_limit_tests()
|
|
14171
14176
|
await ip_address_form_tests()
|
|
14172
14177
|
await bulk_update_tests()
|
|
14178
|
+
await calendar_events_bulk_update_tests({ sdk })
|
|
14173
14179
|
await cancel_upcoming_appointments_journey_action_test()
|
|
14174
14180
|
await multi_tenant_tests() // should come right after setup tests
|
|
14175
14181
|
await sync_tests_with_access_tags() // should come directly after setup to avoid extra sync values
|
package/test_generated.pdf
CHANGED
|
Binary file
|