@tellescope/sdk 1.253.1 → 1.254.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 +4 -0
- package/lib/cjs/sdk.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/_tmp_bc_verify.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/_tmp_blank_status_verify.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/_tmp_followup_verify.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/_tmp_nonmatch_verify.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/field_redaction.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/field_redaction.test.js +112 -99
- package/lib/cjs/tests/api_tests/field_redaction.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/journey_error_branching.test.js +7 -2
- package/lib/cjs/tests/api_tests/journey_error_branching.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/resource_access_tags.test.d.ts +22 -0
- package/lib/cjs/tests/api_tests/resource_access_tags.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/resource_access_tags.test.js +488 -0
- package/lib/cjs/tests/api_tests/resource_access_tags.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/time_tracks.test.d.ts +8 -0
- package/lib/cjs/tests/api_tests/time_tracks.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/time_tracks.test.js +638 -1
- package/lib/cjs/tests/api_tests/time_tracks.test.js.map +1 -1
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +586 -178
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/esm/sdk.d.ts +4 -0
- package/lib/esm/sdk.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/_tmp_bc_verify.test.d.ts +2 -0
- package/lib/esm/tests/api_tests/_tmp_bc_verify.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/_tmp_bc_verify.test.js +120 -0
- package/lib/esm/tests/api_tests/_tmp_bc_verify.test.js.map +1 -0
- package/lib/esm/tests/api_tests/_tmp_blank_status_verify.test.d.ts +2 -0
- package/lib/esm/tests/api_tests/_tmp_blank_status_verify.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/_tmp_blank_status_verify.test.js +200 -0
- package/lib/esm/tests/api_tests/_tmp_blank_status_verify.test.js.map +1 -0
- package/lib/esm/tests/api_tests/_tmp_followup_verify.test.d.ts +2 -0
- package/lib/esm/tests/api_tests/_tmp_followup_verify.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/_tmp_followup_verify.test.js +194 -0
- package/lib/esm/tests/api_tests/_tmp_followup_verify.test.js.map +1 -0
- package/lib/esm/tests/api_tests/_tmp_nonmatch_verify.test.d.ts +2 -0
- package/lib/esm/tests/api_tests/_tmp_nonmatch_verify.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/_tmp_nonmatch_verify.test.js +115 -0
- package/lib/esm/tests/api_tests/_tmp_nonmatch_verify.test.js.map +1 -0
- package/lib/esm/tests/api_tests/field_redaction.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/field_redaction.test.js +112 -99
- package/lib/esm/tests/api_tests/field_redaction.test.js.map +1 -1
- package/lib/esm/tests/api_tests/journey_error_branching.test.js +7 -2
- package/lib/esm/tests/api_tests/journey_error_branching.test.js.map +1 -1
- package/lib/esm/tests/api_tests/resource_access_tags.test.d.ts +22 -0
- package/lib/esm/tests/api_tests/resource_access_tags.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/resource_access_tags.test.js +484 -0
- package/lib/esm/tests/api_tests/resource_access_tags.test.js.map +1 -0
- package/lib/esm/tests/api_tests/time_tracks.test.d.ts +8 -0
- package/lib/esm/tests/api_tests/time_tracks.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/time_tracks.test.js +635 -0
- package/lib/esm/tests/api_tests/time_tracks.test.js.map +1 -1
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +587 -179
- 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/field_redaction.test.ts +13 -0
- package/src/tests/api_tests/journey_error_branching.test.ts +5 -1
- package/src/tests/api_tests/resource_access_tags.test.ts +303 -0
- package/src/tests/api_tests/time_tracks.test.ts +420 -0
- package/src/tests/tests.ts +298 -5
- package/test_generated.pdf +0 -0
package/src/tests/tests.ts
CHANGED
|
@@ -83,12 +83,13 @@ import { cross_org_api_key_tests } from "./api_tests/cross_org_api_key.test";
|
|
|
83
83
|
import { custom_dashboards_tests } from "./api_tests/custom_dashboards.test";
|
|
84
84
|
import { message_assignment_trigger_tests } from "./api_tests/message_assignment_trigger.test";
|
|
85
85
|
import { outbound_chat_sent_trigger_tests } from "./api_tests/outbound_chat_sent_trigger.test";
|
|
86
|
-
import { time_tracks_tests, time_tracks_historical_tests, time_tracks_correction_tests, time_tracks_review_tests, time_tracks_lock_tests, time_tracks_edge_case_tests } from "./api_tests/time_tracks.test";
|
|
86
|
+
import { time_tracks_tests, time_tracks_historical_tests, time_tracks_correction_tests, time_tracks_review_tests, time_tracks_lock_tests, time_tracks_edge_case_tests, time_tracks_resubmit_tests, time_tracks_appointment_duration_tests } from "./api_tests/time_tracks.test";
|
|
87
87
|
import { monthly_availability_restrictions_tests } from "./api_tests/monthly_availability_restrictions.test";
|
|
88
88
|
import { calendar_event_limits_tests } from "./api_tests/calendar_event_limits.test";
|
|
89
89
|
import { custom_aggregation_tests } from "./api_tests/custom_aggregation.test";
|
|
90
90
|
import { chats_analytics_tests } from "./api_tests/chats_analytics.test";
|
|
91
91
|
import { no_access_permission_checks_tests } from "./api_tests/no_access_permission_checks.test";
|
|
92
|
+
import { resource_access_tags_tests } from "./api_tests/resource_access_tags.test";
|
|
92
93
|
import { field_redaction_tests } from "./api_tests/field_redaction.test";
|
|
93
94
|
import { data_sync_redaction_bypass_tests } from "./api_tests/security/F-0001-data-sync-redaction-bypass.test";
|
|
94
95
|
import { enduser_write_restrictions_tests } from "./api_tests/security/F-0106-F-0110-enduser-write-restrictions.test";
|
|
@@ -3713,6 +3714,290 @@ const order_status_equals_tests = async () => {
|
|
|
3713
3714
|
])
|
|
3714
3715
|
}
|
|
3715
3716
|
|
|
3717
|
+
// Covers the "blank status matches any order status" behavior (Order Status Equals acting as "Order Status Changed").
|
|
3718
|
+
// Kept separate from order_status_equals_tests because a blank-status trigger would break that test's exact tag-count assertions.
|
|
3719
|
+
const order_status_blank_tests = async () => {
|
|
3720
|
+
log_header("Automation Trigger Tests (Order Status Equals - blank status)")
|
|
3721
|
+
|
|
3722
|
+
// A and A2 both fire on any status for BlankSource; the only difference is omitted vs. empty-string status.
|
|
3723
|
+
const A = await sdk.api.automation_triggers.createOne({
|
|
3724
|
+
event: { type: 'Order Status Equals', info: { source: 'BlankSource' } }, // status omitted entirely
|
|
3725
|
+
action: { type: 'Add Tags', info: { tags: ['AnyOmit'] }},
|
|
3726
|
+
status: 'Active',
|
|
3727
|
+
title: "Blank status (omitted)"
|
|
3728
|
+
})
|
|
3729
|
+
const A2 = await sdk.api.automation_triggers.createOne({
|
|
3730
|
+
event: { type: 'Order Status Equals', info: { source: 'BlankSource', status: '' } }, // explicit empty string
|
|
3731
|
+
action: { type: 'Add Tags', info: { tags: ['AnyEmpty'] }},
|
|
3732
|
+
status: 'Active',
|
|
3733
|
+
title: "Blank status (empty string)"
|
|
3734
|
+
})
|
|
3735
|
+
const B = await sdk.api.automation_triggers.createOne({
|
|
3736
|
+
event: { type: 'Order Status Equals', info: { source: 'BlankSource', status: '', skus: ['MATCH-SKU'] } },
|
|
3737
|
+
action: { type: 'Add Tags', info: { tags: ['BlankWithSku'] }},
|
|
3738
|
+
status: 'Active',
|
|
3739
|
+
title: "Blank status with SKU filter"
|
|
3740
|
+
})
|
|
3741
|
+
const C = await sdk.api.automation_triggers.createOne({
|
|
3742
|
+
event: { type: 'Order Status Equals', info: { source: 'OtherSource' } }, // blank status, different source
|
|
3743
|
+
action: { type: 'Add Tags', info: { tags: ['WrongSource'] }},
|
|
3744
|
+
status: 'Active',
|
|
3745
|
+
title: "Blank status, other source"
|
|
3746
|
+
})
|
|
3747
|
+
const D = await sdk.api.automation_triggers.createOne({
|
|
3748
|
+
event: { type: 'Order Status Equals', info: { source: 'BlankSource', status: 'Shipped' } }, // status-specific (regression)
|
|
3749
|
+
action: { type: 'Add Tags', info: { tags: ['ShippedOnly'] }},
|
|
3750
|
+
status: 'Active',
|
|
3751
|
+
title: "Status-specific (regression)"
|
|
3752
|
+
})
|
|
3753
|
+
// BA/BD exercise the separate bulk-create code path (createSome of 2+); kept on their own source so the
|
|
3754
|
+
// pre-existing "bulk ignores sku/protocol filters" divergence doesn't affect these assertions.
|
|
3755
|
+
const BA = await sdk.api.automation_triggers.createOne({
|
|
3756
|
+
event: { type: 'Order Status Equals', info: { source: 'BulkSource' } }, // blank status
|
|
3757
|
+
action: { type: 'Add Tags', info: { tags: ['BulkAny'] }},
|
|
3758
|
+
status: 'Active',
|
|
3759
|
+
title: "Bulk blank status"
|
|
3760
|
+
})
|
|
3761
|
+
const BD = await sdk.api.automation_triggers.createOne({
|
|
3762
|
+
event: { type: 'Order Status Equals', info: { source: 'BulkSource', status: 'Shipped' } }, // status-specific
|
|
3763
|
+
action: { type: 'Add Tags', info: { tags: ['BulkShipped'] }},
|
|
3764
|
+
status: 'Active',
|
|
3765
|
+
title: "Bulk status-specific"
|
|
3766
|
+
})
|
|
3767
|
+
// BD2's status matches NO order in the bulk batch below; backwards-compat: it must never fire (the query's $in
|
|
3768
|
+
// branch excludes it entirely, exactly as before the blank-status change).
|
|
3769
|
+
const BD2 = await sdk.api.automation_triggers.createOne({
|
|
3770
|
+
event: { type: 'Order Status Equals', info: { source: 'BulkSource', status: 'NeverInBatch' } },
|
|
3771
|
+
action: { type: 'Add Tags', info: { tags: ['BulkNever'] }},
|
|
3772
|
+
status: 'Active',
|
|
3773
|
+
title: "Bulk status-specific (absent from batch)"
|
|
3774
|
+
})
|
|
3775
|
+
// P: blank status composed with a protocol filter (proves blank works with non-SKU filters + the no-protocol branch)
|
|
3776
|
+
const P = await sdk.api.automation_triggers.createOne({
|
|
3777
|
+
event: { type: 'Order Status Equals', info: { source: 'BlankSource', status: '', protocols: ['Protocol-A'] } },
|
|
3778
|
+
action: { type: 'Add Tags', info: { tags: ['BlankProtocol'] }},
|
|
3779
|
+
status: 'Active',
|
|
3780
|
+
title: "Blank status with protocol filter"
|
|
3781
|
+
})
|
|
3782
|
+
|
|
3783
|
+
// Case 1: validation accepts triggers with no status / empty status (A and A2 created above without error)
|
|
3784
|
+
await async_test(
|
|
3785
|
+
"Trigger with omitted status was created",
|
|
3786
|
+
() => Promise.resolve(A),
|
|
3787
|
+
{ onResult: t => !!t.id && t.event.type === 'Order Status Equals' && !t.event.info.status }
|
|
3788
|
+
)
|
|
3789
|
+
await async_test(
|
|
3790
|
+
"Trigger with empty-string status was created",
|
|
3791
|
+
() => Promise.resolve(A2),
|
|
3792
|
+
{ onResult: t => !!t.id && t.event.type === 'Order Status Equals' && t.event.info.status === '' }
|
|
3793
|
+
)
|
|
3794
|
+
|
|
3795
|
+
// Case 2: blank status fires on an arbitrary status
|
|
3796
|
+
const e2 = await sdk.api.endusers.createOne({})
|
|
3797
|
+
await sdk.api.enduser_orders.createOne({ status: 'StatusOne', source: 'BlankSource', title: 'Title', externalId: 'blank-1', enduserId: e2.id })
|
|
3798
|
+
await wait(undefined, 500) // allow triggers to happen
|
|
3799
|
+
await async_test(
|
|
3800
|
+
"Blank status fires on arbitrary status (no other tags)",
|
|
3801
|
+
() => sdk.api.endusers.getOne(e2.id),
|
|
3802
|
+
{ onResult: e => !!(
|
|
3803
|
+
e.tags?.includes('AnyOmit')
|
|
3804
|
+
&& e.tags?.includes('AnyEmpty')
|
|
3805
|
+
&& !e.tags?.includes('BlankWithSku')
|
|
3806
|
+
&& !e.tags?.includes('WrongSource')
|
|
3807
|
+
&& !e.tags?.includes('ShippedOnly')
|
|
3808
|
+
) }
|
|
3809
|
+
)
|
|
3810
|
+
|
|
3811
|
+
// Case 3: blank status fires on a totally different status value (status-value-independent)
|
|
3812
|
+
const e3 = await sdk.api.endusers.createOne({})
|
|
3813
|
+
await sdk.api.enduser_orders.createOne({ status: 'totally-arbitrary-xyz', source: 'BlankSource', title: 'Title', externalId: 'blank-2', enduserId: e3.id })
|
|
3814
|
+
await wait(undefined, 500) // allow triggers to happen
|
|
3815
|
+
await async_test(
|
|
3816
|
+
"Blank status fires on a different arbitrary status",
|
|
3817
|
+
() => sdk.api.endusers.getOne(e3.id),
|
|
3818
|
+
{ onResult: e => !!(
|
|
3819
|
+
e.tags?.includes('AnyOmit')
|
|
3820
|
+
&& e.tags?.includes('AnyEmpty')
|
|
3821
|
+
) }
|
|
3822
|
+
)
|
|
3823
|
+
|
|
3824
|
+
// Case 4: source isolation - blank trigger does not fire for a different source
|
|
3825
|
+
const e4 = await sdk.api.endusers.createOne({})
|
|
3826
|
+
await sdk.api.enduser_orders.createOne({ status: 'StatusOne', source: 'DifferentSource', title: 'Title', externalId: 'blank-3', enduserId: e4.id })
|
|
3827
|
+
await wait(undefined, 500) // allow triggers to happen
|
|
3828
|
+
await async_test(
|
|
3829
|
+
"Blank status is still scoped to its source",
|
|
3830
|
+
() => sdk.api.endusers.getOne(e4.id),
|
|
3831
|
+
{ onResult: e => !!(
|
|
3832
|
+
!e.tags?.includes('AnyOmit')
|
|
3833
|
+
&& !e.tags?.includes('AnyEmpty')
|
|
3834
|
+
&& !e.tags?.includes('WrongSource') // C only matches OtherSource
|
|
3835
|
+
) }
|
|
3836
|
+
)
|
|
3837
|
+
|
|
3838
|
+
// Case 5a: other filters still enforced with blank status (sku mismatch)
|
|
3839
|
+
const e5 = await sdk.api.endusers.createOne({})
|
|
3840
|
+
await sdk.api.enduser_orders.createOne({ status: 'whatever', source: 'BlankSource', title: 'Title', externalId: 'blank-4', enduserId: e5.id, sku: 'NOPE' })
|
|
3841
|
+
await wait(undefined, 500) // allow triggers to happen
|
|
3842
|
+
await async_test(
|
|
3843
|
+
"Blank status + SKU filter does not fire on SKU mismatch",
|
|
3844
|
+
() => sdk.api.endusers.getOne(e5.id),
|
|
3845
|
+
{ onResult: e => !!(
|
|
3846
|
+
e.tags?.includes('AnyOmit')
|
|
3847
|
+
&& e.tags?.includes('AnyEmpty')
|
|
3848
|
+
&& !e.tags?.includes('BlankWithSku')
|
|
3849
|
+
) }
|
|
3850
|
+
)
|
|
3851
|
+
|
|
3852
|
+
// Case 5b: other filters still enforced with blank status (sku match)
|
|
3853
|
+
const e6 = await sdk.api.endusers.createOne({})
|
|
3854
|
+
await sdk.api.enduser_orders.createOne({ status: 'whatever', source: 'BlankSource', title: 'Title', externalId: 'blank-5', enduserId: e6.id, sku: 'MATCH-SKU' })
|
|
3855
|
+
await wait(undefined, 500) // allow triggers to happen
|
|
3856
|
+
await async_test(
|
|
3857
|
+
"Blank status + SKU filter fires on SKU match",
|
|
3858
|
+
() => sdk.api.endusers.getOne(e6.id),
|
|
3859
|
+
{ onResult: e => !!(
|
|
3860
|
+
e.tags?.includes('AnyOmit')
|
|
3861
|
+
&& e.tags?.includes('AnyEmpty')
|
|
3862
|
+
&& e.tags?.includes('BlankWithSku')
|
|
3863
|
+
) }
|
|
3864
|
+
)
|
|
3865
|
+
|
|
3866
|
+
// Case 6: update path + regression coexistence with a status-specific trigger
|
|
3867
|
+
const e7 = await sdk.api.endusers.createOne({})
|
|
3868
|
+
const o7 = await sdk.api.enduser_orders.createOne({ status: 'Created', source: 'BlankSource', title: 'Title', externalId: 'blank-6', enduserId: e7.id })
|
|
3869
|
+
await wait(undefined, 500) // allow triggers to happen
|
|
3870
|
+
await async_test(
|
|
3871
|
+
"Blank fires on create; status-specific (Shipped) does not yet",
|
|
3872
|
+
() => sdk.api.endusers.getOne(e7.id),
|
|
3873
|
+
{ onResult: e => !!(
|
|
3874
|
+
e.tags?.includes('AnyOmit')
|
|
3875
|
+
&& e.tags?.includes('AnyEmpty')
|
|
3876
|
+
&& !e.tags?.includes('ShippedOnly')
|
|
3877
|
+
) }
|
|
3878
|
+
)
|
|
3879
|
+
// update to a NON-matching status: blank fires again, but the status-specific trigger must stay un-fired
|
|
3880
|
+
await sdk.api.enduser_orders.updateOne(o7.id, { status: 'Delivered', externalId: 'blank-6-delivered' })
|
|
3881
|
+
await wait(undefined, 500) // allow triggers to happen
|
|
3882
|
+
await async_test(
|
|
3883
|
+
"Update to non-matching status: blank fires, status-specific (Shipped) does NOT fire",
|
|
3884
|
+
() => sdk.api.endusers.getOne(e7.id),
|
|
3885
|
+
{ onResult: e => !!(
|
|
3886
|
+
e.tags?.includes('AnyOmit') // proves the update event was processed
|
|
3887
|
+
&& e.tags?.includes('AnyEmpty')
|
|
3888
|
+
&& !e.tags?.includes('ShippedOnly') // 'Delivered' must not trigger the 'Shipped' trigger
|
|
3889
|
+
) }
|
|
3890
|
+
)
|
|
3891
|
+
// now update to the matching status: status-specific trigger fires
|
|
3892
|
+
await sdk.api.enduser_orders.updateOne(o7.id, { status: 'Shipped', externalId: 'blank-6-shipped' })
|
|
3893
|
+
await wait(undefined, 500) // allow triggers to happen
|
|
3894
|
+
await async_test(
|
|
3895
|
+
"Blank fires on update too; status-specific (Shipped) now fires",
|
|
3896
|
+
() => sdk.api.endusers.getOne(e7.id),
|
|
3897
|
+
{ onResult: e => !!(
|
|
3898
|
+
e.tags?.includes('AnyOmit')
|
|
3899
|
+
&& e.tags?.includes('AnyEmpty')
|
|
3900
|
+
&& e.tags?.includes('ShippedOnly')
|
|
3901
|
+
) }
|
|
3902
|
+
)
|
|
3903
|
+
|
|
3904
|
+
// Case 7: bulk create path (createSome of 2+) must honor blank status + status-specific selectivity.
|
|
3905
|
+
// This exercises a SEPARATE matching code path (handle_orders_create bulk branch) from single creates.
|
|
3906
|
+
const eb1 = await sdk.api.endusers.createOne({})
|
|
3907
|
+
const eb2 = await sdk.api.endusers.createOne({})
|
|
3908
|
+
const eb3 = await sdk.api.endusers.createOne({})
|
|
3909
|
+
await sdk.api.enduser_orders.createSome([
|
|
3910
|
+
{ status: 'StatusA', source: 'BulkSource', title: 'Title', externalId: 'bulk-1', enduserId: eb1.id },
|
|
3911
|
+
{ status: 'Shipped', source: 'BulkSource', title: 'Title', externalId: 'bulk-2', enduserId: eb2.id },
|
|
3912
|
+
{ status: 'StatusB', source: 'BulkSource', title: 'Title', externalId: 'bulk-3', enduserId: eb3.id },
|
|
3913
|
+
])
|
|
3914
|
+
await wait(undefined, 500) // allow triggers to happen
|
|
3915
|
+
await async_test(
|
|
3916
|
+
"Bulk create: blank fires on non-Shipped order; status-specific (matching + absent) do not",
|
|
3917
|
+
() => sdk.api.endusers.getOne(eb1.id),
|
|
3918
|
+
{ onResult: e => !!(e.tags?.includes('BulkAny') && !e.tags?.includes('BulkShipped') && !e.tags?.includes('BulkNever')) }
|
|
3919
|
+
)
|
|
3920
|
+
await async_test(
|
|
3921
|
+
"Bulk create: blank + matching status-specific fire on the Shipped order; absent-status one does not",
|
|
3922
|
+
() => sdk.api.endusers.getOne(eb2.id),
|
|
3923
|
+
{ onResult: e => !!(e.tags?.includes('BulkAny') && e.tags?.includes('BulkShipped') && !e.tags?.includes('BulkNever')) }
|
|
3924
|
+
)
|
|
3925
|
+
await async_test(
|
|
3926
|
+
"Bulk create: blank fires on the other non-Shipped order; status-specific (matching + absent) do not",
|
|
3927
|
+
() => sdk.api.endusers.getOne(eb3.id),
|
|
3928
|
+
{ onResult: e => !!(e.tags?.includes('BulkAny') && !e.tags?.includes('BulkShipped') && !e.tags?.includes('BulkNever')) }
|
|
3929
|
+
)
|
|
3930
|
+
|
|
3931
|
+
// Case 8: an order update that does NOT change status must not run the handler (true "status changed" semantic).
|
|
3932
|
+
const e8 = await sdk.api.endusers.createOne({})
|
|
3933
|
+
const o8 = await sdk.api.enduser_orders.createOne({ status: 'Shipped', source: 'BlankSource', title: 'Title', externalId: 'noChange-1', enduserId: e8.id })
|
|
3934
|
+
await wait(undefined, 500) // allow triggers to happen
|
|
3935
|
+
await async_test(
|
|
3936
|
+
"Setup: status-specific (Shipped) fired on create",
|
|
3937
|
+
() => sdk.api.endusers.getOne(e8.id),
|
|
3938
|
+
{ onResult: e => !!(e.tags?.includes('AnyOmit') && e.tags?.includes('ShippedOnly')) }
|
|
3939
|
+
)
|
|
3940
|
+
// clear tags (replaceObjectFields forces the empty array to actually replace)
|
|
3941
|
+
await sdk.api.endusers.updateOne(e8.id, { tags: [] }, { replaceObjectFields: true })
|
|
3942
|
+
// sanity-check the clear actually took, so a later failure points at re-firing rather than a broken clear
|
|
3943
|
+
await async_test(
|
|
3944
|
+
"Setup: tags cleared before non-status update",
|
|
3945
|
+
() => sdk.api.endusers.getOne(e8.id),
|
|
3946
|
+
{ onResult: e => !e.tags?.length }
|
|
3947
|
+
)
|
|
3948
|
+
// update a non-status field (status stays 'Shipped'); handler should early-return and re-add nothing.
|
|
3949
|
+
// If it wrongly fired, the blank triggers A/A2 would re-add AnyOmit/AnyEmpty, so empty tags proves non-firing.
|
|
3950
|
+
await sdk.api.enduser_orders.updateOne(o8.id, { tracking: 'tracking-123', externalId: 'noChange-1b' })
|
|
3951
|
+
await wait(undefined, 500) // allow triggers to happen
|
|
3952
|
+
await async_test(
|
|
3953
|
+
"Update with unchanged status does not fire any trigger",
|
|
3954
|
+
() => sdk.api.endusers.getOne(e8.id),
|
|
3955
|
+
{ onResult: e => !e.tags?.length }
|
|
3956
|
+
)
|
|
3957
|
+
|
|
3958
|
+
// Case 9: protocol filter with blank status - order without a protocol must not fire (the order.protocol ? : false branch)
|
|
3959
|
+
const e9 = await sdk.api.endusers.createOne({})
|
|
3960
|
+
await sdk.api.enduser_orders.createOne({ status: 'whatever', source: 'BlankSource', title: 'Title', externalId: 'proto-1', enduserId: e9.id })
|
|
3961
|
+
await wait(undefined, 500) // allow triggers to happen
|
|
3962
|
+
await async_test(
|
|
3963
|
+
"Blank + protocol filter does not fire when order has no protocol",
|
|
3964
|
+
() => sdk.api.endusers.getOne(e9.id),
|
|
3965
|
+
{ onResult: e => !!(e.tags?.includes('AnyOmit') && !e.tags?.includes('BlankProtocol')) }
|
|
3966
|
+
)
|
|
3967
|
+
const e10 = await sdk.api.endusers.createOne({})
|
|
3968
|
+
await sdk.api.enduser_orders.createOne({ status: 'whatever', source: 'BlankSource', title: 'Title', externalId: 'proto-2', enduserId: e10.id, protocol: 'Protocol-A' })
|
|
3969
|
+
await wait(undefined, 500) // allow triggers to happen
|
|
3970
|
+
await async_test(
|
|
3971
|
+
"Blank + protocol filter fires when order protocol matches",
|
|
3972
|
+
() => sdk.api.endusers.getOne(e10.id),
|
|
3973
|
+
{ onResult: e => !!(e.tags?.includes('AnyOmit') && e.tags?.includes('BlankProtocol')) }
|
|
3974
|
+
)
|
|
3975
|
+
|
|
3976
|
+
await Promise.all([
|
|
3977
|
+
sdk.api.automation_triggers.deleteOne(A.id),
|
|
3978
|
+
sdk.api.automation_triggers.deleteOne(A2.id),
|
|
3979
|
+
sdk.api.automation_triggers.deleteOne(B.id),
|
|
3980
|
+
sdk.api.automation_triggers.deleteOne(C.id),
|
|
3981
|
+
sdk.api.automation_triggers.deleteOne(D.id),
|
|
3982
|
+
sdk.api.automation_triggers.deleteOne(BA.id),
|
|
3983
|
+
sdk.api.automation_triggers.deleteOne(BD.id),
|
|
3984
|
+
sdk.api.automation_triggers.deleteOne(BD2.id),
|
|
3985
|
+
sdk.api.automation_triggers.deleteOne(P.id),
|
|
3986
|
+
sdk.api.endusers.deleteOne(e2.id),
|
|
3987
|
+
sdk.api.endusers.deleteOne(e3.id),
|
|
3988
|
+
sdk.api.endusers.deleteOne(e4.id),
|
|
3989
|
+
sdk.api.endusers.deleteOne(e5.id),
|
|
3990
|
+
sdk.api.endusers.deleteOne(e6.id),
|
|
3991
|
+
sdk.api.endusers.deleteOne(e7.id),
|
|
3992
|
+
sdk.api.endusers.deleteOne(eb1.id),
|
|
3993
|
+
sdk.api.endusers.deleteOne(eb2.id),
|
|
3994
|
+
sdk.api.endusers.deleteOne(eb3.id),
|
|
3995
|
+
sdk.api.endusers.deleteOne(e8.id),
|
|
3996
|
+
sdk.api.endusers.deleteOne(e9.id),
|
|
3997
|
+
sdk.api.endusers.deleteOne(e10.id),
|
|
3998
|
+
])
|
|
3999
|
+
}
|
|
4000
|
+
|
|
3716
4001
|
const tag_added_tests = async () => {
|
|
3717
4002
|
log_header("Automation Trigger Tests (Tag Added)")
|
|
3718
4003
|
|
|
@@ -5305,6 +5590,7 @@ const automation_trigger_tests = async () => {
|
|
|
5305
5590
|
await assign_care_team_tests()
|
|
5306
5591
|
await push_forms_to_portal_group_completion_tests({ sdk, sdkNonAdmin })
|
|
5307
5592
|
await order_status_equals_tests()
|
|
5593
|
+
await order_status_blank_tests()
|
|
5308
5594
|
await set_fields_order_templates_tests({ sdk, sdkNonAdmin })
|
|
5309
5595
|
await medication_added_trigger_tests({ sdk, sdkNonAdmin })
|
|
5310
5596
|
await appointment_cancelled_tests()
|
|
@@ -8862,8 +9148,11 @@ export const switch_to_related_contacts_tests = async () => {
|
|
|
8862
9148
|
() => pollForResults(
|
|
8863
9149
|
() => sdk.api.endusers.getOne(parent.id),
|
|
8864
9150
|
e => !!e.tags?.includes('Success'),
|
|
8865
|
-
|
|
8866
|
-
|
|
9151
|
+
// switchToRelatedContact (cycle 1) then the afterAction addEnduserTags (cycle 2) each wait a
|
|
9152
|
+
// full worker poll cycle (>= 8s, see worker pollingDelaySeconds), so ~16s worst case. Poll for
|
|
9153
|
+
// 30s (500ms x 60) to cover two cycles plus buffer; the old 10s window timed out flakily.
|
|
9154
|
+
500,
|
|
9155
|
+
60,
|
|
8867
9156
|
),
|
|
8868
9157
|
passOnAnyResult
|
|
8869
9158
|
)
|
|
@@ -14395,7 +14684,7 @@ const ip_address_form_tests = async () => {
|
|
|
14395
14684
|
})
|
|
14396
14685
|
|
|
14397
14686
|
await wait(undefined, 500) // wait for IP to be set
|
|
14398
|
-
async_test(
|
|
14687
|
+
await async_test(
|
|
14399
14688
|
'IP Set on Enduser creation',
|
|
14400
14689
|
() => sdk.api.endusers.getOne(enduserId),
|
|
14401
14690
|
{ onResult: result => !!result.fields?.IP }
|
|
@@ -14414,7 +14703,8 @@ const ip_address_form_tests = async () => {
|
|
|
14414
14703
|
lname: 'test',
|
|
14415
14704
|
})
|
|
14416
14705
|
|
|
14417
|
-
|
|
14706
|
+
await wait(undefined, 500) // wait for IP to be re-set
|
|
14707
|
+
await async_test(
|
|
14418
14708
|
'IP Set on update',
|
|
14419
14709
|
() => sdk.api.endusers.getOne(enduserId),
|
|
14420
14710
|
{ onResult: result => !!result.fields?.IP && result.fields?.otherField === 'Set' && result.id === enduserId }
|
|
@@ -14547,6 +14837,7 @@ const ip_address_form_tests = async () => {
|
|
|
14547
14837
|
await replace_form_field_template_values_tests()
|
|
14548
14838
|
await mfa_tests()
|
|
14549
14839
|
await setup_tests(sdk, sdkNonAdmin)
|
|
14840
|
+
await resource_access_tags_tests({ sdk, sdkNonAdmin })
|
|
14550
14841
|
await beluga_manual_sync_tests({ sdk, sdkNonAdmin })
|
|
14551
14842
|
await beluga_pharmacy_mappings_tests({ sdk, sdkNonAdmin })
|
|
14552
14843
|
await enduser_write_restrictions_tests({ sdk, sdkNonAdmin })
|
|
@@ -14586,6 +14877,8 @@ const ip_address_form_tests = async () => {
|
|
|
14586
14877
|
await time_tracks_review_tests({ sdk, sdkNonAdmin })
|
|
14587
14878
|
await time_tracks_lock_tests({ sdk, sdkNonAdmin })
|
|
14588
14879
|
await time_tracks_edge_case_tests({ sdk, sdkNonAdmin })
|
|
14880
|
+
await time_tracks_resubmit_tests({ sdk, sdkNonAdmin })
|
|
14881
|
+
await time_tracks_appointment_duration_tests({ sdk, sdkNonAdmin })
|
|
14589
14882
|
await calendar_event_limits_tests({ sdk, sdkNonAdmin })
|
|
14590
14883
|
await get_some_projection_tests({ sdk, sdkNonAdmin })
|
|
14591
14884
|
await elation_user_id_tests({ sdk, sdkNonAdmin })
|
package/test_generated.pdf
CHANGED
|
Binary file
|