@tellescope/sdk 2.0.0-beta.1 → 2.0.0-beta.2
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/CLAUDE.md +24 -0
- package/env.example +6 -0
- package/lib/cjs/sdk.d.ts +373 -3
- package/lib/cjs/sdk.d.ts.map +1 -1
- package/lib/cjs/sdk.js.map +1 -1
- package/lib/cjs/tests/api_tests/booking_prevent_upcoming_duplicate.test.d.ts +22 -0
- package/lib/cjs/tests/api_tests/booking_prevent_upcoming_duplicate.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/booking_prevent_upcoming_duplicate.test.js +506 -0
- package/lib/cjs/tests/api_tests/booking_prevent_upcoming_duplicate.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/enduser_fields_sync.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/enduser_fields_sync.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/enduser_fields_sync.test.js +3 -1
- package/lib/cjs/tests/api_tests/enduser_fields_sync.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.js +3 -1
- package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/form_vital_reading.test.d.ts +7 -0
- package/lib/cjs/tests/api_tests/form_vital_reading.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/form_vital_reading.test.js +461 -0
- package/lib/cjs/tests/api_tests/form_vital_reading.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/journey_statistics_cache.test.d.ts +26 -0
- package/lib/cjs/tests/api_tests/journey_statistics_cache.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/journey_statistics_cache.test.js +232 -0
- package/lib/cjs/tests/api_tests/journey_statistics_cache.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/journey_step_manual_count.test.d.ts +34 -0
- package/lib/cjs/tests/api_tests/journey_step_manual_count.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/journey_step_manual_count.test.js +243 -0
- package/lib/cjs/tests/api_tests/journey_step_manual_count.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/load_threads_care_team.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/load_threads_care_team.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/load_threads_care_team.test.js +3 -1
- package/lib/cjs/tests/api_tests/load_threads_care_team.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/organization_signup.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/organization_signup.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/organization_signup.test.js +3 -1
- package/lib/cjs/tests/api_tests/organization_signup.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/phone_embed_leave_message.test.d.ts +7 -0
- package/lib/cjs/tests/api_tests/phone_embed_leave_message.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/phone_embed_leave_message.test.js +571 -0
- package/lib/cjs/tests/api_tests/phone_embed_leave_message.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/programs.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/programs.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/programs.test.js +73 -17
- package/lib/cjs/tests/api_tests/programs.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/public_form_case_insensitive_match.test.d.ts +7 -0
- package/lib/cjs/tests/api_tests/public_form_case_insensitive_match.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/public_form_case_insensitive_match.test.js +733 -0
- package/lib/cjs/tests/api_tests/public_form_case_insensitive_match.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js +3 -1
- package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/appointment-reschedule-ownership.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/security/appointment-reschedule-ownership.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/appointment-reschedule-ownership.test.js +3 -1
- package/lib/cjs/tests/api_tests/security/appointment-reschedule-ownership.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.js +3 -1
- package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.js +3 -1
- package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/formsort_webhook_auth_field_lock.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/formsort_webhook_auth_field_lock.test.js +424 -39
- package/lib/cjs/tests/api_tests/security/formsort_webhook_auth_field_lock.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/register_business_id_injection.test.js +2 -2
- package/lib/cjs/tests/api_tests/security/register_business_id_injection.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.js +3 -1
- package/lib/cjs/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/session_for_join_link.test.d.ts +10 -0
- package/lib/cjs/tests/api_tests/session_for_join_link.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/session_for_join_link.test.js +147 -0
- package/lib/cjs/tests/api_tests/session_for_join_link.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/set_fields_order_templates.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/set_fields_order_templates.test.js +191 -88
- package/lib/cjs/tests/api_tests/set_fields_order_templates.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/stripe_checkout_items.test.d.ts +17 -0
- package/lib/cjs/tests/api_tests/stripe_checkout_items.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/stripe_checkout_items.test.js +219 -0
- package/lib/cjs/tests/api_tests/stripe_checkout_items.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/stripe_multiple_customer_ids.test.d.ts +5 -0
- package/lib/cjs/tests/api_tests/stripe_multiple_customer_ids.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/stripe_multiple_customer_ids.test.js +396 -0
- package/lib/cjs/tests/api_tests/stripe_multiple_customer_ids.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/tickets_bulk_assign_from_queue.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/tickets_bulk_assign_from_queue.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/tickets_bulk_assign_from_queue.test.js +3 -1
- package/lib/cjs/tests/api_tests/tickets_bulk_assign_from_queue.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/totp_mfa.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/totp_mfa.test.js +37 -31
- package/lib/cjs/tests/api_tests/totp_mfa.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/trigger_contains_matching.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/trigger_contains_matching.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/trigger_contains_matching.test.js +3 -1
- package/lib/cjs/tests/api_tests/trigger_contains_matching.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/user_logs_restore_deleted.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/user_logs_restore_deleted.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/user_logs_restore_deleted.test.js +3 -1
- package/lib/cjs/tests/api_tests/user_logs_restore_deleted.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/vital_review_trigger_action.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/vital_review_trigger_action.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/vital_review_trigger_action.test.js +3 -1
- package/lib/cjs/tests/api_tests/vital_review_trigger_action.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/vitl_push.test.d.ts +7 -0
- package/lib/cjs/tests/api_tests/vitl_push.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/vitl_push.test.js +341 -0
- package/lib/cjs/tests/api_tests/vitl_push.test.js.map +1 -0
- package/lib/cjs/tests/setup_isolated.d.ts +48 -0
- package/lib/cjs/tests/setup_isolated.d.ts.map +1 -1
- package/lib/cjs/tests/setup_isolated.js +119 -1
- package/lib/cjs/tests/setup_isolated.js.map +1 -1
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +374 -292
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/cjs/tests/unit_tests/isolated_suite_discovery.test.d.ts +2 -0
- package/lib/cjs/tests/unit_tests/isolated_suite_discovery.test.d.ts.map +1 -0
- package/lib/cjs/tests/unit_tests/isolated_suite_discovery.test.js +201 -0
- package/lib/cjs/tests/unit_tests/isolated_suite_discovery.test.js.map +1 -0
- package/lib/cjs/tests/unit_tests/programs_conditional_logic.test.d.ts +3 -0
- package/lib/cjs/tests/unit_tests/programs_conditional_logic.test.d.ts.map +1 -0
- package/lib/cjs/tests/unit_tests/programs_conditional_logic.test.js +120 -0
- package/lib/cjs/tests/unit_tests/programs_conditional_logic.test.js.map +1 -0
- package/lib/cjs/tests/webhooks_tests.js +44 -34
- package/lib/cjs/tests/webhooks_tests.js.map +1 -1
- package/lib/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/esm/sdk.d.ts +373 -3
- package/lib/esm/sdk.d.ts.map +1 -1
- package/lib/esm/sdk.js.map +1 -1
- package/lib/esm/tests/api_tests/booking_prevent_upcoming_duplicate.test.d.ts +22 -0
- package/lib/esm/tests/api_tests/booking_prevent_upcoming_duplicate.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/booking_prevent_upcoming_duplicate.test.js +501 -0
- package/lib/esm/tests/api_tests/booking_prevent_upcoming_duplicate.test.js.map +1 -0
- package/lib/esm/tests/api_tests/enduser_fields_sync.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/enduser_fields_sync.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/enduser_fields_sync.test.js +2 -0
- package/lib/esm/tests/api_tests/enduser_fields_sync.test.js.map +1 -1
- package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.js +2 -0
- package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.js.map +1 -1
- package/lib/esm/tests/api_tests/form_vital_reading.test.d.ts +7 -0
- package/lib/esm/tests/api_tests/form_vital_reading.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/form_vital_reading.test.js +456 -0
- package/lib/esm/tests/api_tests/form_vital_reading.test.js.map +1 -0
- package/lib/esm/tests/api_tests/journey_statistics_cache.test.d.ts +26 -0
- package/lib/esm/tests/api_tests/journey_statistics_cache.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/journey_statistics_cache.test.js +227 -0
- package/lib/esm/tests/api_tests/journey_statistics_cache.test.js.map +1 -0
- package/lib/esm/tests/api_tests/journey_step_manual_count.test.d.ts +34 -0
- package/lib/esm/tests/api_tests/journey_step_manual_count.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/journey_step_manual_count.test.js +238 -0
- package/lib/esm/tests/api_tests/journey_step_manual_count.test.js.map +1 -0
- package/lib/esm/tests/api_tests/load_threads_care_team.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/load_threads_care_team.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/load_threads_care_team.test.js +2 -0
- package/lib/esm/tests/api_tests/load_threads_care_team.test.js.map +1 -1
- package/lib/esm/tests/api_tests/organization_signup.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/organization_signup.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/organization_signup.test.js +2 -0
- package/lib/esm/tests/api_tests/organization_signup.test.js.map +1 -1
- package/lib/esm/tests/api_tests/phone_embed_leave_message.test.d.ts +7 -0
- package/lib/esm/tests/api_tests/phone_embed_leave_message.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/phone_embed_leave_message.test.js +566 -0
- package/lib/esm/tests/api_tests/phone_embed_leave_message.test.js.map +1 -0
- package/lib/esm/tests/api_tests/programs.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/programs.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/programs.test.js +72 -16
- package/lib/esm/tests/api_tests/programs.test.js.map +1 -1
- package/lib/esm/tests/api_tests/public_form_case_insensitive_match.test.d.ts +7 -0
- package/lib/esm/tests/api_tests/public_form_case_insensitive_match.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/public_form_case_insensitive_match.test.js +728 -0
- package/lib/esm/tests/api_tests/public_form_case_insensitive_match.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js +2 -0
- package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/appointment-reschedule-ownership.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/security/appointment-reschedule-ownership.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/appointment-reschedule-ownership.test.js +2 -0
- package/lib/esm/tests/api_tests/security/appointment-reschedule-ownership.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.js +2 -0
- package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.js +2 -0
- package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/formsort_webhook_auth_field_lock.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/formsort_webhook_auth_field_lock.test.js +424 -39
- package/lib/esm/tests/api_tests/security/formsort_webhook_auth_field_lock.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/register_business_id_injection.test.js +2 -2
- package/lib/esm/tests/api_tests/security/register_business_id_injection.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.js +2 -0
- package/lib/esm/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.js.map +1 -1
- package/lib/esm/tests/api_tests/session_for_join_link.test.d.ts +10 -0
- package/lib/esm/tests/api_tests/session_for_join_link.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/session_for_join_link.test.js +142 -0
- package/lib/esm/tests/api_tests/session_for_join_link.test.js.map +1 -0
- package/lib/esm/tests/api_tests/set_fields_order_templates.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/set_fields_order_templates.test.js +191 -88
- package/lib/esm/tests/api_tests/set_fields_order_templates.test.js.map +1 -1
- package/lib/esm/tests/api_tests/stripe_checkout_items.test.d.ts +17 -0
- package/lib/esm/tests/api_tests/stripe_checkout_items.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/stripe_checkout_items.test.js +214 -0
- package/lib/esm/tests/api_tests/stripe_checkout_items.test.js.map +1 -0
- package/lib/esm/tests/api_tests/stripe_multiple_customer_ids.test.d.ts +5 -0
- package/lib/esm/tests/api_tests/stripe_multiple_customer_ids.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/stripe_multiple_customer_ids.test.js +388 -0
- package/lib/esm/tests/api_tests/stripe_multiple_customer_ids.test.js.map +1 -0
- package/lib/esm/tests/api_tests/tickets_bulk_assign_from_queue.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/tickets_bulk_assign_from_queue.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/tickets_bulk_assign_from_queue.test.js +2 -0
- package/lib/esm/tests/api_tests/tickets_bulk_assign_from_queue.test.js.map +1 -1
- package/lib/esm/tests/api_tests/totp_mfa.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/totp_mfa.test.js +37 -31
- package/lib/esm/tests/api_tests/totp_mfa.test.js.map +1 -1
- package/lib/esm/tests/api_tests/trigger_contains_matching.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/trigger_contains_matching.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/trigger_contains_matching.test.js +2 -0
- package/lib/esm/tests/api_tests/trigger_contains_matching.test.js.map +1 -1
- package/lib/esm/tests/api_tests/user_logs_restore_deleted.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/user_logs_restore_deleted.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/user_logs_restore_deleted.test.js +2 -0
- package/lib/esm/tests/api_tests/user_logs_restore_deleted.test.js.map +1 -1
- package/lib/esm/tests/api_tests/vital_review_trigger_action.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/vital_review_trigger_action.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/vital_review_trigger_action.test.js +2 -0
- package/lib/esm/tests/api_tests/vital_review_trigger_action.test.js.map +1 -1
- package/lib/esm/tests/api_tests/vitl_push.test.d.ts +7 -0
- package/lib/esm/tests/api_tests/vitl_push.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/vitl_push.test.js +333 -0
- package/lib/esm/tests/api_tests/vitl_push.test.js.map +1 -0
- package/lib/esm/tests/setup_isolated.d.ts +48 -0
- package/lib/esm/tests/setup_isolated.d.ts.map +1 -1
- package/lib/esm/tests/setup_isolated.js +114 -0
- package/lib/esm/tests/setup_isolated.js.map +1 -1
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +375 -293
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/esm/tests/unit_tests/isolated_suite_discovery.test.d.ts +2 -0
- package/lib/esm/tests/unit_tests/isolated_suite_discovery.test.d.ts.map +1 -0
- package/lib/esm/tests/unit_tests/isolated_suite_discovery.test.js +174 -0
- package/lib/esm/tests/unit_tests/isolated_suite_discovery.test.js.map +1 -0
- package/lib/esm/tests/unit_tests/programs_conditional_logic.test.d.ts +3 -0
- package/lib/esm/tests/unit_tests/programs_conditional_logic.test.d.ts.map +1 -0
- package/lib/esm/tests/unit_tests/programs_conditional_logic.test.js +117 -0
- package/lib/esm/tests/unit_tests/programs_conditional_logic.test.js.map +1 -0
- package/lib/esm/tests/webhooks_tests.js +44 -34
- package/lib/esm/tests/webhooks_tests.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -11
- package/src/sdk.ts +3 -2
- package/src/tests/api_tests/booking_prevent_upcoming_duplicate.test.ts +541 -0
- package/src/tests/api_tests/enduser_fields_sync.test.ts +4 -0
- package/src/tests/api_tests/enduser_observations_auto_review.test.ts +4 -0
- package/src/tests/api_tests/form_vital_reading.test.ts +393 -0
- package/src/tests/api_tests/journey_statistics_cache.test.ts +237 -0
- package/src/tests/api_tests/journey_step_manual_count.test.ts +220 -0
- package/src/tests/api_tests/load_threads_care_team.test.ts +4 -0
- package/src/tests/api_tests/organization_signup.test.ts +4 -0
- package/src/tests/api_tests/phone_embed_leave_message.test.ts +541 -0
- package/src/tests/api_tests/programs.test.ts +351 -0
- package/src/tests/api_tests/public_form_case_insensitive_match.test.ts +632 -0
- package/src/tests/api_tests/security/add-to-journey-foreign-enduserid.test.ts +4 -0
- package/src/tests/api_tests/security/appointment-reschedule-ownership.test.ts +4 -0
- package/src/tests/api_tests/security/file-link-session-confinement.test.ts +4 -0
- package/src/tests/api_tests/security/form-logic-js-execution.test.ts +4 -0
- package/src/tests/api_tests/security/formsort_webhook_auth_field_lock.test.ts +225 -0
- package/src/tests/api_tests/security/register_business_id_injection.test.ts +2 -2
- package/src/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.ts +4 -0
- package/src/tests/api_tests/session_for_join_link.test.ts +99 -0
- package/src/tests/api_tests/set_fields_order_templates.test.ts +94 -9
- package/src/tests/api_tests/stripe_checkout_items.test.ts +186 -0
- package/src/tests/api_tests/tickets_bulk_assign_from_queue.test.ts +4 -0
- package/src/tests/api_tests/totp_mfa.test.ts +10 -5
- package/src/tests/api_tests/trigger_contains_matching.test.ts +4 -0
- package/src/tests/api_tests/user_logs_restore_deleted.test.ts +4 -0
- package/src/tests/api_tests/vital_review_trigger_action.test.ts +455 -0
- package/src/tests/api_tests/vitl_push.test.ts +323 -0
- package/src/tests/setup_isolated.ts +140 -0
- package/src/tests/tests.ts +124 -30
- package/src/tests/unit_tests/isolated_suite_discovery.test.ts +178 -0
- package/src/tests/unit_tests/programs_conditional_logic.test.ts +189 -0
- package/src/tests/webhooks_tests.ts +6 -1
- package/test_generated.pdf +0 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
require('source-map-support').install();
|
|
2
|
+
|
|
3
|
+
import * as fs from "fs"
|
|
4
|
+
import * as path from "path"
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
assert,
|
|
8
|
+
log_header,
|
|
9
|
+
} from "@tellescope/testing"
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
discover_isolated_suites,
|
|
13
|
+
isolated_suites_root,
|
|
14
|
+
parse_test_parallelism,
|
|
15
|
+
DEFAULT_TEST_PARALLELISM,
|
|
16
|
+
ISOLATED_SUITE_EXPORT,
|
|
17
|
+
} from "../setup_isolated"
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Guard for the auto-discovering dispatcher (run_discovered_isolated_suites).
|
|
21
|
+
*
|
|
22
|
+
* Discovery walks the COMPILED tree (lib/cjs/tests/api_tests), so the failure mode the old
|
|
23
|
+
* hand-maintained arrays did not have is a suite that silently stops running: a `.test.ts` enrolls
|
|
24
|
+
* itself, the build no-ops, and the dispatcher never sees it. Nothing else in the suite would
|
|
25
|
+
* notice. So the first check here compares the enrolled SOURCE files against what discovery
|
|
26
|
+
* actually loaded, in both directions — a missing one means a stale build (`npm run check:build`),
|
|
27
|
+
* an extra one means a compiled orphan of a deleted test.
|
|
28
|
+
*
|
|
29
|
+
* The other two checks protect the dispatcher's own invariants: names are the only handle on a
|
|
30
|
+
* suite in the output, and a suite that is both discovered and awaited by name in tests.ts would
|
|
31
|
+
* provision its tenants and run twice.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
// compiled location is <sdk>/lib/cjs/tests/unit_tests, so four levels up is the package root
|
|
35
|
+
const SRC_TESTS = path.resolve(__dirname, '..', '..', '..', '..', 'src', 'tests')
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Relative paths of every source file under `root` that enrolls itself, split by whether discovery
|
|
39
|
+
* could ever see it. Discovery only loads `*.test.js` under `api_tests`, so a marker anywhere else
|
|
40
|
+
* is a suite that silently never runs — hence `unreachable`, which is an error rather than a miss.
|
|
41
|
+
*/
|
|
42
|
+
const enrolled_source_files = (root: string) => {
|
|
43
|
+
const discoverable: string[] = []
|
|
44
|
+
const unreachable: string[] = []
|
|
45
|
+
|
|
46
|
+
const walk = (dir: string, prefix: string) => {
|
|
47
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
48
|
+
const relative = prefix ? `${prefix}/${entry.name}` : entry.name
|
|
49
|
+
|
|
50
|
+
if (entry.isDirectory()) { walk(path.join(dir, entry.name), relative); continue }
|
|
51
|
+
if (!entry.name.endsWith('.ts') || entry.name.endsWith('.d.ts')) continue
|
|
52
|
+
|
|
53
|
+
const source = fs.readFileSync(path.join(dir, entry.name), 'utf8')
|
|
54
|
+
if (!new RegExp(`^export const ${ISOLATED_SUITE_EXPORT}\\b`, 'm').test(source)) continue
|
|
55
|
+
|
|
56
|
+
const inApiTests = relative === 'api_tests' || relative.indexOf('api_tests/') === 0
|
|
57
|
+
if (inApiTests && entry.name.endsWith('.test.ts')) {
|
|
58
|
+
discoverable.push(relative.replace(/^api_tests\//, ''))
|
|
59
|
+
} else {
|
|
60
|
+
unreachable.push(relative)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
walk(root, '')
|
|
65
|
+
|
|
66
|
+
return { discoverable: discoverable.sort(), unreachable: unreachable.sort() }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const isolated_suite_discovery_unit_tests = async () => {
|
|
70
|
+
log_header("Isolated suite discovery")
|
|
71
|
+
|
|
72
|
+
const discovered = discover_isolated_suites() // throws on a malformed descriptor or a duplicate name
|
|
73
|
+
const discoveredFiles = discovered.map(s => s.file).sort()
|
|
74
|
+
|
|
75
|
+
if (!fs.existsSync(SRC_TESTS)) {
|
|
76
|
+
// Published package, not the monorepo — there is no source tree to compare against.
|
|
77
|
+
console.log(` SKIPPED source comparison: no source tree at ${SRC_TESTS}`)
|
|
78
|
+
} else {
|
|
79
|
+
const { discoverable, unreachable } = enrolled_source_files(SRC_TESTS)
|
|
80
|
+
const enrolled = discoverable.map(f => f.replace(/\.ts$/, '.js'))
|
|
81
|
+
|
|
82
|
+
// Scanning all of src/tests, not just api_tests: an ISOLATED_SUITE outside the discovered tree
|
|
83
|
+
// (wrong directory, or a filename that is not *.test.ts) would never run and nothing else would say so.
|
|
84
|
+
assert(
|
|
85
|
+
unreachable.length === 0,
|
|
86
|
+
`exports ${ISOLATED_SUITE_EXPORT} where discovery can never see it (must be api_tests/**/*.test.ts): ${unreachable.join(', ')}`,
|
|
87
|
+
`every ${ISOLATED_SUITE_EXPORT} in src/tests lives where discovery looks`,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
const missing = enrolled.filter(f => discoveredFiles.indexOf(f) === -1)
|
|
91
|
+
const extra = discoveredFiles.filter(f => enrolled.indexOf(f) === -1)
|
|
92
|
+
|
|
93
|
+
assert(
|
|
94
|
+
missing.length === 0,
|
|
95
|
+
`enrolled in src but NOT discovered (stale lib/cjs? run npm run check:build -- --fix): ${missing.join(', ')}`,
|
|
96
|
+
`every src file exporting ${ISOLATED_SUITE_EXPORT} is discovered (${enrolled.length})`,
|
|
97
|
+
)
|
|
98
|
+
assert(
|
|
99
|
+
extra.length === 0,
|
|
100
|
+
`discovered but not enrolled in any src file (compiled orphan? delete lib/cjs and rebuild): ${extra.join(', ')}`,
|
|
101
|
+
'every discovered suite has a source file',
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
assert(discovered.length > 0, `no isolated suites discovered under ${isolated_suites_root()}`, 'suites were discovered')
|
|
106
|
+
|
|
107
|
+
// Names are the only handle on a suite in the run output and in a failure message.
|
|
108
|
+
const byName: Record<string, string[]> = {}
|
|
109
|
+
for (const s of discovered) {
|
|
110
|
+
byName[s.name] = (byName[s.name] || []).concat(s.file)
|
|
111
|
+
}
|
|
112
|
+
const duplicateNames = Object.keys(byName).filter(n => byName[n].length > 1)
|
|
113
|
+
assert(
|
|
114
|
+
duplicateNames.length === 0,
|
|
115
|
+
`duplicate suite names: ${duplicateNames.map(n => `${JSON.stringify(n)} in ${byName[n].join(' and ')}`).join('; ')}`,
|
|
116
|
+
`suite names are unique (${discovered.length})`,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
// A discovered suite must not ALSO be awaited by name in tests.ts — that would run it twice, each
|
|
120
|
+
// run provisioning its own tenants (which can never be deleted).
|
|
121
|
+
const testsPath = path.join(SRC_TESTS, 'tests.ts')
|
|
122
|
+
if (!fs.existsSync(testsPath)) {
|
|
123
|
+
console.log(` SKIPPED tests.ts comparison: not found at ${testsPath}`)
|
|
124
|
+
} else {
|
|
125
|
+
const testsSource = fs.readFileSync(testsPath, 'utf8')
|
|
126
|
+
|
|
127
|
+
const doubleRun: string[] = []
|
|
128
|
+
for (const suite of discovered) {
|
|
129
|
+
const loaded = require(path.join(isolated_suites_root(), suite.file))
|
|
130
|
+
for (const exported of Object.keys(loaded)) {
|
|
131
|
+
if (exported === ISOLATED_SUITE_EXPORT) continue // every enrolled file exports this one
|
|
132
|
+
if (new RegExp(`\\bawait\\s+${exported}\\s*\\(`).test(testsSource)) {
|
|
133
|
+
doubleRun.push(`${exported} (api_tests/${suite.file}, discovered as "${suite.name}")`)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
assert(
|
|
138
|
+
doubleRun.length === 0,
|
|
139
|
+
`awaited directly in tests.ts as well as discovered, so it would run twice: ${doubleRun.join(', ')}`,
|
|
140
|
+
'no discovered suite is also awaited directly in tests.ts',
|
|
141
|
+
)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// TEST_PARALLELISM parsing: a bad value must fall back to the default, never to "unlimited".
|
|
145
|
+
const parallelismCases: [string | undefined, number][] = [
|
|
146
|
+
[undefined, DEFAULT_TEST_PARALLELISM],
|
|
147
|
+
['', DEFAULT_TEST_PARALLELISM],
|
|
148
|
+
[' ', DEFAULT_TEST_PARALLELISM],
|
|
149
|
+
['abc', DEFAULT_TEST_PARALLELISM],
|
|
150
|
+
['0', DEFAULT_TEST_PARALLELISM],
|
|
151
|
+
['-1', DEFAULT_TEST_PARALLELISM],
|
|
152
|
+
['2.5', DEFAULT_TEST_PARALLELISM],
|
|
153
|
+
['1', 1],
|
|
154
|
+
[' 3 ', 3],
|
|
155
|
+
['16', 16],
|
|
156
|
+
]
|
|
157
|
+
for (const [raw, expected] of parallelismCases) {
|
|
158
|
+
const actual = parse_test_parallelism(raw)
|
|
159
|
+
assert(
|
|
160
|
+
actual === expected,
|
|
161
|
+
`TEST_PARALLELISM=${JSON.stringify(raw)} parsed as ${actual}, expected ${expected}`,
|
|
162
|
+
`TEST_PARALLELISM=${JSON.stringify(raw)} → ${expected}`,
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Allow running this test file independently
|
|
168
|
+
if (require.main === module) {
|
|
169
|
+
isolated_suite_discovery_unit_tests()
|
|
170
|
+
.then(() => {
|
|
171
|
+
console.log("Isolated suite discovery unit tests completed successfully")
|
|
172
|
+
process.exit(0)
|
|
173
|
+
})
|
|
174
|
+
.catch((error) => {
|
|
175
|
+
console.error("Isolated suite discovery unit tests failed:", error)
|
|
176
|
+
process.exit(1)
|
|
177
|
+
})
|
|
178
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { evaluate_conditional_logic_for_enduser_fields, validate_custom_field_references } from "@tellescope/utilities"
|
|
2
|
+
import { Enduser, EnduserProgram } from "@tellescope/types-models"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Unit coverage for the `Programs` key in evaluate_conditional_logic_for_enduser_fields — the V1
|
|
6
|
+
* evaluator that triggers, journeys and phone-tree branches all run on.
|
|
7
|
+
*
|
|
8
|
+
* `{ Programs: { $in: 'CHF' } }` means "has a program named CHF"; adding `$status` means "...whose
|
|
9
|
+
* status is S", bound to that same program entry. Comparison is exact string throughout, matching the
|
|
10
|
+
* shipped Order Status Equals / Vital Update program filters.
|
|
11
|
+
*
|
|
12
|
+
* The round-trip between this and the saved V2 Mongo filter is covered separately, by
|
|
13
|
+
* packages/private/webapp/src/__tests__/programs_condition_filter.test.ts.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
let failures = 0
|
|
17
|
+
let passed = 0
|
|
18
|
+
|
|
19
|
+
const assert = (name: string, actual: boolean, expected: boolean) => {
|
|
20
|
+
if (actual === expected) {
|
|
21
|
+
passed++
|
|
22
|
+
console.log(` ✓ ${name}`)
|
|
23
|
+
} else {
|
|
24
|
+
failures++
|
|
25
|
+
console.error(` ✗ ${name} — expected ${expected}, got ${actual}`)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const with_programs = (programs?: EnduserProgram[]) => ({ programs } as Omit<Enduser, 'id'>)
|
|
30
|
+
|
|
31
|
+
const matches = (programs: EnduserProgram[] | undefined, value: Record<string, any>) => (
|
|
32
|
+
evaluate_conditional_logic_for_enduser_fields(
|
|
33
|
+
with_programs(programs) as any,
|
|
34
|
+
{ $and: [{ condition: { Programs: value } }] },
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
const CHF_ACTIVE: EnduserProgram[] = [{ name: 'CHF', status: 'active' }]
|
|
39
|
+
const CHF_COMPLETED: EnduserProgram[] = [{ name: 'CHF', status: 'completed' }]
|
|
40
|
+
const CHF_NO_STATUS: EnduserProgram[] = [{ name: 'CHF' }]
|
|
41
|
+
const TWO: EnduserProgram[] = [{ name: 'CHF', status: 'completed' }, { name: 'Diabetes', status: 'active' }]
|
|
42
|
+
|
|
43
|
+
const run_is_in_tests = () => {
|
|
44
|
+
console.log("\n[Programs / Is In]")
|
|
45
|
+
|
|
46
|
+
assert("matches a patient with that program", matches(CHF_ACTIVE, { $in: 'CHF' }), true)
|
|
47
|
+
assert("does not match a patient with a different program", matches([{ name: 'Diabetes' }], { $in: 'CHF' }), false)
|
|
48
|
+
assert("does not match a patient with no programs", matches([], { $in: 'CHF' }), false)
|
|
49
|
+
assert("does not match a patient whose programs are unset", matches(undefined, { $in: 'CHF' }), false)
|
|
50
|
+
assert("matches one program among several", matches(TWO, { $in: 'Diabetes' }), true)
|
|
51
|
+
|
|
52
|
+
// exact string comparison — deliberately NOT case-insensitive
|
|
53
|
+
assert("name comparison is case sensitive", matches(CHF_ACTIVE, { $in: 'chf' }), false)
|
|
54
|
+
assert("name comparison does not substring match", matches(CHF_ACTIVE, { $in: 'CH' }), false)
|
|
55
|
+
assert("a name with spaces and punctuation matches exactly", matches([{ name: 'Post-Op Care' }], { $in: 'Post-Op Care' }), true)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const run_status_tests = () => {
|
|
59
|
+
console.log("\n[Programs / $status]")
|
|
60
|
+
|
|
61
|
+
assert("name + status both match", matches(CHF_ACTIVE, { $in: 'CHF', $status: 'active' }), true)
|
|
62
|
+
assert("name matches but status does not", matches(CHF_COMPLETED, { $in: 'CHF', $status: 'active' }), false)
|
|
63
|
+
assert("status matches but name does not", matches(CHF_ACTIVE, { $in: 'Diabetes', $status: 'active' }), false)
|
|
64
|
+
assert("a program with no status is not matched by a status condition", matches(CHF_NO_STATUS, { $in: 'CHF', $status: 'active' }), false)
|
|
65
|
+
assert("a blank status means any status", matches(CHF_COMPLETED, { $in: 'CHF', $status: '' }), true)
|
|
66
|
+
assert("an omitted status means any status", matches(CHF_NO_STATUS, { $in: 'CHF' }), true)
|
|
67
|
+
assert("status comparison is case sensitive", matches(CHF_ACTIVE, { $in: 'CHF', $status: 'Active' }), false)
|
|
68
|
+
|
|
69
|
+
// name and status must come from the SAME program, which is the whole point of one paired key
|
|
70
|
+
assert(
|
|
71
|
+
"does not match when the name and the status come from different programs",
|
|
72
|
+
matches(TWO, { $in: 'CHF', $status: 'active' }),
|
|
73
|
+
false,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
// $status serialised FIRST — the generic Object.keys(value)[0] operator dispatch would pick $status
|
|
77
|
+
// here and fall through to false, so the Programs branch must read $in/$nin by name
|
|
78
|
+
assert(
|
|
79
|
+
"$status before $in still evaluates as Is In",
|
|
80
|
+
matches(CHF_ACTIVE, { $status: 'active', $in: 'CHF' }),
|
|
81
|
+
true,
|
|
82
|
+
)
|
|
83
|
+
assert(
|
|
84
|
+
"$status before $nin still evaluates as Is Not In",
|
|
85
|
+
matches(CHF_ACTIVE, { $status: 'active', $nin: 'CHF' }),
|
|
86
|
+
false,
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const run_is_not_in_tests = () => {
|
|
91
|
+
console.log("\n[Programs / Is Not In]")
|
|
92
|
+
|
|
93
|
+
assert("does not match a patient with that program", matches(CHF_ACTIVE, { $nin: 'CHF' }), false)
|
|
94
|
+
assert("matches a patient with a different program", matches([{ name: 'Diabetes' }], { $nin: 'CHF' }), true)
|
|
95
|
+
assert("matches a patient with no programs", matches([], { $nin: 'CHF' }), true)
|
|
96
|
+
assert("matches a patient whose programs are unset", matches(undefined, { $nin: 'CHF' }), true)
|
|
97
|
+
|
|
98
|
+
assert("negates the name+status pair", matches(CHF_ACTIVE, { $nin: 'CHF', $status: 'active' }), false)
|
|
99
|
+
assert("matches when the name is present but the status differs", matches(CHF_COMPLETED, { $nin: 'CHF', $status: 'active' }), true)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const run_unconfigured_tests = () => {
|
|
103
|
+
console.log("\n[Programs / unconfigured]")
|
|
104
|
+
|
|
105
|
+
// An unfinished condition must match nobody in BOTH directions. This deliberately DIVERGES from
|
|
106
|
+
// Journeys rather than copying it: `{ Journeys: { $nin: '' } }` matches everybody (the blank id is
|
|
107
|
+
// simply absent from enduser.journeys). Failing open on $nin would fire a trigger for every patient.
|
|
108
|
+
assert("a blank name matches nobody under Is In", matches(CHF_ACTIVE, { $in: '' }), false)
|
|
109
|
+
assert("a blank name matches nobody under Is Not In", matches(CHF_ACTIVE, { $nin: '' }), false)
|
|
110
|
+
assert("a blank name matches nobody even with no programs", matches([], { $nin: '' }), false)
|
|
111
|
+
assert("a value with no operator matches nobody", matches(CHF_ACTIVE, { $status: 'active' }), false)
|
|
112
|
+
|
|
113
|
+
// the branch is narrowed to $in/$nin, so any other object condition under a key named 'Programs'
|
|
114
|
+
// falls through to the generic custom-field handler — which is what the V2 translator does too
|
|
115
|
+
assert("a non-$in/$nin operator falls through instead of being swallowed", matches(CHF_ACTIVE, { $isSet: 'Value' }), false)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const run_other_conditions_unaffected = () => {
|
|
119
|
+
console.log("\n[Programs / coexistence with Care Type and Stage]")
|
|
120
|
+
|
|
121
|
+
const enduser = {
|
|
122
|
+
programs: CHF_ACTIVE,
|
|
123
|
+
fields: { 'Care Type': 'RPM', 'Care Stage': 'Onboarding' },
|
|
124
|
+
} as any
|
|
125
|
+
|
|
126
|
+
const evaluate = (conditions: Record<string, any>) => (
|
|
127
|
+
evaluate_conditional_logic_for_enduser_fields(enduser, conditions)
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
assert(
|
|
131
|
+
"an existing Care Type condition is unaffected",
|
|
132
|
+
evaluate({ $and: [{ condition: { 'Care Type': 'RPM' } }] }),
|
|
133
|
+
true,
|
|
134
|
+
)
|
|
135
|
+
assert(
|
|
136
|
+
"Care Stage and Programs can be combined in one filter",
|
|
137
|
+
evaluate({ $and: [{ condition: { 'Care Stage': 'Onboarding' } }, { condition: { Programs: { $in: 'CHF' } } }] }),
|
|
138
|
+
true,
|
|
139
|
+
)
|
|
140
|
+
assert(
|
|
141
|
+
"the combined filter fails when the Programs half fails",
|
|
142
|
+
evaluate({ $and: [{ condition: { 'Care Stage': 'Onboarding' } }, { condition: { Programs: { $in: 'Diabetes' } } }] }),
|
|
143
|
+
false,
|
|
144
|
+
)
|
|
145
|
+
assert(
|
|
146
|
+
"an $or over Care Type and Programs matches on either half",
|
|
147
|
+
evaluate({ $or: [{ condition: { 'Care Type': 'Nope' } }, { condition: { Programs: { $in: 'CHF' } } }] }),
|
|
148
|
+
true,
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const run_custom_field_validation_tests = () => {
|
|
153
|
+
console.log("\n[Programs is a built-in field]")
|
|
154
|
+
|
|
155
|
+
// without 'Programs' in BUILT_IN_FIELDS, the trigger and journey validation hooks flag every program
|
|
156
|
+
// condition as a reference to a custom field that no longer exists
|
|
157
|
+
const conditions = { $and: [{ condition: { Programs: { $in: 'CHF', $status: 'active' } } }] }
|
|
158
|
+
assert(
|
|
159
|
+
"a Programs condition is not reported as a missing custom field",
|
|
160
|
+
validate_custom_field_references(conditions, new Set<string>()).length === 0,
|
|
161
|
+
true,
|
|
162
|
+
)
|
|
163
|
+
assert(
|
|
164
|
+
"a genuinely missing custom field is still reported",
|
|
165
|
+
validate_custom_field_references(
|
|
166
|
+
{ $and: [{ condition: { deletedField: 'x' } }] },
|
|
167
|
+
new Set<string>(),
|
|
168
|
+
).includes('deletedField'),
|
|
169
|
+
true,
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const run_all = () => {
|
|
174
|
+
console.log("Running programs_conditional_logic unit tests")
|
|
175
|
+
run_is_in_tests()
|
|
176
|
+
run_status_tests()
|
|
177
|
+
run_is_not_in_tests()
|
|
178
|
+
run_unconfigured_tests()
|
|
179
|
+
run_other_conditions_unaffected()
|
|
180
|
+
run_custom_field_validation_tests()
|
|
181
|
+
console.log(`\nResults: ${passed} passed, ${failures} failed`)
|
|
182
|
+
if (failures > 0) process.exit(1)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (require.main === module) {
|
|
186
|
+
run_all()
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export { run_all as programs_conditional_logic_unit_tests }
|
|
@@ -756,8 +756,13 @@ const run_tests = async () => {
|
|
|
756
756
|
log_header("Webhooks Tests")
|
|
757
757
|
await sdk.authenticate(email, password)
|
|
758
758
|
await sdkSub.authenticate(subUserEmail, password)
|
|
759
|
-
await reset_test_tenant(sdk)
|
|
759
|
+
await reset_test_tenant(sdk)
|
|
760
760
|
await nonAdminSdk.authenticate(nonAdminEmail, nonAdminPassword)
|
|
761
|
+
// as in setup_tests: booking cancel/reschedule below would otherwise email the host for real
|
|
762
|
+
await Promise.all([
|
|
763
|
+
sdk.api.users.updateOne(sdk.userInfo.id, { notificationEmailsDisabled: true }),
|
|
764
|
+
sdk.api.users.updateOne(nonAdminSdk.userInfo.id, { notificationEmailsDisabled: true }),
|
|
765
|
+
]).catch(console.error)
|
|
761
766
|
|
|
762
767
|
await async_test(
|
|
763
768
|
'configure webhook is admin only',
|
package/test_generated.pdf
CHANGED
|
Binary file
|