diff --git a/.eslintrc.json b/.eslintrc.json index d2928e50fdc..7258c5c5366 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -9,9 +9,9 @@ "airbnb-base", "airbnb-typescript/base", "plugin:sonarjs/recommended", - "prettier", "plugin:json/recommended", - "plugin:@typescript-eslint/recommended" + "plugin:@typescript-eslint/recommended", + "prettier" ], "plugins": ["@typescript-eslint", "unicorn"], "globals": {}, diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b18fd293573..040e07f81d2 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,3 +4,11 @@ updates: directory: '/' schedule: interval: 'weekly' + - package-ecosystem: 'docker' + directory: '/' + schedule: + interval: 'daily' + - package-ecosystem: 'npm' + directory: '/' + schedule: + interval: 'daily' diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index fe308ce8b93..cfcb1fc0d8c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -26,6 +26,8 @@ N/A N/A +@coderabbitai review +
### Developer checklist diff --git a/.github/workflows/build-push-docker-image.yml b/.github/workflows/build-push-docker-image.yml index 9f6709a0405..7ddae0a3aed 100644 --- a/.github/workflows/build-push-docker-image.yml +++ b/.github/workflows/build-push-docker-image.yml @@ -155,7 +155,7 @@ jobs: if: ${{ inputs.build_type == 'dt' }} run: | docker buildx imagetools create -t rudderstack/rudder-transformer:latest ${{ inputs.push_tags }}-amd64 ${{ inputs.push_tags }}-arm64 - + - name: Create latest ut multi-arch manifest # To be triggered only for release/hotfix PR merges coming from `prepare-for-prod-ut-deploy.yaml` if: ${{ inputs.build_type == 'ut' }} diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 00000000000..a8ff39eee0d --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,36 @@ +name: Commitlint + +on: [push] + +jobs: + commitlint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + fetch-depth: 0 + + - name: Setup Node + uses: actions/setup-node@v4.0.1 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install Dependencies + run: npm ci + + - name: Print versions + run: | + git --version + node --version + npm --version + npx commitlint --version + + # Run the commitlint action, considering its own dependencies and yours as well 🚀 + # `github.workspace` is the path to your repository. + - uses: wagoid/commitlint-github-action@v5 + env: + NODE_PATH: ${{ github.workspace }}/node_modules + with: + commitDepth: 1 diff --git a/.github/workflows/component-test-report.yml b/.github/workflows/component-test-report.yml index 99040044178..3d457df9ff8 100644 --- a/.github/workflows/component-test-report.yml +++ b/.github/workflows/component-test-report.yml @@ -28,7 +28,7 @@ jobs: fetch-depth: 1 - name: Setup Node - uses: actions/setup-node@v4.0.1 + uses: actions/setup-node@v4.0.2 with: node-version-file: '.nvmrc' cache: 'npm' @@ -40,13 +40,11 @@ jobs: run: | npm run test:ts -- component - - name: Uplaod Report to S3 run: | aws s3 cp ./test_reports/ s3://test-integrations-dev/integrations-test-reports/rudder-transformer/${{ github.event.number }}/ --recursive - - - name: Comment on PR with S3 Object URL + - name: Add Test Report Link as Comment on PR uses: actions/github-script@v7 with: github-token: ${{ secrets.PAT }} @@ -55,14 +53,25 @@ jobs: // Get the pull request number const prNumber = context.payload.pull_request.number; const commentBody = `Test report for this run is available at: https://test-integrations-dev.s3.amazonaws.com/integrations-test-reports/rudder-transformer/${prNumber}/test-report.html`; - + + // find all the comments of the PR + const issueComments = await github.paginate(github.rest.issues.listComments, { + owner, + repo, + issue_number: prNumber, + }); + + for (const comment of issueComments) { + if (comment.body === commentBody) { + console.log('Comment already exists'); + return; + } + } // Comment on the pull request - github.rest.issues.createComment({ + await github.rest.issues.createComment({ owner, repo, issue_number: prNumber, body: commentBody }); - - \ No newline at end of file diff --git a/.github/workflows/create-hotfix-branch.yml b/.github/workflows/create-hotfix-branch.yml index a164c25beee..994283a9f43 100644 --- a/.github/workflows/create-hotfix-branch.yml +++ b/.github/workflows/create-hotfix-branch.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest # Only allow these users to create new hotfix branch from 'main' - if: github.ref == 'refs/heads/main' && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'koladilip' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'ujjwal-ab') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'koladilip' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'ujjwal-ab') + if: github.ref == 'refs/heads/main' && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'koladilip' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'utsabc') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'koladilip' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'sanpj2292' || github.triggering_actor == 'utsabc') steps: - name: Create Branch uses: peterjgrainger/action-create-branch@v2.4.0 diff --git a/.github/workflows/draft-new-release.yml b/.github/workflows/draft-new-release.yml index 33b0396705c..95431fef8ee 100644 --- a/.github/workflows/draft-new-release.yml +++ b/.github/workflows/draft-new-release.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest # Only allow release stakeholders to initiate releases - if: (github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/hotfix/')) && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'koladilip' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'yashasvibajpai' || github.actor == 'sanpj2292' || github.actor == 'ujjwal-ab') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'koladilip' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'yashasvibajpai' || github.triggering_actor == 'sanpj2292' || github.triggering_actor == 'ujjwal-ab') + if: (github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/hotfix/')) && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'koladilip' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'yashasvibajpai' || github.actor == 'sanpj2292' || github.actor == 'utsabc') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'koladilip' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'yashasvibajpai' || github.triggering_actor == 'sanpj2292' || github.triggering_actor == 'utsabc') steps: - name: Checkout uses: actions/checkout@v4.1.1 @@ -16,7 +16,7 @@ jobs: fetch-depth: 0 - name: Setup Node - uses: actions/setup-node@v4.0.1 + uses: actions/setup-node@v4.0.2 with: node-version-file: '.nvmrc' cache: 'npm' diff --git a/.github/workflows/dt-test-and-report-code-coverage.yml b/.github/workflows/dt-test-and-report-code-coverage.yml index 40962274003..4375b3383e0 100644 --- a/.github/workflows/dt-test-and-report-code-coverage.yml +++ b/.github/workflows/dt-test-and-report-code-coverage.yml @@ -20,7 +20,7 @@ jobs: fetch-depth: 1 - name: Setup Node - uses: actions/setup-node@v4.0.1 + uses: actions/setup-node@v4.0.2 with: node-version-file: '.nvmrc' cache: 'npm' @@ -40,12 +40,16 @@ jobs: npm run lint:fix - name: Upload Coverage Reports to Codecov - uses: codecov/codecov-action@v3.1.4 + uses: codecov/codecov-action@v4.0.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: directory: ./reports/coverage - name: Upload TS Coverage Reports to Codecov - uses: codecov/codecov-action@v3.1.4 + uses: codecov/codecov-action@v4.0.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: directory: ./reports/ts-coverage diff --git a/.github/workflows/prepare-for-prod-dt-deploy.yml b/.github/workflows/prepare-for-prod-dt-deploy.yml index 2af853f6430..a5ca48e3f83 100644 --- a/.github/workflows/prepare-for-prod-dt-deploy.yml +++ b/.github/workflows/prepare-for-prod-dt-deploy.yml @@ -144,3 +144,39 @@ jobs: git push -u origin hosted-transformer-$TAG_NAME gh pr create --fill + + - name: Update helm charts and raise pull request for enterprise customers on dedicated transformers + env: + GITHUB_TOKEN: ${{ secrets.PAT }} + run: | + cd rudder-devops + git checkout -b dedicated-transformer-$TAG_NAME + + cd customer-objects + + declare -a enabled_ut_customers=() + declare -a sub_directories=('enterprise-us' 'enterprise-eu') + + # identify the customers enabled in sub-directories + for directory in "${sub_directories[@]}"; do + for f in "./$directory"/*; do + [[ -f $f ]] || continue + + enabled="$(yq e '.spec.user_transformer.enabled' $f)" + if [ $enabled == "true" ]; then + enabled_ut_customers+=( $f ) + fi + done + done + + # bump up the customers version and repository information + for customer in "${enabled_ut_customers[@]}"; do + yq eval -i ".spec.user_transformer.image.version=\"$TAG_NAME\"" $customer + yq eval -i ".spec.user_transformer.image.repository=\"$TF_IMAGE_REPOSITORY\"" $customer + git add $customer + done + + git commit -m "chore: upgrade dedicated transformers to $TAG_NAME" + git push -u origin dedicated-transformer-$TAG_NAME + + gh pr create --fill diff --git a/.github/workflows/prepare-for-prod-rollback.yml b/.github/workflows/prepare-for-prod-rollback.yml index 9ac144a21e0..825720efe1a 100644 --- a/.github/workflows/prepare-for-prod-rollback.yml +++ b/.github/workflows/prepare-for-prod-rollback.yml @@ -27,11 +27,14 @@ jobs: git config --global user.name "GitHub Actions" git config --global user.email "noreply@github.com" + - name: Clone Devops Repo + run: | + git clone https://${{secrets.PAT}}@github.com/rudderlabs/rudder-devops.git + - name: Update Helm Charts and Raise Pull Request env: GITHUB_TOKEN: ${{ secrets.PAT }} run: | - git clone https://${{secrets.PAT}}@github.com/rudderlabs/rudder-devops.git cd rudder-devops git checkout -b shared-transformer-rollback-${{ steps.target-version.outputs.tag_name }} @@ -57,3 +60,38 @@ jobs: git push -u origin shared-transformer-rollback-${{ steps.target-version.outputs.tag_name }} gh pr create --fill + + - name: Update helm charts and raise pull request for enterprise customers on dedicated transformers + env: + GITHUB_TOKEN: ${{ secrets.PAT }} + run: | + cd rudder-devops + git checkout -b dedicated-transformer-rollback-${{ steps.target-version.outputs.tag_name }} + + cd customer-objects + + declare -a enabled_ut_customers=() + declare -a sub_directories=('enterprise-us' 'enterprise-eu') + + # identify the customers enabled in sub-directories + for directory in "${sub_directories[@]}"; do + for f in "./$directory"/*; do + [[ -f $f ]] || continue + + enabled="$(yq e '.spec.user_transformer.enabled' $f)" + if [ $enabled == "true" ]; then + enabled_ut_customers+=( $f ) + fi + done + done + + # bump up the customers version and repository information + for customer in "${enabled_ut_customers[@]}"; do + yq eval -i ".spec.user_transformer.image.version=\"${{ steps.target-version.outputs.tag_name }}\"" $customer + git add $customer + done + + git commit -m "chore: rollback dedicated transformers to ${{ steps.target-version.outputs.tag_name }}" + git push -u origin dedicated-transformer-rollback-${{ steps.target-version.outputs.tag_name }} + + gh pr create --fill diff --git a/.github/workflows/prepare-for-staging-deploy.yml b/.github/workflows/prepare-for-staging-deploy.yml index 4e8f29cffa7..3e0b3aac19b 100644 --- a/.github/workflows/prepare-for-staging-deploy.yml +++ b/.github/workflows/prepare-for-staging-deploy.yml @@ -68,7 +68,6 @@ jobs: secrets: DOCKERHUB_PROD_TOKEN: ${{ secrets.DOCKERHUB_PROD_TOKEN }} - create-pull-request: name: Update Helm Charts For Staging and Create Pull Request runs-on: ubuntu-latest @@ -102,7 +101,7 @@ jobs: cd rudder-devops BRANCH_NAME="shared-transformer-$TAG_NAME" echo $BRANCH_NAME - if [ `git ls-remote --heads origin $BRANCH_NAME 2>/dev/null` ] + if [ -n "$(git ls-remote --heads origin $BRANCH_NAME 2>/dev/null)" ] then echo "Staging deployment branch already exists!" else @@ -113,9 +112,9 @@ jobs: yq eval -i ".user-transformer.image.tag=\"$TAG_NAME\"" staging.yaml git add staging.yaml - cd ../../../../config-be-rudder-transformer - yq eval -i ".config-be-rudder-transformer.image.tag=\"$TAG_NAME\"" values.staging.yaml - yq eval -i ".config-be-user-transformer.image.tag=\"$TAG_NAME\"" values.staging.yaml + cd ../../../../config-be-rudder-transformer/environment/staging + yq eval -i ".config-be-rudder-transformer.image.tag=\"$TAG_NAME\"" base.yaml + yq eval -i ".config-be-user-transformer.image.tag=\"$TAG_NAME\"" base.yaml git add values.staging.yaml git commit -m "chore: upgrade staging env transformers to \"$TAG_NAME\"" diff --git a/.github/workflows/publish-new-release.yml b/.github/workflows/publish-new-release.yml index 9d1558d8265..233e99577dc 100644 --- a/.github/workflows/publish-new-release.yml +++ b/.github/workflows/publish-new-release.yml @@ -30,7 +30,7 @@ jobs: fetch-depth: 0 - name: Setup Node - uses: actions/setup-node@v4.0.1 + uses: actions/setup-node@v4.0.2 with: node-version-file: '.nvmrc' cache: 'npm' @@ -89,7 +89,7 @@ jobs: - name: Notify Slack Channel id: slack - uses: slackapi/slack-github-action@v1.24.0 + uses: slackapi/slack-github-action@v1.25.0 continue-on-error: true env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/ut-tests.yml b/.github/workflows/ut-tests.yml index 30c29ceaee3..0a2ef8a3909 100644 --- a/.github/workflows/ut-tests.yml +++ b/.github/workflows/ut-tests.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 1 - name: Setup Node - uses: actions/setup-node@v4.0.1 + uses: actions/setup-node@v4.0.2 with: node-version-file: '.nvmrc' cache: 'npm' diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml new file mode 100644 index 00000000000..4caef8dd918 --- /dev/null +++ b/.github/workflows/verify.yml @@ -0,0 +1,36 @@ +name: Verify + +on: + pull_request: + +jobs: + formatting-lint: + name: Check for formatting & lint errors + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + with: + # Make sure the actual branch is checked out when running on pull requests + ref: ${{ github.head_ref }} + + - name: Setup Node + uses: actions/setup-node@v3.7.0 + with: + node-version-file: .nvmrc + cache: 'npm' + + - name: Install Dependencies + run: npm ci + + - name: Run Lint Checks + run: | + npm run lint + + - run: git diff --exit-code + + - name: Error message + if: ${{ failure() }} + run: | + echo 'Eslint check is failing Ensure you have run `npm run lint` and committed the files locally.' diff --git a/.gitignore b/.gitignore index f96c3ac8077..09c536ebb80 100644 --- a/.gitignore +++ b/.gitignore @@ -132,9 +132,10 @@ dist # Others **/.DS_Store - +.dccache .idea # component test report -test_reports/ \ No newline at end of file +test_reports/ +temp/ diff --git a/.nvmrc b/.nvmrc index a9d087399d7..3c5535cf60a 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18.19.0 +18.19.1 diff --git a/.prettierignore b/.prettierignore index 93eb370b0de..99747b29bbb 100644 --- a/.prettierignore +++ b/.prettierignore @@ -7,3 +7,4 @@ test/**/*.js !test/**/data.js src/util/lodash-es-core.js src/util/url-search-params.min.js +dist diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000000..13c49c08f15 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,24 @@ +{ + "prettier.requireConfig": true, + "prettier.configPath": ".prettierrc", + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "[jsonc]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "[yaml]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "editor.codeActionsOnSave": { + "source.organizeImports": "never" + }, + "eslint.validate": ["javascript", "typescript"] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 034e9251f18..5d3a37e1221 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,147 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.60.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.57.1...v1.60.0) (2024-03-20) + + +### Features + +* ninetailed: add default value for context.location as {} ([#3197](https://github.com/rudderlabs/rudder-transformer/issues/3197)) ([91fc0fb](https://github.com/rudderlabs/rudder-transformer/commit/91fc0fb3e9eeb127298a0ce305ef6d1d7b72a39f)) + + +### Bug Fixes + +* heap: make userId as required for track and identify call ([#3198](https://github.com/rudderlabs/rudder-transformer/issues/3198)) ([6a7c534](https://github.com/rudderlabs/rudder-transformer/commit/6a7c534a7df812bb7e39c1905eadcc29d7cd1329)) +* tiktok_ads: validate message.event type ([#3203](https://github.com/rudderlabs/rudder-transformer/issues/3203)) ([a86c277](https://github.com/rudderlabs/rudder-transformer/commit/a86c2771034877cef4161cda61bcda5fdda2d89f)) + +## [1.59.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.57.1...v1.59.0) (2024-03-18) + + +### Features + +* add Koala destination ([#3122](https://github.com/rudderlabs/rudder-transformer/issues/3122)) ([1ca039d](https://github.com/rudderlabs/rudder-transformer/commit/1ca039d64ebb1a18a0fc6b78ed5ee08528ad6b48)) +* add support of skip_user_properties_sync on Amplitude ([#3181](https://github.com/rudderlabs/rudder-transformer/issues/3181)) ([5e4ddbd](https://github.com/rudderlabs/rudder-transformer/commit/5e4ddbd8a591341a581a5721505d6dcb010f2eec)) +* adding zod validations ([#3066](https://github.com/rudderlabs/rudder-transformer/issues/3066)) ([325433b](https://github.com/rudderlabs/rudder-transformer/commit/325433b9188c8d1dbe740c7e193cdc2e58fdd751)) +* onboard destination movable ink ([#3167](https://github.com/rudderlabs/rudder-transformer/issues/3167)) ([7018b1e](https://github.com/rudderlabs/rudder-transformer/commit/7018b1e5e7f37ae177191c5ecf3a71cfe2f3d147)) +* update proxy tests for cm360 ([#3039](https://github.com/rudderlabs/rudder-transformer/issues/3039)) ([0504ffa](https://github.com/rudderlabs/rudder-transformer/commit/0504ffa898956f5b61771fb32ecfd0e0bf15248f)) +* use dontBatch directive in algolia ([#3169](https://github.com/rudderlabs/rudder-transformer/issues/3169)) ([916aaec](https://github.com/rudderlabs/rudder-transformer/commit/916aaecb1939160620d5fd3c4c0c0e33f2a371b2)) + + +### Bug Fixes + +* api contract for v1 proxy ([#3049](https://github.com/rudderlabs/rudder-transformer/issues/3049)) ([93947db](https://github.com/rudderlabs/rudder-transformer/commit/93947db35cdaf1ca7ed87ec5f73567754af312ab)) +* email mapping for clevertap ([#3173](https://github.com/rudderlabs/rudder-transformer/issues/3173)) ([04eab92](https://github.com/rudderlabs/rudder-transformer/commit/04eab92e1c383f9e8cdd5c845530a42a0af2932a)) +* fb pixel test case refactor ([#3075](https://github.com/rudderlabs/rudder-transformer/issues/3075)) ([cff7d1c](https://github.com/rudderlabs/rudder-transformer/commit/cff7d1c4578087a37614c0ef4529058481873479)) +* fixed 500 status for algolia dontBatch ([#3178](https://github.com/rudderlabs/rudder-transformer/issues/3178)) ([6330888](https://github.com/rudderlabs/rudder-transformer/commit/6330888ad5c67e3a800037b56501fc08da09e4d1)) +* label not present in prometheus metrics ([#3176](https://github.com/rudderlabs/rudder-transformer/issues/3176)) ([01d460c](https://github.com/rudderlabs/rudder-transformer/commit/01d460c3edaf39b35c4686516c9e9140be46aa5e)) +* send proper status to server in cm360 ([#3127](https://github.com/rudderlabs/rudder-transformer/issues/3127)) ([229ce47](https://github.com/rudderlabs/rudder-transformer/commit/229ce473af1ddd62d946bea1b018c882b142a5ef)) + +## [1.58.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.57.1...v1.58.0) (2024-03-04) + + +### Features + +* add support for interaction events in sfmc ([#3109](https://github.com/rudderlabs/rudder-transformer/issues/3109)) ([0486049](https://github.com/rudderlabs/rudder-transformer/commit/0486049ba2ad96b50d8f29e96b46b96a8a5c9f76)) +* add support of custom page/screen event name in mixpanel ([#3098](https://github.com/rudderlabs/rudder-transformer/issues/3098)) ([0eb2393](https://github.com/rudderlabs/rudder-transformer/commit/0eb2393939fba2452ef7f07a1d149d87f18290c3)) +* consent mode support for google adwords remarketing list ([#3143](https://github.com/rudderlabs/rudder-transformer/issues/3143)) ([7532c90](https://github.com/rudderlabs/rudder-transformer/commit/7532c90d7e1feac00f12961c56da18757010f44a)) +* **facebook:** update content_type mapping logic for fb pixel and fb conversions ([#3113](https://github.com/rudderlabs/rudder-transformer/issues/3113)) ([aea417c](https://github.com/rudderlabs/rudder-transformer/commit/aea417cd2691547399010c034cadbc5db6b0c6ee)) +* klaviyo profile mapping ([#3105](https://github.com/rudderlabs/rudder-transformer/issues/3105)) ([2761786](https://github.com/rudderlabs/rudder-transformer/commit/2761786ff3fc99ed6d4d3b7a6c2400226b1cfb12)) +* onboard new destination ninetailed ([#3106](https://github.com/rudderlabs/rudder-transformer/issues/3106)) ([0e2588e](https://github.com/rudderlabs/rudder-transformer/commit/0e2588ecd87f3b2c6877a099aa1cbf2d5325966c)) + + +### Bug Fixes + +* add error handling for tiktok ads ([#3144](https://github.com/rudderlabs/rudder-transformer/issues/3144)) ([e93e47f](https://github.com/rudderlabs/rudder-transformer/commit/e93e47f33e098104fb532916932fe38bbfeaa4a1)) +* **algolia:** added check for objectIds or filters to be non empty ([#3126](https://github.com/rudderlabs/rudder-transformer/issues/3126)) ([d619c97](https://github.com/rudderlabs/rudder-transformer/commit/d619c9769cd270cb2d16dad0865683ff4beb2d19)) +* clevertap remove stringification of array object properties ([#3048](https://github.com/rudderlabs/rudder-transformer/issues/3048)) ([69e43b6](https://github.com/rudderlabs/rudder-transformer/commit/69e43b6ffadeaec87b7440da34a341890ceba252)) +* convert to string from null in hs ([#3136](https://github.com/rudderlabs/rudder-transformer/issues/3136)) ([75e9f46](https://github.com/rudderlabs/rudder-transformer/commit/75e9f462b0ff9b9a8abab3c78dc7d147926e9e5e)) +* event fix and added utility ([#3142](https://github.com/rudderlabs/rudder-transformer/issues/3142)) ([9b705b7](https://github.com/rudderlabs/rudder-transformer/commit/9b705b71a9d3a595ea0fbf532602c3941b0a18db)) +* metadata structure correction ([#3119](https://github.com/rudderlabs/rudder-transformer/issues/3119)) ([8351b5c](https://github.com/rudderlabs/rudder-transformer/commit/8351b5cbbf81bbc14b2f884feaae4ad3ca59a39a)) +* one_signal: Encode external_id in endpoint ([#3140](https://github.com/rudderlabs/rudder-transformer/issues/3140)) ([8a20886](https://github.com/rudderlabs/rudder-transformer/commit/8a2088608d6da4b35bbb506db2fc3df1e4d41f3b)) +* rakuten: sync property mapping sourcekeys to rudderstack standard spec ([#3129](https://github.com/rudderlabs/rudder-transformer/issues/3129)) ([2ebff95](https://github.com/rudderlabs/rudder-transformer/commit/2ebff956ff2aa74b008a8de832a31d8774d2d47e)) +* reddit revenue mapping for floating point values ([#3118](https://github.com/rudderlabs/rudder-transformer/issues/3118)) ([41f4078](https://github.com/rudderlabs/rudder-transformer/commit/41f4078011ef54334bb9ecc11a7b2ccc8831a4aa)) +* version deprecation failure false positive ([#3104](https://github.com/rudderlabs/rudder-transformer/issues/3104)) ([657b780](https://github.com/rudderlabs/rudder-transformer/commit/657b7805eb01da25a007d978198d5debf03917fd)) + +### [1.57.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.57.0...v1.57.1) (2024-03-04) + + +### Bug Fixes + +* amplitude fix for user operations ([7f2364e](https://github.com/rudderlabs/rudder-transformer/commit/7f2364e41167611c41003559de65cee1fece5464)) +* amplitude fix for user operations ([#3153](https://github.com/rudderlabs/rudder-transformer/issues/3153)) ([31869fb](https://github.com/rudderlabs/rudder-transformer/commit/31869fb114bb141d545de01c56f57b97e5aa54a6)) + +## [1.57.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.56.1...v1.57.0) (2024-02-29) + + +### Features + +* add event mapping support for branch destination ([#3135](https://github.com/rudderlabs/rudder-transformer/issues/3135)) ([cc94bba](https://github.com/rudderlabs/rudder-transformer/commit/cc94bba682f667877a721f63627adc6ff6a7386a)) + + +### Bug Fixes + +* marketo bulk upload zero and null value allowed ([#3134](https://github.com/rudderlabs/rudder-transformer/issues/3134)) ([4dcbf8f](https://github.com/rudderlabs/rudder-transformer/commit/4dcbf8fb189a39bb40b950742425a0b9da2d8d7c)) + +### [1.56.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.56.0...v1.56.1) (2024-02-21) + + +### Bug Fixes + +* update proxy data type for response handler input ([#3030](https://github.com/rudderlabs/rudder-transformer/issues/3030)) ([457a18b](https://github.com/rudderlabs/rudder-transformer/commit/457a18b2aec03aa0dfafcadc611b5f7176e97beb)) + +## [1.56.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.55.0...v1.56.0) (2024-02-19) + + +### Features + +* **hs:** chunking data based on batch limit ([#2907](https://github.com/rudderlabs/rudder-transformer/issues/2907)) ([a60694c](https://github.com/rudderlabs/rudder-transformer/commit/a60694cef1da31d27a5cf90264548cad793f556f)) +* onboard bluecore integration ([#3061](https://github.com/rudderlabs/rudder-transformer/issues/3061)) ([aef5f8e](https://github.com/rudderlabs/rudder-transformer/commit/aef5f8e5f267262e0f9e10229f14f2bcc8ad29e2)) +* tiktok_offline_events added support for all Standard events ([#3094](https://github.com/rudderlabs/rudder-transformer/issues/3094)) ([b5cdccb](https://github.com/rudderlabs/rudder-transformer/commit/b5cdccb75fe68150816140174087fddad677db10)) + + +### Bug Fixes + +* add support of placing properties at root in af ([#3082](https://github.com/rudderlabs/rudder-transformer/issues/3082)) ([0f01524](https://github.com/rudderlabs/rudder-transformer/commit/0f01524b6f4f2f82efc21f88f8c97cb6fdaf91ea)) +* amplitude batch output metadata ([#3077](https://github.com/rudderlabs/rudder-transformer/issues/3077)) ([69c8348](https://github.com/rudderlabs/rudder-transformer/commit/69c83489c85486c9b2aed4a1292bd9f0aae9ca44)) +* amplitude: Error handling for missing event type ([#3079](https://github.com/rudderlabs/rudder-transformer/issues/3079)) ([f7ec0a1](https://github.com/rudderlabs/rudder-transformer/commit/f7ec0a1244a7b97e6b40de5ed9881c63300866dc)) +* custify user-regulation logic ([#3076](https://github.com/rudderlabs/rudder-transformer/issues/3076)) ([9683161](https://github.com/rudderlabs/rudder-transformer/commit/9683161612c7e3b9c2be95a2728f68ec7dcf69f4)) +* error handling for auth0 source ([#3038](https://github.com/rudderlabs/rudder-transformer/issues/3038)) ([2a21274](https://github.com/rudderlabs/rudder-transformer/commit/2a21274333350c615991f7b56b81b766502d5bf4)) +* **ga4:** failures not considered with 200 status in events tab ([#3089](https://github.com/rudderlabs/rudder-transformer/issues/3089)) ([6a364fb](https://github.com/rudderlabs/rudder-transformer/commit/6a364fba34c46b15c0fe4b06ecfa6f4b81b6f436)) +* gaoc batching order ([#3064](https://github.com/rudderlabs/rudder-transformer/issues/3064)) ([a98cabd](https://github.com/rudderlabs/rudder-transformer/commit/a98cabdfe7781ada12baf742df4a3a439fc5fecd)) +* resolve bugsnag issue caused due to undefined properties ([#3086](https://github.com/rudderlabs/rudder-transformer/issues/3086)) ([d522b35](https://github.com/rudderlabs/rudder-transformer/commit/d522b35c908a9f262ba3ba27dda0ea5d9ac5bc6b)) +* tiktok ads v2 error handling ([#3084](https://github.com/rudderlabs/rudder-transformer/issues/3084)) ([b6edff4](https://github.com/rudderlabs/rudder-transformer/commit/b6edff46fa0e0e210e82206fea46a064e3fbe00f)) + +## [1.55.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.54.4...v1.55.0) (2024-02-05) + + +### Features + +* add new stat for access token expired in fb custom audience ([#3043](https://github.com/rudderlabs/rudder-transformer/issues/3043)) ([1e6d540](https://github.com/rudderlabs/rudder-transformer/commit/1e6d540fafc61a84fbbaa63d4bc5b1edc17ec44e)) +* **intercom:** upgrade intercom version from 1.4 to 2.10 ([#2976](https://github.com/rudderlabs/rudder-transformer/issues/2976)) ([717639b](https://github.com/rudderlabs/rudder-transformer/commit/717639bcce605109b145eb4cc6836fe1589278fe)) +* onboard new destination rakuten ([#3046](https://github.com/rudderlabs/rudder-transformer/issues/3046)) ([c7c3110](https://github.com/rudderlabs/rudder-transformer/commit/c7c3110a4526e31bc296abb33f3246fa8eee049a)) +* trade desk real time conversions ([#3023](https://github.com/rudderlabs/rudder-transformer/issues/3023)) ([212d5f0](https://github.com/rudderlabs/rudder-transformer/commit/212d5f09d8addc618d4398029e62c9a18a9512cf)) + + +### Bug Fixes + +* adding map for marketo known values and javascript known values ([#3037](https://github.com/rudderlabs/rudder-transformer/issues/3037)) ([64ab555](https://github.com/rudderlabs/rudder-transformer/commit/64ab555d31b4c1c49863794444bd79b2b6a45927)) +* mixpanel timestamp in ms ([#3028](https://github.com/rudderlabs/rudder-transformer/issues/3028)) ([5ad55a2](https://github.com/rudderlabs/rudder-transformer/commit/5ad55a27c8b737fd96f65c68ba086769747c5360)) +* upgrade ua-parser-js from 1.0.35 to 1.0.37 ([9a4cdef](https://github.com/rudderlabs/rudder-transformer/commit/9a4cdef59ab1c2d9dc95eb8629a7009d8d633297)) + +### [1.54.4](https://github.com/rudderlabs/rudder-transformer/compare/v1.54.3...v1.54.4) (2024-01-31) + + +### Bug Fixes + +* purchsse events for reddit ([56d24ec](https://github.com/rudderlabs/rudder-transformer/commit/56d24ec74c0c21bcdcdf262b4feec6edd1dff51c)) + +### [1.54.3](https://github.com/rudderlabs/rudder-transformer/compare/v1.54.2...v1.54.3) (2024-01-30) + + +### Bug Fixes + +* hubspot increasing batch limit from 10 to 100 ([8075b7c](https://github.com/rudderlabs/rudder-transformer/commit/8075b7c6c6203657a8aad2525bd2f302dabd9960)) + ### [1.54.2](https://github.com/rudderlabs/rudder-transformer/compare/v1.54.1...v1.54.2) (2024-01-25) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1cef57af73e..bdd76d916cf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,7 +35,6 @@ See the project's [README](README.md) for further information about working in t - Include instructions on how to test your changes. 3. Your branch may be merged once all configured checks pass, including: - A review from appropriate maintainers -4. Along with the PR in transformer raise a PR against [config-generator][config-generator] with the configurations. ## Committing diff --git a/Dockerfile b/Dockerfile index 6bd03c9515f..8cd4005a7b1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1.4 -FROM node:18.19.0-alpine3.18 AS base +FROM node:18.19.1-alpine3.18 AS base ENV HUSKY 0 RUN apk update diff --git a/README.md b/README.md index 2b3908dcb55..4ff1cd4b34d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ +

+⚠️ Docker image for rudder-transformer has been moved to new org rudderstack/rudder-transformer +

+

+ [![codecov](https://codecov.io/gh/rudderlabs/rudder-transformer/branch/develop/graph/badge.svg?token=G24OON85SB)](https://codecov.io/gh/rudderlabs/rudder-transformer) # RudderStack Transformer diff --git a/github-release.config.js b/github-release.config.js new file mode 100644 index 00000000000..df269d8a02b --- /dev/null +++ b/github-release.config.js @@ -0,0 +1,5 @@ +module.exports = { + gitRawCommitsOpts: { + merges: null, + }, +}; diff --git a/jest.default.config.js b/jest.default.config.js index 59ca8449021..d1b5390b9e7 100644 --- a/jest.default.config.js +++ b/jest.default.config.js @@ -27,7 +27,7 @@ module.exports = { coverageDirectory: 'reports/coverage', // An array of regexp pattern strings used to skip coverage collection - coveragePathIgnorePatterns: ['/node_modules/', '__tests__', 'warehouse/v0' ,'test'], + coveragePathIgnorePatterns: ['/node_modules/', '__tests__', 'warehouse/v0', 'test'], // A list of reporter names that Jest uses when writing coverage reports coverageReporters: ['json', 'text', 'lcov', 'clover'], diff --git a/package-lock.json b/package-lock.json index 59df32aa830..5701e64a623 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.54.2", + "version": "1.60.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.54.2", + "version": "1.60.0", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "0.7.24", @@ -19,8 +19,9 @@ "@koa/router": "^12.0.0", "@ndhoule/extend": "^2.0.0", "@pyroscope/nodejs": "^0.2.6", - "@rudderstack/integrations-lib": "^0.1.8", - "@rudderstack/workflow-engine": "^0.6.9", + "@rudderstack/integrations-lib": "^0.2.4", + "@rudderstack/workflow-engine": "^0.7.2", + "@shopify/jest-koa-mocks": "^5.1.1", "ajv": "^8.12.0", "ajv-draft-04": "^1.0.0", "ajv-formats": "^2.1.1", @@ -62,13 +63,15 @@ "rudder-transformer-cdk": "^1.4.11", "set-value": "^4.1.0", "sha256": "^0.2.0", + "sqlstring": "^2.3.3", "stacktrace-parser": "^0.1.10", "statsd-client": "^0.4.7", "truncate-utf8-bytes": "^1.0.2", "ua-parser-js": "^1.0.37", "unset-value": "^2.0.1", "uuid": "^9.0.0", - "valid-url": "^1.0.9" + "valid-url": "^1.0.9", + "zod": "^3.22.4" }, "devDependencies": { "@commitlint/config-conventional": "^17.6.3", @@ -90,9 +93,10 @@ "eslint": "^8.40.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.0.0", - "eslint-config-prettier": "^8.8.0", + "eslint-config-prettier": "^8.10.0", "eslint-plugin-import": "^2.27.5", "eslint-plugin-json": "^3.1.0", + "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-sonarjs": "^0.19.0", "eslint-plugin-unicorn": "^46.0.1", "glob": "^10.3.3", @@ -105,7 +109,7 @@ "madge": "^6.1.0", "mocked-env": "^1.3.5", "node-notifier": "^10.0.1", - "prettier": "^2.8.8", + "prettier": "^3.2.4", "semver": "^7.5.3", "standard-version": "^9.5.0", "supertest": "^6.3.3", @@ -114,11 +118,45 @@ "typescript": "^5.0.4" } }, + "../rudder-integrations-lib": { + "name": "@rudderstack/integrations-lib", + "version": "0.1.10", + "extraneous": true, + "license": "MIT", + "dependencies": { + "@rudderstack/workflow-engine": "^0.5.7", + "axios": "^1.4.0", + "axios-mock-adapter": "^1.22.0", + "crypto": "^1.0.1", + "get-value": "^3.0.1", + "handlebars": "^4.7.8", + "lodash": "^4.17.21", + "moment": "^2.29.4", + "moment-timezone": "^0.5.43", + "set-value": "^4.1.0", + "sha256": "^0.2.0", + "tslib": "^2.4.0", + "winston": "^3.11.0" + }, + "devDependencies": { + "@types/get-value": "^3.0.3", + "@types/jest": "^29.5.4", + "@types/lodash": "^4.14.195", + "@types/node": "^20.3.3", + "@types/set-value": "^4.0.1", + "@types/sha256": "^0.2.0", + "jest": "^29.4.3", + "pre-commit": "^1.2.2", + "prettier": "^2.8.4", + "ts-jest": "^29.0.5", + "ts-node": "^10.9.1", + "typescript": "^5.1.6" + } + }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3199,7 +3237,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -3214,7 +3251,6 @@ "version": "4.10.0", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -3223,7 +3259,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -3246,7 +3281,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3261,14 +3295,12 @@ "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "node_modules/@eslint/js": { "version": "8.56.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -3298,7 +3330,6 @@ "version": "0.11.13", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", - "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", @@ -3312,7 +3343,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, "engines": { "node": ">=12.22" }, @@ -3324,8 +3354,7 @@ "node_modules/@humanwhocodes/object-schema": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", - "dev": true + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==" }, "node_modules/@hutson/parse-repository-url": { "version": "3.0.2", @@ -4312,7 +4341,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -4325,7 +4353,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "engines": { "node": ">= 8" } @@ -4334,7 +4361,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -4353,6 +4379,18 @@ "node": ">=14" } }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -4432,14 +4470,15 @@ } }, "node_modules/@rudderstack/integrations-lib": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@rudderstack/integrations-lib/-/integrations-lib-0.1.9.tgz", - "integrity": "sha512-ROi/LfI7PXqKDrjSig+1Rf2TQ8MgxJGJ7sAD1B0PmRKELQpxK6PLt8QF+vKXl8wYILQu2gwTkZ5o+uwmNKxGzg==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@rudderstack/integrations-lib/-/integrations-lib-0.2.4.tgz", + "integrity": "sha512-32Zose9aOPNWd4EyUNuS5YY+Vq4LYMuDcabJ+s3t1ZfHHMfISlDNF02b60MWgOrU8PARYC+siDs5wgA6xfZpzQ==", "dependencies": { - "@rudderstack/workflow-engine": "^0.5.7", "axios": "^1.4.0", "axios-mock-adapter": "^1.22.0", "crypto": "^1.0.1", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^17.1.0", "get-value": "^3.0.1", "handlebars": "^4.7.8", "lodash": "^4.17.21", @@ -4447,69 +4486,22 @@ "moment-timezone": "^0.5.43", "set-value": "^4.1.0", "sha256": "^0.2.0", - "tslib": "^2.4.0" - } - }, - "node_modules/@rudderstack/integrations-lib/node_modules/@aws-crypto/sha256-js": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-4.0.0.tgz", - "integrity": "sha512-MHGJyjE7TX9aaqXj7zk2ppnFUOhaDs5sP+HtNS0evOxn72c+5njUmyJmpGd7TfyoDznZlHMmdo/xGUdu2NIjNQ==", - "dependencies": { - "@aws-crypto/util": "^4.0.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@rudderstack/integrations-lib/node_modules/@aws-crypto/sha256-js/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@rudderstack/integrations-lib/node_modules/@aws-crypto/util": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-4.0.0.tgz", - "integrity": "sha512-2EnmPy2gsFZ6m8bwUQN4jq+IyXV3quHAcwPOS6ZA3k+geujiqI8aRokO2kFJe+idJ/P3v4qWI186rVMo0+zLDQ==", - "dependencies": { - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" - } - }, - "node_modules/@rudderstack/integrations-lib/node_modules/@aws-crypto/util/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@rudderstack/integrations-lib/node_modules/@rudderstack/json-template-engine": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@rudderstack/json-template-engine/-/json-template-engine-0.5.5.tgz", - "integrity": "sha512-p3HdTqgZiJjjZmjaHN2paa1e87ifGE5UjkA4zdvge4bBzJbKKMQNWqRg6I96SwoA+hsxNkW/f9R83SPLU9t7LA==" - }, - "node_modules/@rudderstack/integrations-lib/node_modules/@rudderstack/workflow-engine": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@rudderstack/workflow-engine/-/workflow-engine-0.5.8.tgz", - "integrity": "sha512-H1aCowYqTnOoqJtL9cGDhdhoGNl+KzqmVbSjFmE7n75onZaIMs87+HQyW08jYxS9l1Uo4TL8SAvzFICqFqkBbw==", - "dependencies": { - "@aws-crypto/sha256-js": "^4.0.0", - "@rudderstack/json-template-engine": "^0.5.5", - "js-yaml": "^4.1.0", - "jsonata": "^2.0.3", - "lodash": "^4.17.21", - "object-sizeof": "^2.6.3" + "tslib": "^2.4.0", + "winston": "^3.11.0" } }, "node_modules/@rudderstack/json-template-engine": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@rudderstack/json-template-engine/-/json-template-engine-0.8.2.tgz", - "integrity": "sha512-9oMBnqgNuwiXd7MUlNOAchCnJXQAy6w6XGmDqDM6iXdYDkvqYFiq7sbg5j4SdtpTTST293hahREr5PXfFVzVKg==" + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@rudderstack/json-template-engine/-/json-template-engine-0.8.5.tgz", + "integrity": "sha512-+iH40g+ZA2ANgwjOITdEdZJLZV+ljR28Akn/dRoDia591tMu7PptyvDaAvl+m1DijWXddpLQ8SX9xaEcIdmqlw==" }, "node_modules/@rudderstack/workflow-engine": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/@rudderstack/workflow-engine/-/workflow-engine-0.6.10.tgz", - "integrity": "sha512-3GRdnbB0BuSPWiKf4JsSpG7QuGffAFWkT5T0JLR7Jxps25gt+PgtjQiAlwrRhO5A0WeTJMIKTI7ctz6dGmJosg==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@rudderstack/workflow-engine/-/workflow-engine-0.7.2.tgz", + "integrity": "sha512-aXQvoXMekvXxxDG6Yc5P5l3PJIwqVA+EmJ2w4SnQ94BUHhbsybPjgGvyzD17MUTAdWEOtqS38SuzLflBs/5T4g==", "dependencies": { "@aws-crypto/sha256-js": "^5.0.0", - "@rudderstack/json-template-engine": "^0.8.1", + "@rudderstack/json-template-engine": "^0.8.4", "jsonata": "^2.0.3", "lodash": "^4.17.21", "object-sizeof": "^2.6.3", @@ -4539,6 +4531,18 @@ "tslib": "^2.6.2" } }, + "node_modules/@shopify/jest-koa-mocks": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@shopify/jest-koa-mocks/-/jest-koa-mocks-5.1.1.tgz", + "integrity": "sha512-H1dRznXIK03ph1l/VDBQ5ef+A9kkEn3ikNfk70zwm9auW15MfHfY9gekE99VecxUSekws7sbFte0i8ltWCS4/g==", + "dependencies": { + "koa": "^2.13.4", + "node-mocks-http": "^1.11.0" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + } + }, "node_modules/@sideway/address": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", @@ -5429,14 +5433,12 @@ "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, "node_modules/@types/keygrip": { "version": "1.0.6", @@ -5518,8 +5520,7 @@ "node_modules/@types/semver": { "version": "7.5.6", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", - "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", - "dev": true + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==" }, "node_modules/@types/send": { "version": "0.17.4", @@ -5570,7 +5571,6 @@ "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", - "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", "@typescript-eslint/scope-manager": "5.62.0", @@ -5604,7 +5604,6 @@ "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", - "dev": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -5631,7 +5630,6 @@ "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0" @@ -5648,7 +5646,6 @@ "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", - "dev": true, "dependencies": { "@typescript-eslint/typescript-estree": "5.62.0", "@typescript-eslint/utils": "5.62.0", @@ -5675,7 +5672,6 @@ "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -5688,7 +5684,6 @@ "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0", @@ -5715,7 +5710,6 @@ "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", @@ -5741,7 +5735,6 @@ "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, "dependencies": { "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" @@ -5757,8 +5750,7 @@ "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "node_modules/abbrev": { "version": "1.1.1", @@ -5781,7 +5773,6 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -5793,7 +5784,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -5993,7 +5983,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "is-array-buffer": "^3.0.1" @@ -6021,7 +6010,6 @@ "version": "3.1.7", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -6040,7 +6028,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, "engines": { "node": ">=8" } @@ -6049,7 +6036,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -6068,7 +6054,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -6086,7 +6071,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -6104,7 +6088,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", - "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.2", @@ -6168,7 +6151,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -6583,7 +6565,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -6790,7 +6771,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -7522,8 +7502,7 @@ "node_modules/confusing-browser-globals": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" }, "node_modules/console-control-strings": { "version": "1.1.0", @@ -8531,7 +8510,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -8704,8 +8682,7 @@ "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "node_modules/deepmerge": { "version": "4.3.1", @@ -8752,7 +8729,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -9125,7 +9101,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, "dependencies": { "path-type": "^4.0.0" }, @@ -9137,7 +9112,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, "dependencies": { "esutils": "^2.0.2" }, @@ -9367,7 +9341,6 @@ "version": "1.22.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", - "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "arraybuffer.prototype.slice": "^1.0.2", @@ -9420,7 +9393,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", - "dev": true, "dependencies": { "get-intrinsic": "^1.2.2", "has-tostringtag": "^1.0.0", @@ -9434,7 +9406,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, "dependencies": { "hasown": "^2.0.0" } @@ -9443,7 +9414,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -9527,7 +9497,6 @@ "version": "8.56.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", - "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -9582,7 +9551,6 @@ "version": "15.0.0", "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "dev": true, "dependencies": { "confusing-browser-globals": "^1.0.10", "object.assign": "^4.1.2", @@ -9601,7 +9569,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -9610,7 +9577,6 @@ "version": "17.1.0", "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.1.0.tgz", "integrity": "sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig==", - "dev": true, "dependencies": { "eslint-config-airbnb-base": "^15.0.0" }, @@ -9637,7 +9603,6 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -9648,7 +9613,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "dependencies": { "ms": "^2.1.1" } @@ -9657,7 +9621,6 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, "dependencies": { "debug": "^3.2.7" }, @@ -9674,7 +9637,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "dependencies": { "ms": "^2.1.1" } @@ -9683,7 +9645,6 @@ "version": "2.29.1", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, "dependencies": { "array-includes": "^3.1.7", "array.prototype.findlastindex": "^1.2.3", @@ -9714,7 +9675,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "dependencies": { "ms": "^2.1.1" } @@ -9723,7 +9683,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, "dependencies": { "esutils": "^2.0.2" }, @@ -9735,7 +9694,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -9753,6 +9711,36 @@ "node": ">=12.0" } }, + "node_modules/eslint-plugin-prettier": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", + "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.6" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, "node_modules/eslint-plugin-sonarjs": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.19.0.tgz", @@ -9904,7 +9892,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -9917,7 +9904,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -9929,7 +9915,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -9945,7 +9930,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -9960,7 +9944,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -9976,7 +9959,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -9987,14 +9969,12 @@ "node_modules/eslint/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "engines": { "node": ">=10" }, @@ -10006,7 +9986,6 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -10022,7 +10001,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "engines": { "node": ">=4.0" } @@ -10031,7 +10009,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -10039,14 +10016,12 @@ "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -10058,7 +10033,6 @@ "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -10088,7 +10062,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -10100,7 +10073,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "engines": { "node": ">=4.0" } @@ -10109,7 +10081,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -10121,7 +10092,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "engines": { "node": ">=4.0" } @@ -10130,7 +10100,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, "engines": { "node": ">=4.0" } @@ -10139,7 +10108,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -10246,11 +10214,16 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -10266,7 +10239,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -10277,14 +10249,12 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "node_modules/fast-printf": { "version": "1.6.9", @@ -10329,7 +10299,6 @@ "version": "1.16.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", - "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -10367,7 +10336,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, "dependencies": { "flat-cache": "^3.0.4" }, @@ -10430,7 +10398,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -10458,7 +10425,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -10505,7 +10471,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -10518,8 +10483,7 @@ "node_modules/flatted": { "version": "3.2.9", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" }, "node_modules/flatten": { "version": "1.0.3", @@ -10556,7 +10520,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, "dependencies": { "is-callable": "^1.1.3" } @@ -10708,7 +10671,6 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -10726,7 +10688,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -11049,7 +11010,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -11305,7 +11265,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -11395,7 +11354,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -11410,7 +11368,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, "dependencies": { "define-properties": "^1.1.3" }, @@ -11425,7 +11382,6 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -11522,8 +11478,7 @@ "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, "node_modules/growly": { "version": "1.3.0", @@ -11572,7 +11527,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -11910,7 +11864,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", - "dev": true, "engines": { "node": ">= 4" } @@ -11919,7 +11872,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -11935,7 +11887,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { "node": ">=4" } @@ -11963,7 +11914,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, "engines": { "node": ">=0.8.19" } @@ -12125,7 +12075,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", - "dev": true, "dependencies": { "get-intrinsic": "^1.2.2", "hasown": "^2.0.0", @@ -12191,7 +12140,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.0", @@ -12210,7 +12158,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, "dependencies": { "has-bigints": "^1.0.1" }, @@ -12222,7 +12169,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -12275,7 +12221,6 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -12298,7 +12243,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -12328,7 +12272,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -12384,7 +12327,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -12416,7 +12358,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -12428,7 +12369,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -12437,7 +12377,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -12470,7 +12409,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -12507,7 +12445,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -12547,7 +12484,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -12570,7 +12506,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -12585,7 +12520,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -12612,7 +12546,6 @@ "version": "1.1.12", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dev": true, "dependencies": { "which-typed-array": "^1.1.11" }, @@ -12663,7 +12596,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -12706,8 +12638,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isobject": { "version": "3.0.1", @@ -14516,8 +14447,7 @@ "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "node_modules/json-diff": { "version": "1.0.6", @@ -14562,8 +14492,7 @@ "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "node_modules/json-stringify-safe": { "version": "5.0.1", @@ -14657,7 +14586,6 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, "dependencies": { "json-buffer": "3.0.1" } @@ -14907,7 +14835,6 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -15257,7 +15184,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -15334,8 +15260,7 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "node_modules/lodash.mergewith": { "version": "4.6.2", @@ -16102,6 +16027,14 @@ "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==", "dev": true }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -16112,7 +16045,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "engines": { "node": ">= 8" } @@ -16129,7 +16061,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -16616,14 +16547,12 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "node_modules/natural-compare-lite": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" }, "node_modules/negotiator": { "version": "0.6.3", @@ -16684,6 +16613,47 @@ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, + "node_modules/node-mocks-http": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/node-mocks-http/-/node-mocks-http-1.14.1.tgz", + "integrity": "sha512-mfXuCGonz0A7uG1FEjnypjm34xegeN5+HI6xeGhYKecfgaZhjsmYoLE9LEFmT+53G1n8IuagPZmVnEL/xNsFaA==", + "dependencies": { + "@types/express": "^4.17.21", + "@types/node": "^20.10.6", + "accepts": "^1.3.7", + "content-disposition": "^0.5.3", + "depd": "^1.1.0", + "fresh": "^0.5.2", + "merge-descriptors": "^1.0.1", + "methods": "^1.1.2", + "mime": "^1.3.4", + "parseurl": "^1.3.3", + "range-parser": "^1.2.0", + "type-is": "^1.6.18" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/node-mocks-http/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-mocks-http/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/node-notifier": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-10.0.1.tgz", @@ -16846,7 +16816,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -16886,7 +16855,6 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -16904,7 +16872,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -16918,7 +16885,6 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -16935,7 +16901,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -16947,7 +16912,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -17018,7 +16982,6 @@ "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", @@ -17178,7 +17141,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -17240,7 +17202,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -17322,7 +17283,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -17366,7 +17326,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, "engines": { "node": ">=8" } @@ -17381,7 +17340,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -17876,7 +17834,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, "engines": { "node": ">= 0.8.0" } @@ -17891,20 +17848,32 @@ } }, "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz", + "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==", "dev": true, "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -18099,7 +18068,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -18136,6 +18104,14 @@ "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", "dev": true }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/raw-body": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", @@ -18366,7 +18342,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -18567,7 +18542,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -18665,7 +18639,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -18697,7 +18670,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1", @@ -18714,8 +18686,7 @@ "node_modules/safe-array-concat/node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, "node_modules/safe-buffer": { "version": "5.2.1", @@ -18749,7 +18720,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", @@ -18864,7 +18834,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", - "dev": true, "dependencies": { "define-data-property": "^1.0.1", "functions-have-names": "^1.2.3", @@ -18909,7 +18878,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -18921,7 +18889,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -18973,7 +18940,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, "engines": { "node": ">=8" } @@ -19122,6 +19088,14 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/stack-generator": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz", @@ -19659,7 +19633,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -19676,7 +19649,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -19690,7 +19662,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -19779,7 +19750,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, "engines": { "node": ">=8" }, @@ -19893,6 +19863,22 @@ "node": ">=10" } }, + "node_modules/synckit": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", + "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -19990,8 +19976,7 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "node_modules/through": { "version": "2.3.8", @@ -20056,7 +20041,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -20214,7 +20198,6 @@ "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -20226,7 +20209,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, "dependencies": { "minimist": "^1.2.0" }, @@ -20238,7 +20220,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, "engines": { "node": ">=4" } @@ -20260,7 +20241,6 @@ "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, "dependencies": { "tslib": "^1.8.1" }, @@ -20274,14 +20254,12 @@ "node_modules/tsutils/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -20302,7 +20280,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, "engines": { "node": ">=10" }, @@ -20326,7 +20303,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1", @@ -20340,7 +20316,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -20358,7 +20333,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -20377,7 +20351,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -20397,7 +20370,6 @@ "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -20444,7 +20416,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -20712,7 +20683,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -20727,7 +20697,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -20749,7 +20718,6 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", - "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.4", @@ -21072,6 +21040,14 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 93c97fedda0..5c1d9c1848a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.54.2", + "version": "1.60.0", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { @@ -19,9 +19,9 @@ "setup": "npm ci", "setup:swagger": "swagger-cli bundle swagger/api.yaml --outfile dist/swagger.json --type json", "format": "prettier --write .", - "lint": "eslint . || exit 0", "lint:fix": "eslint . --fix", "lint:fix:json": "eslint --ext .json --fix .", + "lint": "npm run format && npm run lint:fix", "check:merge": "npm run verify || exit 1; codecov", "start": "cd dist;node ./src/index.js;cd ..", "build:start": "npm run build && npm run start", @@ -49,7 +49,7 @@ "commit-msg": "commitlint --edit", "prepare": "node ./scripts/skipPrepareScript.js || husky install", "release": "npx standard-version", - "release:github": "DEBUG=conventional-github-releaser npx conventional-github-releaser -p angular -v", + "release:github": "DEBUG=conventional-github-releaser npx conventional-github-releaser -p angular --config github-release.config.js", "clean:node": "modclean", "check:lint": "eslint . -f json -o reports/eslint.json || exit 0" }, @@ -64,8 +64,9 @@ "@koa/router": "^12.0.0", "@ndhoule/extend": "^2.0.0", "@pyroscope/nodejs": "^0.2.6", - "@rudderstack/integrations-lib": "^0.1.8", - "@rudderstack/workflow-engine": "^0.6.9", + "@rudderstack/integrations-lib": "^0.2.4", + "@rudderstack/workflow-engine": "^0.7.2", + "@shopify/jest-koa-mocks": "^5.1.1", "ajv": "^8.12.0", "ajv-draft-04": "^1.0.0", "ajv-formats": "^2.1.1", @@ -107,13 +108,15 @@ "rudder-transformer-cdk": "^1.4.11", "set-value": "^4.1.0", "sha256": "^0.2.0", + "sqlstring": "^2.3.3", "stacktrace-parser": "^0.1.10", "statsd-client": "^0.4.7", "truncate-utf8-bytes": "^1.0.2", "ua-parser-js": "^1.0.37", "unset-value": "^2.0.1", "uuid": "^9.0.0", - "valid-url": "^1.0.9" + "valid-url": "^1.0.9", + "zod": "^3.22.4" }, "devDependencies": { "@commitlint/config-conventional": "^17.6.3", @@ -135,9 +138,10 @@ "eslint": "^8.40.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.0.0", - "eslint-config-prettier": "^8.8.0", + "eslint-config-prettier": "^8.10.0", "eslint-plugin-import": "^2.27.5", "eslint-plugin-json": "^3.1.0", + "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-sonarjs": "^0.19.0", "eslint-plugin-unicorn": "^46.0.1", "glob": "^10.3.3", @@ -150,7 +154,7 @@ "madge": "^6.1.0", "mocked-env": "^1.3.5", "node-notifier": "^10.0.1", - "prettier": "^2.8.8", + "prettier": "^3.2.4", "semver": "^7.5.3", "standard-version": "^9.5.0", "supertest": "^6.3.3", diff --git a/src/adapters/network.js b/src/adapters/network.js index b0bd14374eb..0720638d12d 100644 --- a/src/adapters/network.js +++ b/src/adapters/network.js @@ -49,11 +49,15 @@ const fireHTTPStats = (clientResponse, startTime, statTags) => { const destType = statTags.destType ? statTags.destType : ''; const feature = statTags.feature ? statTags.feature : ''; const endpointPath = statTags.endpointPath ? statTags.endpointPath : ''; + const requestMethod = statTags.requestMethod ? statTags.requestMethod : ''; + const module = statTags.module ? statTags.module : ''; const statusCode = clientResponse.success ? clientResponse.response.status : ''; stats.timing('outgoing_request_latency', startTime, { feature, destType, endpointPath, + requestMethod, + module, }); stats.counter('outgoing_request_count', 1, { feature, @@ -61,6 +65,8 @@ const fireHTTPStats = (clientResponse, startTime, statTags) => { endpointPath, success: clientResponse.success, statusCode, + requestMethod, + module, }); }; diff --git a/src/adapters/networkHandlerFactory.js b/src/adapters/networkHandlerFactory.js index e8c3748d15a..de80809a041 100644 --- a/src/adapters/networkHandlerFactory.js +++ b/src/adapters/networkHandlerFactory.js @@ -27,8 +27,9 @@ SUPPORTED_VERSIONS.forEach((version) => { // }, // generic: GenericNetworkHandler, // } - handlers[version][dest] = - require(`../${version}/destinations/${dest}/networkHandler`).networkHandler; + handlers[version][dest] = require( + `../${version}/destinations/${dest}/networkHandler`, + ).networkHandler; } catch { // Do nothing as exception indicates // network handler is not defined for that destination diff --git a/src/adapters/networkhandler/genericNetworkHandler.js b/src/adapters/networkhandler/genericNetworkHandler.js index bcbcb212592..d9358085f44 100644 --- a/src/adapters/networkhandler/genericNetworkHandler.js +++ b/src/adapters/networkhandler/genericNetworkHandler.js @@ -17,13 +17,14 @@ const tags = require('../../v0/util/tags'); * will act as fall-fack for such scenarios. * */ -const responseHandler = (destinationResponse, dest) => { +const responseHandler = (responseParams) => { + const { destinationResponse, destType } = responseParams; const { status } = destinationResponse; - const message = `[Generic Response Handler] Request for destination: ${dest} Processed Successfully`; + const message = `[Generic Response Handler] Request for destination: ${destType} Processed Successfully`; // if the response from destination is not a success case build an explicit error if (!isHttpStatusSuccess(status)) { throw new NetworkError( - `[Generic Response Handler] Request failed for destination ${dest} with status: ${status}`, + `[Generic Response Handler] Request failed for destination ${destType} with status: ${status}`, status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), diff --git a/src/cdk/v2/destinations/algolia/procWorkflow.yaml b/src/cdk/v2/destinations/algolia/procWorkflow.yaml index b9ce7ef7fd4..f9ac8e3ae6e 100644 --- a/src/cdk/v2/destinations/algolia/procWorkflow.yaml +++ b/src/cdk/v2/destinations/algolia/procWorkflow.yaml @@ -61,7 +61,7 @@ steps: const filters = $.context.payload.filters; const objectIDs = $.context.payload.objectIDs; $.assert(!(filters && objectIDs), "event can't have both objectIds and filters at the same time."); - $.assert(filters || objectIDs, "Either filters or objectIds is required."); + $.assert(filters.length || objectIDs.length, "Either filters or objectIds is required and must be non empty."); - name: validatePayloadForClickEvent condition: $.context.payload.eventType === "click" diff --git a/src/cdk/v2/destinations/algolia/rtWorkflow.yaml b/src/cdk/v2/destinations/algolia/rtWorkflow.yaml index 758a71bf5ba..f5442f32094 100644 --- a/src/cdk/v2/destinations/algolia/rtWorkflow.yaml +++ b/src/cdk/v2/destinations/algolia/rtWorkflow.yaml @@ -2,7 +2,6 @@ bindings: - path: ../../../../v0/destinations/algolia/config - name: handleRtTfSingleEventError path: ../../../../v0/util/index - steps: - name: validateInput template: | @@ -28,10 +27,14 @@ steps: $.outputs.transform#idx.error.( $.handleRtTfSingleEventError(^[idx], .originalError ?? ., {}) )[] + - name: batchSuccessfulEvents description: Batches the successfulEvents template: | - let batches = $.chunk($.outputs.successfulEvents, $.MAX_BATCH_SIZE); + const dontBatchTrueEvents = $.outputs.successfulEvents{.metadata.dontBatch}[]; + const dontBatchFalseEvents = $.outputs.successfulEvents{!.metadata.dontBatch}[]; + + let batches = [...$.chunk(dontBatchFalseEvents, $.MAX_BATCH_SIZE), ...$.chunk(dontBatchTrueEvents, 1)]; batches@batch.({ "batchedRequest": { "body": { @@ -56,6 +59,7 @@ steps: "statusCode": 200, "destination": batch[0].destination })[]; + - name: finalPayload template: | [...$.outputs.failedEvents, ...$.outputs.batchSuccessfulEvents] diff --git a/src/cdk/v2/destinations/bingads_audience/procWorkflow.yaml b/src/cdk/v2/destinations/bingads_audience/procWorkflow.yaml index 744c05a9a6d..3292d66c690 100644 --- a/src/cdk/v2/destinations/bingads_audience/procWorkflow.yaml +++ b/src/cdk/v2/destinations/bingads_audience/procWorkflow.yaml @@ -50,4 +50,4 @@ steps: const response = $.defaultRequestConfig(); response.body.JSON = payload; response - ) \ No newline at end of file + ) diff --git a/src/cdk/v2/destinations/bluecore/config.js b/src/cdk/v2/destinations/bluecore/config.js new file mode 100644 index 00000000000..9b9cde9c663 --- /dev/null +++ b/src/cdk/v2/destinations/bluecore/config.js @@ -0,0 +1,56 @@ +const { getMappingConfig } = require('../../../../v0/util'); + +const BASE_URL = 'https://api.bluecore.com/api/track/mobile/v1'; + +const CONFIG_CATEGORIES = { + IDENTIFY: { + name: 'bluecoreIdentifyConfig', + type: 'identify', + }, + TRACK: { + name: 'bluecoreTrackConfig', + type: 'track', + }, + COMMON: { + name: 'bluecoreCommonConfig', + type: 'common', + }, +}; + +const EVENT_NAME_MAPPING = [ + { + src: ['product viewed'], + dest: 'viewed_product', + }, + { + src: ['products searched'], + dest: 'search', + }, + { + src: ['product added'], + dest: 'add_to_cart', + }, + { + src: ['product removed'], + dest: 'remove_from_cart', + }, + { + src: ['product added to wishlist'], + dest: 'wishlist', + }, + { + src: ['order completed'], + dest: 'purchase', + }, +]; + +const BLUECORE_EXCLUSION_FIELDS = ['query', 'order_id', 'total']; + +const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); +module.exports = { + CONFIG_CATEGORIES, + MAPPING_CONFIG, + EVENT_NAME_MAPPING, + BASE_URL, + BLUECORE_EXCLUSION_FIELDS, +}; diff --git a/src/cdk/v2/destinations/bluecore/data/bluecoreCommonConfig.json b/src/cdk/v2/destinations/bluecore/data/bluecoreCommonConfig.json new file mode 100644 index 00000000000..be74c7c4b3c --- /dev/null +++ b/src/cdk/v2/destinations/bluecore/data/bluecoreCommonConfig.json @@ -0,0 +1,52 @@ +[ + { + "destKey": "properties.customer.name", + "sourceKeys": "name", + "required": false, + "sourceFromGenericMap": true + }, + { + "destKey": "properties.customer.first_name", + "sourceKeys": "firstName", + "required": false, + "sourceFromGenericMap": true + }, + { + "destKey": "properties.customer.last_name", + "sourceKeys": "lastName", + "required": false, + "sourceFromGenericMap": true + }, + { + "destKey": "properties.customer.age", + "sourceKeys": ["context.traits.age", "traits.age"], + "required": false + }, + { + "destKey": "properties.customer.sex", + "sourceKeys": ["traits.gender", "context.traits.gender", "traits.sex", "context.traits.sex"], + "required": false + }, + { + "destKey": "properties.customer.address", + "sourceKeys": "address", + "required": false, + "sourceFromGenericMap": true + }, + { + "destKey": "properties.customer.email", + "sourceKeys": "email", + "required": false, + "sourceFromGenericMap": true + }, + { + "destKey": "properties.client", + "sourceKeys": "context.app.version", + "required": false + }, + { + "destKey": "properties.device", + "sourceKeys": "context.device.model", + "required": false + } +] diff --git a/src/cdk/v2/destinations/bluecore/data/bluecoreIdentifyConfig.json b/src/cdk/v2/destinations/bluecore/data/bluecoreIdentifyConfig.json new file mode 100644 index 00000000000..5c3686f0ab6 --- /dev/null +++ b/src/cdk/v2/destinations/bluecore/data/bluecoreIdentifyConfig.json @@ -0,0 +1,7 @@ +[ + { + "destKey": "event", + "sourceKeys": ["traits.action", "context.traits.action"], + "required": false + } +] diff --git a/src/cdk/v2/destinations/bluecore/data/bluecoreTrackConfig.json b/src/cdk/v2/destinations/bluecore/data/bluecoreTrackConfig.json new file mode 100644 index 00000000000..8f6d59ec542 --- /dev/null +++ b/src/cdk/v2/destinations/bluecore/data/bluecoreTrackConfig.json @@ -0,0 +1,22 @@ +[ + { + "destKey": "properties.search_term", + "sourceKeys": "properties.query", + "required": false + }, + { + "destKey": "properties.order_id", + "sourceKeys": "properties.order_id", + "required": false + }, + { + "destKey": "properties.total", + "sourceKeys": "properties.total", + "required": false + }, + { + "destKey": "properties.products", + "sourceKeys": ["properties.products"], + "required": false + } +] diff --git a/src/cdk/v2/destinations/bluecore/procWorkflow.yaml b/src/cdk/v2/destinations/bluecore/procWorkflow.yaml new file mode 100644 index 00000000000..480bced699b --- /dev/null +++ b/src/cdk/v2/destinations/bluecore/procWorkflow.yaml @@ -0,0 +1,69 @@ +bindings: + - name: EventType + path: ../../../../constants + - path: ../../bindings/jsontemplate + - name: defaultRequestConfig + path: ../../../../v0/util + - name: removeUndefinedNullValuesAndEmptyObjectArray + path: ../../../../v0/util + - name: removeUndefinedAndNullValues + path: ../../../../v0/util + - path: ./utils + - path: lodash + name: cloneDeep + +steps: + - name: messageType + template: | + .message.type.toLowerCase(); + - name: validateInput + template: | + let messageType = $.outputs.messageType; + $.assert(messageType, "message Type is not present. Aborting"); + $.assert(messageType in {{$.EventType.([.TRACK, .IDENTIFY])}}, "message type " + messageType + " is not supported"); + $.assertConfig(.destination.Config.bluecoreNamespace, "[BLUECORE] account namespace required for Authentication."); + - name: prepareIdentifyPayload + condition: $.outputs.messageType === {{$.EventType.IDENTIFY}} + template: | + const payload = $.constructProperties(.message); + payload.token = .destination.Config.bluecoreNamespace; + $.verifyPayload(payload, .message); + payload.event = payload.event ?? 'customer_patch'; + payload.properties.distinct_id = $.populateAccurateDistinctId(payload, .message); + $.context.payloads = [$.removeUndefinedAndNullValues(payload)]; + - name: handleTrackEvent + condition: $.outputs.messageType === {{$.EventType.TRACK}} + steps: + - name: validateInput + description: Additional validation for Track events + template: | + $.assert(.message.event, "event_name could not be mapped. Aborting.") + - name: deduceEventNames + template: | + $.context.deducedEventNameArray = $.deduceTrackEventName(.message.event,.destination.Config) + - name: preparePayload + template: | + const payload = $.constructProperties(.message); + $.context.payloads = $.context.deducedEventNameArray@eventName.( + const newPayload = $.cloneDeep(payload); + newPayload.properties.distinct_id = $.populateAccurateDistinctId(newPayload, ^.message); + const temporaryProductArray = newPayload.properties.products ?? $.createProductForStandardEcommEvent(^.message, eventName); + newPayload.properties.products = $.normalizeProductArray(temporaryProductArray); + newPayload.event = eventName; + newPayload.token = ^.destination.Config.bluecoreNamespace; + $.verifyPayload(newPayload, ^.message); + $.removeUndefinedNullValuesAndEmptyObjectArray(newPayload) + )[]; + + - name: buildResponse + template: | + $.context.payloads.( + const response = $.defaultRequestConfig(); + response.body.JSON = .; + response.method = "POST"; + response.endpoint = "https://api.bluecore.com/api/track/mobile/v1"; + response.headers = { + "Content-Type": "application/json" + }; + response + ) diff --git a/src/cdk/v2/destinations/bluecore/utils.js b/src/cdk/v2/destinations/bluecore/utils.js new file mode 100644 index 00000000000..22ec254fe2e --- /dev/null +++ b/src/cdk/v2/destinations/bluecore/utils.js @@ -0,0 +1,250 @@ +const lodash = require('lodash'); + +const { + InstrumentationError, + isDefinedAndNotNullAndNotEmpty, + getHashFromArrayWithDuplicate, + isDefinedAndNotNull, + isDefinedNotNullNotEmpty, +} = require('@rudderstack/integrations-lib'); +const { + getFieldValueFromMessage, + validateEventName, + constructPayload, + getDestinationExternalID, +} = require('../../../../v0/util'); +const { CommonUtils } = require('../../../../util/common'); +const { EVENT_NAME_MAPPING } = require('./config'); +const { EventType } = require('../../../../constants'); +const { MAPPING_CONFIG, CONFIG_CATEGORIES } = require('./config'); + +/** + * Verifies the correctness of payload for different events. + * + * @param {Object} payload - The payload object containing event information. + * @param {Object} message - The message object containing additional information. + * @throws {InstrumentationError} - Throws an error if required properties are missing. + * @returns {void} + */ +const verifyPayload = (payload, message) => { + if ( + message.type === EventType.IDENTIFY && + isDefinedNotNullNotEmpty(message.traits?.action) && + message.traits?.action !== 'identify' + ) { + throw new InstrumentationError( + "[Bluecore] traits.action must be 'identify' for identify action", + ); + } + switch (payload.event) { + case 'search': + if (!payload?.properties?.search_term) { + throw new InstrumentationError( + '[Bluecore] property:: search_query is required for search event', + ); + } + break; + case 'purchase': + if (!payload?.properties?.order_id) { + throw new InstrumentationError( + '[Bluecore] property:: order_id is required for purchase event', + ); + } + if (!payload?.properties?.total) { + throw new InstrumentationError( + '[Bluecore] property:: total is required for purchase event', + ); + } + if ( + !isDefinedAndNotNull(payload?.properties?.customer) || + Object.keys(payload.properties.customer).length === 0 + ) { + throw new InstrumentationError( + `[Bluecore] property:: No relevant trait to populate customer information, which is required for ${payload.event} event`, + ); + } + break; + case 'identify': + case 'optin': + case 'unsubscribe': + if (!isDefinedAndNotNullAndNotEmpty(getFieldValueFromMessage(message, 'email'))) { + throw new InstrumentationError( + `[Bluecore] property:: email is required for ${payload.event} action`, + ); + } + if ( + !isDefinedAndNotNull(payload?.properties?.customer) || + Object.keys(payload.properties.customer).length === 0 + ) { + throw new InstrumentationError( + `[Bluecore] property:: No relevant trait to populate customer information, which is required for ${payload.event} action`, + ); + } + break; + default: + break; + } +}; + +/** + * Deduces the track event name based on the provided track event name and configuration. + * + * @param {string} trackEventName - The track event name to deduce. + * @param {object} Config - The configuration object. + * @returns {string|array} - The deduced track event name. + */ +const deduceTrackEventName = (trackEventName, destConfig) => { + let eventName; + const { eventsMapping } = destConfig; + validateEventName(trackEventName); + /* + Step 1: Will look for the event name in the eventsMapping array if mapped to a standard bluecore event. + and return the corresponding event name if found. + */ + if (eventsMapping.length > 0) { + const keyMap = getHashFromArrayWithDuplicate(eventsMapping, 'from', 'to', false); + eventName = keyMap[trackEventName]; + } + if (isDefinedAndNotNullAndNotEmpty(eventName)) { + const finalEvent = typeof eventName === 'string' ? [eventName] : [...eventName]; + return finalEvent; + } + + /* + Step 2: To find if the particular event is amongst the list of standard + Rudderstack ecommerce events, used specifically for Bluecore API + mappings. + */ + + const eventMapInfo = EVENT_NAME_MAPPING.find((eventMap) => + eventMap.src.includes(trackEventName.toLowerCase()), + ); + if (isDefinedAndNotNull(eventMapInfo)) { + return [eventMapInfo.dest]; + } + + // Step 3: if nothing matches this is to be considered as a custom event + return [trackEventName]; +}; + +/** + * Determines if the given event name is a standard Bluecore event. + * + * @param {string} eventName - The name of the event to check. + * @returns {boolean} - True if the event is a standard Bluecore event, false otherwise. + */ +const isStandardBluecoreEvent = (eventName) => { + // Return false immediately if eventName is an empty string or falsy + if (!eventName) { + return false; + } + // Proceed with the original check if eventName is not empty + return !!EVENT_NAME_MAPPING.some((item) => item.dest.includes(eventName)); +}; + +/** + * Adds an array of products to a message. + * + * @param {object} message - The message object to add the products to. + * @param {array|object} products - The array or object of products to add. + * @param {string} eventName - The name of the event. + * @throws {InstrumentationError} - If the products array is not defined or null. + * @returns {array} - The updated product array. + */ +const normalizeProductArray = (products) => { + let finalProductArray = null; + if (isDefinedAndNotNull(products)) { + const productArray = CommonUtils.toArray(products); + const mappedProductArray = productArray.map( + ({ product_id, sku, id, query, order_id, total, ...rest }) => ({ + id: product_id || sku || id, + ...rest, + }), + ); + finalProductArray = mappedProductArray; + } + // if any custom event is not sent with product array, then it should be null + return finalProductArray; +}; + +/** + * Constructs properties based on the given message. + * + * @param {object} message - The message object. + * @returns {object} - The constructed properties object. + */ +const constructProperties = (message) => { + const commonCategory = CONFIG_CATEGORIES.COMMON; + const commonPayload = constructPayload(message, MAPPING_CONFIG[commonCategory.name]); + const category = CONFIG_CATEGORIES[message.type.toUpperCase()]; + const typeSpecificPayload = constructPayload(message, MAPPING_CONFIG[category.name]); + const finalPayload = lodash.merge(commonPayload, typeSpecificPayload); + return finalPayload; +}; + +/** + * Creates a product for a standard e-commerce event. + * + * @param {Object} properties - The properties of the product. + * @param {string} eventName - The name of the event. + * @returns {Array|null} - An array containing the properties if the event is a standard Bluecore event and not 'search', otherwise null. + */ +const createProductForStandardEcommEvent = (message, eventName) => { + const { event, properties } = message; + if (event.toLowerCase() === 'order completed' && eventName === 'purchase') { + throw new InstrumentationError('[Bluecore]:: products array is required for purchase event'); + } + if (eventName !== 'search' && isStandardBluecoreEvent(eventName)) { + return [properties]; + } + return null; +}; +/** + * Function: populateAccurateDistinctId + * + * Description: + * This function is used to populate the accurate distinct ID based on the given payload and message. + * + * Parameters: + * - payload (object): The payload object containing the event and other data. + * - message (object): The message object containing the user data. + * + * Returns: + * - distinctId (string): The accurate distinct ID based on the given payload and message. + * + * Throws: + * - InstrumentationError: If the distinct ID could not be set. + * + */ +const populateAccurateDistinctId = (payload, message) => { + const bluecoreExternalId = getDestinationExternalID(message, 'bluecoreExternalId'); + if (isDefinedAndNotNullAndNotEmpty(bluecoreExternalId)) { + return bluecoreExternalId; + } + let distinctId; + if (payload.event === 'identify') { + distinctId = getFieldValueFromMessage(message, 'userId'); + } else { + // email is always a more preferred distinct_id + distinctId = + getFieldValueFromMessage(message, 'email') || getFieldValueFromMessage(message, 'userId'); + } + + if (!isDefinedAndNotNullAndNotEmpty(distinctId)) { + // dev safe. AnonymouId should be always present + throw new InstrumentationError( + '[Bluecore] property:: distinct_id could not be set. Please provide either email or userId or anonymousId or externalId as distinct_id.', + ); + } + return distinctId; +}; + +module.exports = { + verifyPayload, + deduceTrackEventName, + normalizeProductArray, + isStandardBluecoreEvent, + constructProperties, + createProductForStandardEcommEvent, + populateAccurateDistinctId, +}; diff --git a/src/cdk/v2/destinations/bluecore/utils.test.js b/src/cdk/v2/destinations/bluecore/utils.test.js new file mode 100644 index 00000000000..829073bbccb --- /dev/null +++ b/src/cdk/v2/destinations/bluecore/utils.test.js @@ -0,0 +1,403 @@ +const { + normalizeProductArray, + verifyPayload, + isStandardBluecoreEvent, + deduceTrackEventName, + populateAccurateDistinctId, + createProductForStandardEcommEvent, +} = require('./utils'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); + +describe('normalizeProductArray', () => { + // Adds an array of products to a message when products array is defined and not null. + it('should add an array of products to a message when products array is defined and not null', () => { + const products = [ + { product_id: 1, name: 'Product 1' }, + { product_id: 2, name: 'Product 2' }, + ]; + const eventName = 'purchase'; + + const result = normalizeProductArray(products, eventName); + + expect(result).toEqual([ + { id: 1, name: 'Product 1' }, + { id: 2, name: 'Product 2' }, + ]); + }); + + // Adds a single product object to a message when a single product object is passed. + it('should add a single product object to a message when a single product object is passed', () => { + const product = { product_id: 1, name: 'Product 1' }; + const eventName = 'add_to_cart'; + + const result = normalizeProductArray(product, eventName); + expect(result).toEqual([{ id: 1, name: 'Product 1' }]); + }); + + it('should not throw an InstrumentationError for a custom event when products array is null', () => { + const message = {}; + const products = null; + const eventName = 'custom'; + + expect(() => { + normalizeProductArray(message, products, eventName); + }).toBeNull; + }); +}); + +describe('verifyPayload', () => { + // Verify payload for search event with search_term property. + it('should verify payload for search event with search_term property', () => { + const payload = { + event: 'search', + properties: { + search_term: 'example', + }, + }; + expect(() => verifyPayload(payload, {})).not.toThrow(); + }); + + // Verify payload for purchase event with order_id and total properties. + it('should verify payload for purchase event with order_id and total and customer properties', () => { + const payload = { + event: 'purchase', + properties: { + order_id: '123', + total: 100, + }, + }; + expect(() => verifyPayload(payload, {})).toThrow(InstrumentationError); + }); + + // Verify payload for identify event with email property. + it('should verify payload for identify event with email property', () => { + const payload = { + event: 'identify', + properties: { + customer: { + first_name: 'John', + }, + }, + }; + const message = { + traits: { + email: 'test@example.com', + }, + }; + expect(() => verifyPayload(payload, message)).not.toThrow(); + }); + + // Verify payload for search event without search_term property, should throw an InstrumentationError. + it('should throw an InstrumentationError when verifying payload for search event without search_term property', () => { + const payload = { + event: 'search', + properties: {}, + }; + expect(() => verifyPayload(payload, {})).toThrow(InstrumentationError); + }); + + // Verify payload for purchase event without order_id property, should throw an InstrumentationError. + it('should throw an InstrumentationError when verifying payload for purchase event without order_id property', () => { + const payload = { + event: 'purchase', + properties: { + total: 100, + }, + }; + expect(() => verifyPayload(payload, {})).toThrow(InstrumentationError); + }); + + // Verify payload for purchase event without total property, should throw an InstrumentationError. + it('should throw an InstrumentationError when verifying payload for purchase event without total property', () => { + const payload = { + event: 'purchase', + properties: { + order_id: '123', + }, + }; + expect(() => verifyPayload(payload, {})).toThrow(InstrumentationError); + }); + + // Verify payload for purchase event without total property, should throw an InstrumentationError. + it('should throw an InstrumentationError when verifying payload for identify event with action field other than identify', () => { + const payload = { + event: 'random', + properties: { + email: 'abc@gmail.com', + }, + }; + expect(() => + verifyPayload(payload, { type: 'identify', traits: { action: 'random' } }), + ).toThrow(InstrumentationError); + }); + + it('should throw an InstrumentationError when verifying payload for optin event without email property', () => { + const payload = { + event: 'optin', + properties: { + order_id: '123', + }, + }; + expect(() => verifyPayload(payload, {})).toThrow(InstrumentationError); + }); + + it('should throw an InstrumentationError when verifying payload for unsubscribe event without email property', () => { + const payload = { + event: 'unsubscribe', + properties: { + order_id: '123', + }, + }; + expect(() => verifyPayload(payload, {})).toThrow(InstrumentationError); + }); +}); + +describe('isStandardBluecoreEvent', () => { + // Returns true if the given event name is in the list of standard Bluecore events. + it('should return true when the given event name is in the list of standard Bluecore events', () => { + const eventName = 'search'; + const result = isStandardBluecoreEvent(eventName); + expect(result).toBe(true); + }); + + // Returns false if the given event name is not in the list of standard Bluecore events. + it('should return false when the given event name is not in the list of standard Bluecore events', () => { + const eventName = 'someEvent'; + const result = isStandardBluecoreEvent(eventName); + expect(result).toBe(false); + }); + + // Returns false if the given event name is null. + it('should return false when the given event name is null', () => { + const eventName = null; + const result = isStandardBluecoreEvent(eventName); + expect(result).toBe(false); + }); + + // Returns false if the given event name is undefined. + it('should return false when the given event name is undefined', () => { + const eventName = undefined; + const result = isStandardBluecoreEvent(eventName); + expect(result).toBe(false); + }); + + // Returns false if the given event name is not a string. + it('should return false when the given event name is not a string', () => { + const eventName = 123; + const result = isStandardBluecoreEvent(eventName); + expect(result).toBe(false); + }); + + // Returns false if the given event name is an empty string. + it('should return false when the given event name is an empty string', () => { + const eventName = ''; + const result = isStandardBluecoreEvent(eventName); + expect(result).toBe(false); + }); +}); + +describe('deduceTrackEventName', () => { + // The function returns the trackEventName if no eventsMapping is provided and the trackEventName is not a standard Rudderstack ecommerce event. + it('should return the trackEventName when no eventsMapping is provided and the trackEventName is not a standard Rudderstack ecommerce event', () => { + const trackEventName = 'customEvent'; + const Config = { + eventsMapping: [], + }; + const result = deduceTrackEventName(trackEventName, Config); + expect(result).toEqual([trackEventName]); + }); + + // The function returns the corresponding event name from eventsMapping if the trackEventName is mapped to a standard bluecore event. + it('should return the corresponding event name from eventsMapping if the trackEventName is mapped to a standard bluecore event', () => { + const trackEventName = 'customEvent'; + const Config = { + eventsMapping: [{ from: 'customEvent', to: 'search' }], + }; + const result = deduceTrackEventName(trackEventName, Config); + expect(result).toEqual(['search']); + }); + + // The function returns the corresponding event name from eventsMapping if the trackEventName is mapped to a standard bluecore event. + it('should return the corresponding event name array from eventsMapping if the trackEventName is mapped to more than one standard bluecore events', () => { + const trackEventName = 'customEvent'; + const Config = { + eventsMapping: [ + { from: 'customEvent', to: 'search' }, + { from: 'customEvent', to: 'purchase' }, + ], + }; + const result = deduceTrackEventName(trackEventName, Config); + expect(result).toEqual(['search', 'purchase']); + }); + + // The function returns the corresponding standard Rudderstack ecommerce event name if the trackEventName is a standard bluecore event. + it('should return the corresponding standard Rudderstack ecommerce event name if the trackEventName is a standard bluecore event', () => { + const trackEventName = 'Product Added to Wishlist'; + const Config = { + eventsMapping: [], + }; + const result = deduceTrackEventName(trackEventName, Config); + expect(result).toEqual(['wishlist']); + }); + + // The function throws an error if the trackEventName is not a string. + it('should throw an error if the trackEventName is not a string', () => { + const trackEventName = 123; + const Config = { + eventsMapping: [], + }; + expect(() => deduceTrackEventName(trackEventName, Config)).toThrow(); + }); + + // The function throws an error if the trackEventName is an empty string. + it('should throw an error if the trackEventName is an empty string', () => { + const trackEventName = ''; + const Config = { + eventsMapping: [], + }; + expect(() => deduceTrackEventName(trackEventName, Config)).toThrow(); + }); +}); + +describe('populateAccurateDistinctId', () => { + // Returns the distinctId based on the email field when it exists in the message object and the event is not an identify event. + it('should return the distinctId based on the email field when it exists in the message object and the event is not an identify event', () => { + const payload = { event: 'event' }; + const message = { userId: '123', context: { traits: { email: 'test@example.com' } } }; + const distinctId = populateAccurateDistinctId(payload, message); + expect(distinctId).toBe('test@example.com'); + }); + + // Returns the distinctId based on the userId field when it exists in the message object and the event is an identify event. + it('should return the distinctId based on the userId field when it exists in the message object and the event is an identify event', () => { + const payload = { event: 'identify' }; + const message = { userId: '123', context: { traits: { email: 'test@example.com' } } }; + const distinctId = populateAccurateDistinctId(payload, message); + expect(distinctId).toBe('123'); + }); + + // Returns the distinctId based on the userId field when it exists in the message object and the email field does not exist and the event is not an identify event. + it('should return the distinctId based on the userId field when it exists in the message object and the email field does not exist and the event is not an identify event', () => { + const payload = { event: 'event' }; + const message = { userId: '123' }; + const distinctId = populateAccurateDistinctId(payload, message); + expect(distinctId).toBe('123'); + }); + + // Returns the distinctId based on the email field when it exists in the message object and the userId field is empty and the event is not an identify event. + it('should throw instrumenatation error as the message is malformed where email is at the root level', () => { + const payload = { event: 'event' }; + const message = { email: 'test@example.com', userId: '' }; + const testFn = () => populateAccurateDistinctId(payload, message); + expect(testFn).toThrow(InstrumentationError); + }); + + // Returns the distinctId based on the userId field when it exists in the message object and the email field is empty and the event is not an identify event. + it('should return the distinctId based on the userId field when it exists in the message object and the email field is empty and the event is not an identify event', () => { + const payload = { event: 'event' }; + const message = { email: '', userId: '123' }; + const distinctId = populateAccurateDistinctId(payload, message); + expect(distinctId).toBe('123'); + }); + + // Returns the distinctId based on the anonymousId field when it exists in the message object and the email and userId fields are empty and the event is not an identify event. + it('should return the distinctId based on the anonymousId field when it exists in the message object and the email and userId fields are empty and the event is not an identify event', () => { + const payload = { event: 'event' }; + const message = { anonymousId: 'abc' }; + const distinctId = populateAccurateDistinctId(payload, message); + expect(distinctId).toBe('abc'); + }); + + it('should return the distinctId based on the externalId field when it exists in the context object and the event is not an identify event', () => { + const payload = { event: 'event' }; + const message = { + userId: '123', + context: { + traits: { email: 'test@example.com' }, + externalId: [{ type: 'bluecoreExternalId', id: '54321' }], + }, + }; + const distinctId = populateAccurateDistinctId(payload, message); + expect(distinctId).toBe('54321'); + }); + + it('should return the distinctId based on the externalId field when it exists in the context object and the event is an identify event', () => { + const payload = { event: 'identify' }; + const message = { + userId: '123', + context: { + traits: { email: 'test@example.com' }, + externalId: [{ type: 'bluecoreExternalId', id: '54321' }], + }, + }; + const distinctId = populateAccurateDistinctId(payload, message); + expect(distinctId).toBe('54321'); + }); +}); + +describe('createProductForStandardEcommEvent', () => { + // Returns an array containing the properties if the event is a standard Bluecore event and not 'search'. + it("should return an array containing the properties when the event is a standard Bluecore event and not 'search'", () => { + const message = { + event: 'some event', + properties: { name: 'product 1' }, + }; + const eventName = 'some event'; + const result = createProductForStandardEcommEvent(message, eventName); + expect(result).toEqual(null); + }); + + // Returns null if the event is 'search'. + it("should return null when the event is 'search'", () => { + const message = { + event: 'search', + properties: { name: 'product 1' }, + }; + const eventName = 'search'; + const result = createProductForStandardEcommEvent(message, eventName); + expect(result).toBeNull(); + }); + + // Throws an InstrumentationError if the event is 'order completed' and the eventName is 'purchase'. + it("should throw an InstrumentationError when the event is 'order completed' and the eventName is 'purchase'", () => { + const message = { + event: 'order completed', + properties: { name: 'product 1' }, + }; + const eventName = 'purchase'; + expect(() => { + createProductForStandardEcommEvent(message, eventName); + }).toThrow(InstrumentationError); + }); + + // Returns null if the eventName is not a standard Bluecore event. + it('should return null when the eventName is not a standard Bluecore event', () => { + const message = { + event: 'some event', + properties: { name: 'product 1', products: [{ product_id: 1, name: 'prod1' }] }, + }; + const eventName = 'non-standard'; + const result = createProductForStandardEcommEvent(message, eventName); + expect(result).toBeNull(); + }); + + // Returns null if the eventName is not provided. + it('should return null when the eventName is not provided', () => { + const message = { + event: 'some event', + properties: { name: 'product 1' }, + }; + const result = createProductForStandardEcommEvent(message); + expect(result).toBeNull(); + }); + + // Returns null if the properties are not provided. + it('should return null when the properties are not provided', () => { + const message = { + event: 'some event', + }; + const eventName = 'some event'; + const result = createProductForStandardEcommEvent(message, eventName); + expect(result).toBeNull(); + }); +}); diff --git a/src/cdk/v2/destinations/fullstory/procWorkflow.yaml b/src/cdk/v2/destinations/fullstory/procWorkflow.yaml index 50ac2a81630..1a54e8688ca 100644 --- a/src/cdk/v2/destinations/fullstory/procWorkflow.yaml +++ b/src/cdk/v2/destinations/fullstory/procWorkflow.yaml @@ -5,7 +5,7 @@ bindings: exportAll: true - name: removeUndefinedAndNullValues path: ../../../../v0/util - + steps: - name: validateInput template: | @@ -28,7 +28,7 @@ steps: $.context.payload.uid = .message.userId; $.context.payload.email = .message.context.traits.email; $.context.payload.display_name = .message.context.traits.name; - + - name: trackPayload condition: $.context.messageType == "track" template: | @@ -42,9 +42,9 @@ steps: condition: $.context.messageType == "track" template: | $.assert(.message.event, "event is required for track call") - + - name: mapContextFieldsForTrack - condition: $.context.messageType == "track" + condition: $.context.messageType == "track" template: | $.context.payload.context.browser = { "url": .message.context.page.url, @@ -67,7 +67,7 @@ steps: "region": .message.properties.region, "country": .message.properties.country, }; - + - name: mapIdsForTrack condition: $.context.messageType == "track" template: | @@ -99,6 +99,3 @@ steps: "params": {}, "files": {} }) - - - diff --git a/src/cdk/v2/destinations/gladly/procWorkflow.yaml b/src/cdk/v2/destinations/gladly/procWorkflow.yaml index fe8697bc31a..a53a0ca8f57 100644 --- a/src/cdk/v2/destinations/gladly/procWorkflow.yaml +++ b/src/cdk/v2/destinations/gladly/procWorkflow.yaml @@ -13,7 +13,6 @@ bindings: path: ../../../../adapters/network - name: processAxiosResponse path: ../../../../adapters/utils/networkUtils - steps: - name: checkIfProcessed diff --git a/src/cdk/v2/destinations/gladly/rtWorkflow.yaml b/src/cdk/v2/destinations/gladly/rtWorkflow.yaml index 341e5552c83..fc5d474d606 100644 --- a/src/cdk/v2/destinations/gladly/rtWorkflow.yaml +++ b/src/cdk/v2/destinations/gladly/rtWorkflow.yaml @@ -30,4 +30,4 @@ steps: )[] - name: finalPayload template: | - [...$.outputs.successfulEvents, ...$.outputs.failedEvents] \ No newline at end of file + [...$.outputs.successfulEvents, ...$.outputs.failedEvents] diff --git a/src/cdk/v2/destinations/heap/procWorkflow.yaml b/src/cdk/v2/destinations/heap/procWorkflow.yaml index 0191b75d188..ac12e7e02a2 100644 --- a/src/cdk/v2/destinations/heap/procWorkflow.yaml +++ b/src/cdk/v2/destinations/heap/procWorkflow.yaml @@ -40,7 +40,9 @@ steps: }); .message.properties.idempotencyKey ? ($.context.payload.idempotency_key = .message.properties.idempotencyKey); - + - name: validateuserId + template: | + $.assert($.context.payload.identity, "userId is required"); - name: finalPayload description: In batchMode we return payload directly condition: $.batchMode @@ -58,5 +60,3 @@ steps: "Content-Type": "application/json" }; response - - \ No newline at end of file diff --git a/src/cdk/v2/destinations/intercom/config.js b/src/cdk/v2/destinations/intercom/config.js new file mode 100644 index 00000000000..518d805d41a --- /dev/null +++ b/src/cdk/v2/destinations/intercom/config.js @@ -0,0 +1,81 @@ +const BASE_ENDPOINT = 'https://api.intercom.io'; +const BASE_EU_ENDPOINT = 'https://api.eu.intercom.io'; +const BASE_AU_ENDPOINT = 'https://api.au.intercom.io'; + +const SEARCH_CONTACT_ENDPOINT = 'contacts/search'; +const CREATE_OR_UPDATE_COMPANY_ENDPOINT = 'companies'; + +const ReservedAttributes = { + v1UserAttributes: [ + 'userId', + 'email', + 'phone', + 'name', + 'createdAt', + 'firstName', + 'lastName', + 'firstname', + 'lastname', + 'company', + ], + v2UserAttributes: [ + 'userId', + 'role', + 'email', + 'phone', + 'name', + 'avatar', + 'company', + 'ownerId', + 'lastName', + 'lastname', + 'firstName', + 'firstname', + 'createdAt', + 'timestamp', + 'lastSeenAt', + 'originalTimestamp', + 'unsubscribedFromEmails', + ], + v1CompanyAttributes: [ + 'remoteCreatedAt', + 'monthlySpend', + 'industry', + 'website', + 'size', + 'plan', + 'name', + 'userId', + ], + v2CompanyAttributes: [ + 'tags', + 'size', + 'plan', + 'name', + 'email', + 'userId', + 'website', + 'industry', + 'segments', + 'userCount', + 'createdAt', + 'sessionCount', + 'monthlySpend', + 'remoteCreatedAt', + ], +}; + +const ReservedCompanyProperties = ['id', 'name', 'industry']; + +const MetadataTypes = { richLink: ['url', 'value'], monetaryAmount: ['amount', 'currency'] }; + +module.exports = { + BASE_ENDPOINT, + MetadataTypes, + BASE_EU_ENDPOINT, + BASE_AU_ENDPOINT, + ReservedAttributes, + SEARCH_CONTACT_ENDPOINT, + ReservedCompanyProperties, + CREATE_OR_UPDATE_COMPANY_ENDPOINT, +}; diff --git a/src/cdk/v2/destinations/intercom/procWorkflow.yaml b/src/cdk/v2/destinations/intercom/procWorkflow.yaml new file mode 100644 index 00000000000..0a8842d5e77 --- /dev/null +++ b/src/cdk/v2/destinations/intercom/procWorkflow.yaml @@ -0,0 +1,230 @@ +bindings: + - name: EventType + path: ../../../../constants + - path: ./utils + exportAll: true + - path: ../../bindings/jsontemplate + exportAll: true + - name: defaultRequestConfig + path: ../../../../v0/util + - name: removeUndefinedAndNullValues + path: ../../../../v0/util + - name: getFieldValueFromMessage + path: ../../../../v0/util + - name: isDefinedAndNotNull + path: ../../../../v0/util + - name: addExternalIdToTraits + path: ../../../../v0/util + - path: ../../bindings/jsontemplate + +steps: + - name: checkIfProcessed + condition: .message.statusCode + template: | + $.batchMode ? .message.body.JSON : .message; + onComplete: return + + - name: messageType + template: | + .message.type.toLowerCase(); + + - name: validateInput + template: | + let messageType = $.outputs.messageType; + $.assert(messageType, "message Type is not present. Aborting"); + $.assert(messageType in {{$.EventType.([.IDENTIFY, .TRACK, .GROUP])}}, "message type " + messageType + " is not supported"); + $.assertConfig(.destination.Config.apiKey, "Access Token is not present. Aborting"); + + - name: apiVersion + template: | + const version = $.isDefinedAndNotNull(.destination.Config.apiVersion) ? .destination.Config.apiVersion : "v2"; + version; + + - name: rEtlPayload + condition: .message.context.mappedToDestination + template: | + $.addExternalIdToTraits(.message); + const payload = $.getFieldValueFromMessage(.message, "traits"); + payload; + + - name: searchContact + condition: ($.outputs.messageType === {{$.EventType.IDENTIFY}} || $.outputs.messageType === {{$.EventType.GROUP}}) && $.outputs.apiVersion !== "v1" + template: | + const contactId = await $.searchContact(.message, .destination); + contactId; + + - name: identifyTransformationForLatestVersion + condition: $.outputs.messageType === {{$.EventType.IDENTIFY}} && $.outputs.apiVersion !== "v1" && !.message.context.mappedToDestination + template: | + const payload = .message.({ + external_id: {{{{$.getGenericPaths("userIdOnly")}}}}, + email: {{{{$.getGenericPaths("email")}}}}, + phone: {{{{$.getGenericPaths("phone")}}}}, + avatar: {{{{$.getGenericPaths("avatar")}}}}, + last_seen_at: $.toSeconds(.context.traits.lastSeenAt), + role: .traits.role || .context.traits.role, + signed_up_at: $.toSeconds(.traits.createdAt || .context.traits.createdAt), + owner_id: Number(.traits.ownerId || .context.traits.ownerId) || undefined, + unsubscribed_from_emails: .traits.unsubscribedFromEmails || .context.traits.unsubscribedFromEmails + }); + !(payload.external_id) && .destination.Config.sendAnonymousId ? payload.external_id = .message.anonymousId; + payload; + + - name: identifyPayloadForLatestVersion + condition: $.outputs.messageType === {{$.EventType.IDENTIFY}} && $.outputs.apiVersion !== "v1" + template: | + const payload = .message.context.mappedToDestination ? $.outputs.rEtlPayload : $.outputs.identifyTransformationForLatestVersion; + payload.name = $.getName(.message); + payload.custom_attributes = .message.context.traits || {}; + payload.custom_attributes = $.filterCustomAttributes(payload, "user", .destination); + payload.external_id = !payload.external_id && .destination.Config.sendAnonymousId && .message.anonymousId ? .message.anonymousId : payload.external_id; + $.context.payload = payload; + $.assert($.context.payload.external_id || $.context.payload.email, "Either email or userId is required for Identify call"); + const endpoint = $.getBaseEndpoint(.destination) + "/" + "contacts"; + $.context.requestMethod = $.outputs.searchContact ? 'PUT' : 'POST'; + $.context.endpoint = $.outputs.searchContact ? endpoint + "/" + $.outputs.searchContact : endpoint; + $.context.payload = $.removeUndefinedAndNullValues($.context.payload); + + - name: identifyTransformationForOlderVersion + condition: $.outputs.messageType === {{$.EventType.IDENTIFY}} && $.outputs.apiVersion === "v1" && !.message.context.mappedToDestination + template: | + const payload = .message.({ + user_id: {{{{$.getGenericPaths("userIdOnly")}}}}, + email: {{{{$.getGenericPaths("email")}}}}, + phone: {{{{$.getGenericPaths("phone")}}}}, + signed_up_at: $.toSeconds(.traits.createdAt || .context.traits.createdAt), + last_seen_user_agent: .context.userAgent, + }); + !(payload.user_id) && .destination.Config.sendAnonymousId ? payload.user_id = .message.anonymousId; + payload; + + - name: identifyPayloadForOlderVersion + condition: $.outputs.messageType === {{$.EventType.IDENTIFY}} && $.outputs.apiVersion === "v1" + template: | + let payload = .message.context.mappedToDestination ? $.outputs.rEtlPayload : $.outputs.identifyTransformationForOlderVersion; + payload = { + ...payload, + name : $.getName(.message), + custom_attributes : .message.traits || .message.context.traits || {}, + update_last_request_at: typeof .destination.Config.updateLastRequestAt === 'boolean' ? .destination.Config.updateLastRequestAt : true + } + payload.companies = $.getCompaniesList(payload); + payload.custom_attributes = !.message.context.mappedToDestination ? $.filterCustomAttributes(payload, "user", .destination); + payload.user_id = !payload.user_id && .destination.Config.sendAnonymousId && .message.anonymousId ? .message.anonymousId : payload.user_id; + $.context.payload = payload; + $.assert($.context.payload.user_id || $.context.payload.email, "Either of `email` or `userId` is required for Identify call"); + $.context.requestMethod = 'POST'; + $.context.endpoint = $.getBaseEndpoint(.destination) + "/" + "users"; + $.context.payload = $.removeUndefinedAndNullValues($.context.payload); + + - name: trackTransformation + condition: $.outputs.messageType === {{$.EventType.TRACK}} && !.message.context.mappedToDestination + template: | + const timestamp = .message.().( + {{{{$.getGenericPaths("timestamp")}}}}; + ); + const payload = .message.({ + event_name: .event, + user_id: {{{{$.getGenericPaths("userIdOnly")}}}}, + email: {{{{$.getGenericPaths("email")}}}}, + metadata: .properties + }); + $.outputs.apiVersion !== "v1" ? payload.id = .message.properties.id || .message.traits.id; + $.outputs.apiVersion !== "v1" ? payload.created_at = $.toSeconds(timestamp); + $.outputs.apiVersion === "v1" ? payload.created = $.toSeconds(timestamp); + !(payload.user_id) && .destination.Config.sendAnonymousId ? payload.user_id = .message.anonymousId; + payload; + + - name: trackPayload + condition: $.outputs.messageType === {{$.EventType.TRACK}} + template: | + let payload = .message.context.mappedToDestination ? $.outputs.rEtlPayload : $.outputs.trackTransformation; + payload = $.addMetadataToPayload(payload); + $.context.payload = payload; + $.assert($.context.payload.event_name, "Event name is required for track call"); + $.assert($.context.payload.user_id || $.context.payload.email, "Either email or userId is required for Track call"); + $.context.requestMethod = 'POST'; + $.context.endpoint = $.getBaseEndpoint(.destination) + "/" + "events"; + $.context.payload = $.removeUndefinedAndNullValues($.context.payload); + + - name: groupTransformation + condition: $.outputs.messageType === {{$.EventType.GROUP}} && !.message.context.mappedToDestination + template: | + const payload = .message.({ + company_id: {{{{$.getGenericPaths("groupId")}}}}, + name: {{{{$.getGenericPaths("name")}}}}, + website: {{{{$.getGenericPaths("website")}}}}, + plan: .traits.plan || .context.traits.plan, + size: Number(.traits.size || .context.traits.size), + industry: .traits.industry || .context.traits.industry, + monthly_spend: .traits.monthlySpend || .context.traits.monthlySpend ? Number(.traits.monthlySpend || .context.traits.monthlySpend) : undefined, + remote_created_at: .traits.remoteCreatedAt || .context.traits.remoteCreatedAt ? Number(.traits.remoteCreatedAt || .context.traits.remoteCreatedAt) : undefined + }); + payload; + + - name: groupPayloadForLatestVersion + condition: $.outputs.messageType === {{$.EventType.GROUP}} && $.outputs.apiVersion !== "v1" + steps: + - name: validateMessageAndPreparePayload + template: | + $.assert(.message.groupId, "groupId is required for group call"); + const payload = .message.context.mappedToDestination ? $.outputs.rEtlPayload : $.outputs.groupTransformation; + payload.custom_attributes = .message.traits || {}; + payload.custom_attributes = $.filterCustomAttributes(payload, "company", .destination); + $.context.payload = payload; + - name: whenSearchContactFound + condition: $.isDefinedAndNotNull($.outputs.searchContact) + template: | + const contactId = $.outputs.searchContact; + const companyId = await $.createOrUpdateCompany($.context.payload, .destination); + $.assert(companyId, "Unable to create or update company"); + $.context.payload = { + id: companyId, + }; + $.context.endpoint = $.getBaseEndpoint(.destination) + "/" + "contacts" + "/" + contactId + "/" + "companies"; + else: + name: whenSearchContactNotFound + template: | + $.context.endpoint = $.getBaseEndpoint(.destination) + "/" + "companies"; + - name: prepareFinalPayload + template: | + $.context.requestMethod = 'POST'; + $.removeUndefinedAndNullValues($.context.payload); + + - name: groupPayloadForOlderVersion + condition: $.outputs.messageType === {{$.EventType.GROUP}} && $.outputs.apiVersion === "v1" + template: | + $.context.response = []; + const response = $.defaultRequestConfig(); + let payload = .message.context.mappedToDestination ? $.outputs.rEtlPayload : $.outputs.groupTransformation; + payload = { + ...payload, + custom_attributes : $.getFieldValueFromMessage(.message, "traits") || {} + } + payload.custom_attributes = $.filterCustomAttributes(payload, "company", .destination); + response.body.JSON = $.removeUndefinedAndNullValues(payload); + response.endpoint = $.getBaseEndpoint(.destination) + "/" + "companies"; + response.headers = $.getHeaders(.destination, $.outputs.apiVersion); + response.method = "POST"; + response.userId = .message.anonymousId; + $.context.response.push(response); + const attachUserAndCompanyResponse = $.attachUserAndCompany(.message, .destination.Config); + attachUserAndCompanyResponse ? attachUserAndCompanyResponse.userId = .message.anonymousId; + attachUserAndCompanyResponse ? $.context.response.push(attachUserAndCompanyResponse); + + - name: buildResponseForProcessTransformation + description: Build response for multiple transformed event + condition: $.context.response && $.context.response.length > 0 + template: | + $.context.response; + else: + name: buildResponseForProcessTransformation + description: Build response for single transformed event + template: | + const response = $.defaultRequestConfig(); + response.body.JSON = $.context.payload; + response.endpoint = $.context.endpoint; + response.method = $.context.requestMethod; + response.headers = $.getHeaders(.destination, $.outputs.apiVersion); + $.outputs.apiVersion === "v1" && $.outputs.messageType !== {{$.EventType.GROUP}} ? response.userId = .message.anonymousId; + response; diff --git a/src/cdk/v2/destinations/intercom/rtWorkflow.yaml b/src/cdk/v2/destinations/intercom/rtWorkflow.yaml new file mode 100644 index 00000000000..edb7267b84c --- /dev/null +++ b/src/cdk/v2/destinations/intercom/rtWorkflow.yaml @@ -0,0 +1,33 @@ +bindings: + - name: handleRtTfSingleEventError + path: ../../../../v0/util/index + - name: isDefinedAndNotNull + path: ../../../../v0/util + +steps: + - name: validateInput + template: | + $.assert(Array.isArray(^) && ^.length > 0, "Invalid event array") + + - name: transform + externalWorkflow: + path: ./procWorkflow.yaml + loopOverInput: true + + - name: successfulEvents + template: | + $.outputs.transform#idx{$.isDefinedAndNotNull(.output)}.({ + "batchedRequest": .output, + "batched": false, + "destination": ^[idx].destination, + "metadata": ^[idx].metadata[], + "statusCode": 200 + })[] + - name: failedEvents + template: | + $.outputs.transform#idx.error.( + $.handleRtTfSingleEventError(^[idx], .originalError ?? ., {}) + )[] + - name: finalPayload + template: | + [...$.outputs.successfulEvents, ...$.outputs.failedEvents] diff --git a/src/cdk/v2/destinations/intercom/utils.js b/src/cdk/v2/destinations/intercom/utils.js new file mode 100644 index 00000000000..ba3063c9f9d --- /dev/null +++ b/src/cdk/v2/destinations/intercom/utils.js @@ -0,0 +1,385 @@ +const md5 = require('md5'); +const get = require('get-value'); +const { NetworkError } = require('@rudderstack/integrations-lib'); +const tags = require('../../../../v0/util/tags'); +const { httpPOST } = require('../../../../adapters/network'); +const { + processAxiosResponse, + getDynamicErrorType, +} = require('../../../../adapters/utils/networkUtils'); +const { + flattenJson, + getIntegrationsObj, + isDefinedAndNotNull, + isHttpStatusSuccess, + defaultRequestConfig, + getFieldValueFromMessage, + defaultPostRequestConfig, + removeUndefinedAndNullValues, +} = require('../../../../v0/util'); +const { JSON_MIME_TYPE } = require('../../../../v0/util/constant'); +const { + BASE_ENDPOINT, + MetadataTypes, + BASE_EU_ENDPOINT, + BASE_AU_ENDPOINT, + ReservedAttributes, + SEARCH_CONTACT_ENDPOINT, + ReservedCompanyProperties, + CREATE_OR_UPDATE_COMPANY_ENDPOINT, +} = require('./config'); + +/** + * Returns destination request headers + * @param {*} destination + * @param {*} apiVersion + * @returns + */ +const getHeaders = (destination, apiVersion) => ({ + 'Content-Type': JSON_MIME_TYPE, + Authorization: `Bearer ${destination.Config.apiKey}`, + Accept: JSON_MIME_TYPE, + 'Intercom-Version': apiVersion === 'v1' ? '1.4' : '2.10', +}); + +/** + * Returns destination request base endpoint + * @param {*} destination + * @returns + */ +const getBaseEndpoint = (destination) => { + const { apiServer } = destination.Config; + let { apiVersion } = destination.Config; + apiVersion = isDefinedAndNotNull(apiVersion) ? apiVersion : 'v2'; + + if (apiVersion === 'v1') return BASE_ENDPOINT; + switch (apiServer) { + case 'eu': + return BASE_EU_ENDPOINT; + case 'au': + return BASE_AU_ENDPOINT; + default: + return BASE_ENDPOINT; + } +}; + +/** + * Returns contact lookup field + * @param {*} message + * @returns + */ +const getLookUpField = (message) => { + let lookupField = 'email'; + const integrationsObj = getIntegrationsObj(message, 'INTERCOM'); + if (integrationsObj && isDefinedAndNotNull(integrationsObj.lookup)) { + lookupField = integrationsObj.lookup; + } + return lookupField; +}; + +/** + * Returns the value of name field + * @param {*} message + * @returns + */ +const getName = (message) => { + const name = message?.traits?.name || message?.context?.traits?.name; + if (name) return name; + const firstName = getFieldValueFromMessage(message, 'firstName'); + const lastName = getFieldValueFromMessage(message, 'lastName'); + if (firstName && lastName) { + return `${firstName} ${lastName}`; + } + + if (firstName || lastName) { + return firstName || lastName; + } + return undefined; +}; + +/** + * Returns company payload + * @param {*} payload + * @returns + */ +const getCompaniesList = (payload) => { + const company = get(payload, 'custom_attributes.company'); + if (!company) return undefined; + const companiesList = []; + if (company.name || company.id) { + const customAttributes = {}; + Object.keys(company).forEach((key) => { + // If key is not in ReservedCompanyProperties + if (!ReservedCompanyProperties.includes(key)) { + const val = company[key]; + if (val !== Object(val)) { + customAttributes[key] = val; + } else { + customAttributes[key] = JSON.stringify(val); + } + } + }); + + companiesList.push({ + company_id: company.id || md5(company.name), + custom_attributes: removeUndefinedAndNullValues(customAttributes), + name: company.name, + industry: company.industry, + }); + } + return companiesList; +}; + +/** + * Returns if email or userId is present in payload or not + * @param {*} message + * @param {*} Config + * @returns + */ +const checkIfEmailOrUserIdPresent = (message, Config) => { + const { context, anonymousId } = message; + let { userId } = message; + if (Config.sendAnonymousId && !userId) { + userId = anonymousId; + } + return !!(userId || context?.traits?.email); +}; + +/** + * Returns add user to company payload + * @param {*} message + * @param {*} Config + * @returns + */ +const attachUserAndCompany = (message, Config) => { + if (!checkIfEmailOrUserIdPresent(message, Config)) return undefined; + const email = message.context?.traits?.email; + const { userId, anonymousId, traits, groupId } = message; + const requestBody = {}; + if (userId) { + requestBody.user_id = userId; + } + if (Config.sendAnonymousId && !userId) { + requestBody.user_id = anonymousId; + } + if (email) { + requestBody.email = email; + } + const companyObj = { + company_id: groupId, + }; + if (traits?.name) { + companyObj.name = traits.name; + } + requestBody.companies = [companyObj]; + const response = defaultRequestConfig(); + response.method = defaultPostRequestConfig.requestMethod; + response.endpoint = `${BASE_ENDPOINT}/users`; + response.headers = { + 'Content-Type': JSON_MIME_TYPE, + Authorization: `Bearer ${Config.apiKey}`, + Accept: JSON_MIME_TYPE, + 'Intercom-Version': '1.4', + }; + response.body.JSON = requestBody; + response.userId = anonymousId; + return response; +}; + +/** + * Returns custom attributes for identify and group calls (for contact and company in intercom) + * @param {*} payload + * @param {*} type + * @returns + */ +const filterCustomAttributes = (payload, type, destination) => { + let ReservedAttributesList; + let { apiVersion } = destination.Config; + apiVersion = isDefinedAndNotNull(apiVersion) ? apiVersion : 'v2'; + if (type === 'user') { + ReservedAttributesList = + apiVersion === 'v1' + ? ReservedAttributes.v1UserAttributes + : ReservedAttributes.v2UserAttributes; + } else { + ReservedAttributesList = + apiVersion === 'v1' + ? ReservedAttributes.v1CompanyAttributes + : ReservedAttributes.v2CompanyAttributes; + } + let customAttributes = { ...get(payload, 'custom_attributes') }; + if (customAttributes) { + ReservedAttributesList.forEach((trait) => { + if (customAttributes[trait]) delete customAttributes[trait]; + }); + if (isDefinedAndNotNull(customAttributes) && Object.keys(customAttributes).length > 0) { + customAttributes = + apiVersion === 'v1' ? flattenJson(customAttributes) : flattenJson(customAttributes, '_'); + } + } + return Object.keys(customAttributes).length === 0 ? undefined : customAttributes; +}; + +/** + * Api call to search contact in intercom to returns id of contact + * Ref doc : https://developers.intercom.com/docs/references/rest-api/api.intercom.io/Contacts/SearchContacts/ + * @param {*} message + * @param {*} destination + * @returns + */ +const searchContact = async (message, destination) => { + const lookupField = getLookUpField(message); + const lookupFieldValue = getFieldValueFromMessage(message, lookupField); + const data = JSON.stringify({ + query: { + operator: 'AND', + value: [ + { + field: lookupField, + operator: '=', + value: lookupFieldValue, + }, + ], + }, + }); + + const headers = getHeaders(destination); + const baseEndPoint = getBaseEndpoint(destination); + const endpoint = `${baseEndPoint}/${SEARCH_CONTACT_ENDPOINT}`; + const response = await httpPOST( + endpoint, + data, + { + headers, + }, + { + destType: 'intercom', + feature: 'transformation', + endpointPath: '/contacts/search', + requestMethod: 'POST', + module: 'router', + }, + ); + const processedUserResponse = processAxiosResponse(response); + if (isHttpStatusSuccess(processedUserResponse.status)) { + return processedUserResponse.response?.data.length > 0 + ? processedUserResponse.response?.data[0]?.id + : null; + } + + throw new NetworkError( + `Unable to search contact due to : ${JSON.stringify(processedUserResponse?.response?.errors)}`, + processedUserResponse?.status, + { + [tags]: getDynamicErrorType(processedUserResponse?.status), + }, + processedUserResponse, + ); +}; + +/** + * Api call to create or update companies in intercom + * Ref doc : https://developers.intercom.com/docs/references/rest-api/api.intercom.io/Companies/createOrUpdateCompany/ + * @param {*} payload + * @param {*} destination + * @returns + */ +const createOrUpdateCompany = async (payload, destination) => { + const headers = getHeaders(destination); + const finalPayload = JSON.stringify(removeUndefinedAndNullValues(payload)); + const baseEndPoint = getBaseEndpoint(destination); + const endpoint = `${baseEndPoint}/${CREATE_OR_UPDATE_COMPANY_ENDPOINT}`; + const response = await httpPOST( + endpoint, + finalPayload, + { + headers, + }, + { + destType: 'intercom', + feature: 'transformation', + endpointPath: '/companies', + requestMethod: 'POST', + module: 'router', + }, + ); + + const processedResponse = processAxiosResponse(response); + if (isHttpStatusSuccess(processedResponse.status)) { + return processedResponse.response?.id; + } + + throw new NetworkError( + `Unable to Create or Update Company due to : ${JSON.stringify( + processedResponse?.response?.errors, + )}`, + processedResponse?.status, + { + [tags]: getDynamicErrorType(processedResponse?.status), + }, + processedResponse, + ); +}; + +/** + * Returns metadata object + * @param {*} metadata + * @returns + */ +const separateReservedAndRestMetadata = (metadata) => { + const reservedMetadata = {}; + const restMetadata = {}; + if (metadata) { + Object.entries(metadata).forEach(([key, value]) => { + if (value && typeof value === 'object') { + const hasMonetaryAmountKeys = MetadataTypes.monetaryAmount.every((type) => type in value); + const hasRichLinkKeys = MetadataTypes.richLink.every((type) => type in value); + if (hasMonetaryAmountKeys || hasRichLinkKeys) { + reservedMetadata[key] = value; + } else { + restMetadata[key] = value; + } + } else { + restMetadata[key] = value; + } + }); + } + + // Return the separated metadata objects + return { reservedMetadata, restMetadata }; +}; + +/** + * Returns final payload with metadata + * @param {*} payload + * @returns + */ +const addMetadataToPayload = (payload) => { + let finalPayload = payload; + if (finalPayload.metadata) { + // reserved metadata contains JSON objects that does not requires flattening + const { reservedMetadata, restMetadata } = separateReservedAndRestMetadata( + finalPayload.metadata, + ); + finalPayload = { + ...finalPayload, + metadata: { ...reservedMetadata, ...flattenJson(restMetadata) }, + }; + } + return finalPayload; +}; + +module.exports = { + getName, + getHeaders, + searchContact, + getLookUpField, + getBaseEndpoint, + getCompaniesList, + addMetadataToPayload, + attachUserAndCompany, + createOrUpdateCompany, + filterCustomAttributes, + checkIfEmailOrUserIdPresent, + separateReservedAndRestMetadata, +}; diff --git a/src/cdk/v2/destinations/intercom/utils.test.js b/src/cdk/v2/destinations/intercom/utils.test.js new file mode 100644 index 00000000000..e651b4ea5dc --- /dev/null +++ b/src/cdk/v2/destinations/intercom/utils.test.js @@ -0,0 +1,765 @@ +const md5 = require('md5'); +const axios = require('axios'); +const { + getName, + getHeaders, + searchContact, + getLookUpField, + getBaseEndpoint, + getCompaniesList, + addMetadataToPayload, + attachUserAndCompany, + createOrUpdateCompany, + filterCustomAttributes, + checkIfEmailOrUserIdPresent, + separateReservedAndRestMetadata, +} = require('./utils'); +const { BASE_ENDPOINT, BASE_EU_ENDPOINT, BASE_AU_ENDPOINT } = require('./config'); + +jest.mock('axios', () => ({ + ...jest.requireActual('axios'), + post: jest.fn(), +})); + +describe('separateReservedAndRestMetadata utility test', () => { + it('separate reserved and rest metadata', () => { + const metadata = { + property1: 1, + property2: 'test', + property3: true, + property4: { + property1: 1, + property2: 'test', + property3: { + subProp1: { + a: 'a', + b: 'b', + }, + subProp2: ['a', 'b'], + }, + }, + property5: {}, + property6: [], + property7: null, + property8: undefined, + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + price: { + amount: 3000, + currency: 'USD', + }, + article: { + url: 'https://example.org/ab1de.html', + value: 'the dude abides', + }, + }; + const expectedReservedMetadata = { + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + price: { + amount: 3000, + currency: 'USD', + }, + article: { + url: 'https://example.org/ab1de.html', + value: 'the dude abides', + }, + }; + const expectedRestMetadata = { + property1: 1, + property2: 'test', + property3: true, + property4: { + property1: 1, + property2: 'test', + property3: { + subProp1: { + a: 'a', + b: 'b', + }, + subProp2: ['a', 'b'], + }, + }, + property5: {}, + property6: [], + property7: null, + property8: undefined, + }; + const { reservedMetadata, restMetadata } = separateReservedAndRestMetadata(metadata); + + expect(expectedReservedMetadata).toEqual(reservedMetadata); + expect(expectedRestMetadata).toEqual(restMetadata); + }); + + it('reserved metadata types not present in input metadata', () => { + const metadata = { + property1: 1, + property2: 'test', + property3: true, + property4: { + property1: 1, + property2: 'test', + property3: { + subProp1: { + a: 'a', + b: 'b', + }, + subProp2: ['a', 'b'], + }, + }, + property5: {}, + property6: [], + property7: null, + property8: undefined, + }; + const expectedRestMetadata = { + property1: 1, + property2: 'test', + property3: true, + property4: { + property1: 1, + property2: 'test', + property3: { + subProp1: { + a: 'a', + b: 'b', + }, + subProp2: ['a', 'b'], + }, + }, + property5: {}, + property6: [], + property7: null, + property8: undefined, + }; + const { reservedMetadata, restMetadata } = separateReservedAndRestMetadata(metadata); + + expect({}).toEqual(reservedMetadata); + expect(expectedRestMetadata).toEqual(restMetadata); + }); + + it('metadata input contains only reserved metadata types', () => { + const metadata = { + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + price: { + amount: 3000, + currency: 'USD', + }, + article: { + url: 'https://example.org/ab1de.html', + value: 'the dude abides', + }, + }; + const expectedReservedMetadata = { + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + price: { + amount: 3000, + currency: 'USD', + }, + article: { + url: 'https://example.org/ab1de.html', + value: 'the dude abides', + }, + }; + const { reservedMetadata, restMetadata } = separateReservedAndRestMetadata(metadata); + + expect(expectedReservedMetadata).toEqual(reservedMetadata); + expect({}).toEqual(restMetadata); + }); + + it('empty metadata object', () => { + const metadata = {}; + const { reservedMetadata, restMetadata } = separateReservedAndRestMetadata(metadata); + expect({}).toEqual(reservedMetadata); + expect({}).toEqual(restMetadata); + }); + + it('null/undefined metadata', () => { + const metadata = null; + const { reservedMetadata, restMetadata } = separateReservedAndRestMetadata(metadata); + expect({}).toEqual(reservedMetadata); + expect({}).toEqual(restMetadata); + }); +}); + +describe('getBaseEndpoint utility test', () => { + it('Should return BASE_ENDPOINT when destination.Config.apiServer is not "eu" or "au"', () => { + const destination = { + Config: { + apiServer: 'us', + }, + }; + const result = getBaseEndpoint(destination); + expect(result).toBe(BASE_ENDPOINT); + }); + + it('Should return BASE_EU_ENDPOINT when destination.Config.apiServer is "eu"', () => { + const destination = { + Config: { + apiServer: 'eu', + apiVersion: 'v2', + }, + }; + const result = getBaseEndpoint(destination); + expect(result).toBe(BASE_EU_ENDPOINT); + }); + + it('Should return BASE_AU_ENDPOINT when destination.Config.apiServer is "au"', () => { + const destination = { + Config: { + apiServer: 'au', + apiVersion: 'v2', + }, + }; + const result = getBaseEndpoint(destination); + expect(result).toBe(BASE_AU_ENDPOINT); + }); + + it('Should return BASE_ENDPOINT when destination.Config.apiServer is null', () => { + const destination = { + Config: { + apiServer: null, + }, + }; + const result = getBaseEndpoint(destination); + expect(result).toBe(BASE_ENDPOINT); + }); +}); + +describe('getHeaders utility test', () => { + it('Should return an object with the correct headers', () => { + const destination = { + Config: { + apiKey: 'testApiKey', + }, + }; + + const expectedHeaders = { + 'Content-Type': 'application/json', + Authorization: `Bearer ${destination.Config.apiKey}`, + Accept: 'application/json', + 'Intercom-Version': '2.10', + }; + const headers = getHeaders(destination, 'v2'); + expect(headers).toEqual(expectedHeaders); + }); +}); + +describe('getLookUpField utility test', () => { + it('Should return email as default lookup field when no integration object is found', () => { + const message = {}; + const result = getLookUpField(message); + expect(result).toBe('email'); + }); +}); + +describe('getName utility test', () => { + it('Should return the concatenation of firstName and lastName fields when both exist', () => { + const message = { + context: { + traits: { + firstName: 'John', + lastName: 'Doe', + }, + }, + }; + expect(getName(message)).toBe('John Doe'); + }); + + it('Should return the firstName field when only firstName exists', () => { + const message = { + context: { + traits: { + firstName: 'John', + }, + }, + }; + expect(getName(message)).toBe('John'); + }); + + it('Should return the lastName field when only lastName exists', () => { + const message = { + context: { + traits: { + lastName: 'Doe', + }, + }, + }; + expect(getName(message)).toBe('Doe'); + }); + + it('Should return undefined when both message.traits and message.context.traits are undefined', () => { + const message = {}; + expect(getName(message)).toBeUndefined(); + }); +}); + +describe('filterCustomAttributes utility test', () => { + it('Should return an empty object when all custom attributes are reserved attributes', () => { + const payload = { custom_attributes: { email: 'test@rudder.com', name: 'rudder test' } }; + const result = filterCustomAttributes(payload, 'user', { Config: { apiVersion: 'v2' } }); + expect(result).toBeUndefined(); + }); + + it('Should return a flattened object when custom attributes are not null, not reserved attributes and nested', () => { + const payload = { + custom_attributes: { source: 'rudder-js-sdk', data: { nestedAttribute: 'nestedValue' } }, + }; + const result = filterCustomAttributes(payload, 'user', { Config: { apiVersion: 'v2' } }); + expect(result).toEqual({ source: 'rudder-js-sdk', data_nestedAttribute: 'nestedValue' }); + }); + + it('Should return null when custom_attributes is null', () => { + const payload = { custom_attributes: null }; + const result = filterCustomAttributes(payload, 'company', { Config: { apiVersion: 'v2' } }); + expect(result).toBeUndefined(); + }); +}); + +describe('addMetadataToPayload utility test', () => { + it('Should return the same payload if metadata is present but empty', () => { + const payload = { data: 'test', metadata: {} }; + const result = addMetadataToPayload(payload); + expect(result).toEqual(payload); + }); + + it('should add flattened metadata to payload if metadata is present and not empty', () => { + const payload = { + data: 'test', + metadata: { + amount: 30, + currency: 'USD', + url: 'https//test.com', + restData: { source: 'rudderStack' }, + }, + }; + const result = addMetadataToPayload(payload); + expect(result).toEqual({ + data: 'test', + metadata: { + amount: 30, + currency: 'USD', + url: 'https//test.com', + 'restData.source': 'rudderStack', + }, + }); + }); +}); + +describe('searchContact utility test', () => { + it('Should successfully search contact by email', async () => { + const message = { context: { traits: { email: 'test@rudderlabs.com' } } }; + const destination = { Config: { apiKey: 'testApiKey', apiServer: 'us' } }; + axios.post.mockResolvedValue({ + status: 200, + data: { + type: 'list', + total_count: 1, + pages: { + type: 'pages', + page: 1, + per_page: 50, + total_pages: 1, + }, + data: [ + { + type: 'contact', + id: '1', + email: 'test@rudderlabs.com', + }, + ], + }, + }); + + const result = await searchContact(message, destination); + expect(result).toEqual('1'); + }); + + it('Should return first contact id if multiple contact exist with give search field', async () => { + const message = { + context: { + traits: { email: 'test@rudderlabs.com', phone: '+91 9999999999' }, + integrations: { INTERCOM: { lookup: 'phone' } }, + }, + }; + const destination = { Config: { apiKey: 'testApiKey', apiServer: 'us' } }; + axios.post.mockResolvedValue({ + status: 200, + data: { + type: 'list', + total_count: 1, + pages: { + type: 'pages', + page: 1, + per_page: 50, + total_pages: 1, + }, + data: [ + { + type: 'contact', + id: '1', + email: 'test@rudderlabs.com', + phone: '+91 9999999999', + }, + { + type: 'contact', + id: '2', + email: 'test+1@rudderlabs.com', + phone: '+91 9999999999', + }, + ], + }, + }); + + const result = await searchContact(message, destination); + expect(result).toEqual('1'); + }); + + it('Should return null if no contact is found', async () => { + const message = { + context: { + traits: { email: 'test+10@rudderlabs.com', phone: '+91 9999999999' }, + integrations: { INTERCOM: { lookup: 'email' } }, + }, + }; + const destination = { Config: { apiKey: 'testApiKey', apiServer: 'us' } }; + axios.post.mockResolvedValue({ + status: 200, + data: { + type: 'list', + total_count: 0, + pages: { + type: 'pages', + page: 1, + per_page: 50, + total_pages: 0, + }, + data: [], + }, + }); + + const result = await searchContact(message, destination); + expect(result).toBeNull(); + }); + + it('Should throw an error in case if axios calls returns an error', async () => { + const message = { + context: { + traits: { email: 'test+3@rudderlabs.com', phone: '+91 9999999999' }, + integrations: { INTERCOM: { lookup: 'email' } }, + }, + }; + const destination = { Config: { apiKey: 'invalidTestApiKey', apiServer: 'us' } }; + axios.post.mockRejectedValue({ + status: 401, + data: { + type: 'error.list', + request_id: 'request_400', + errors: [ + { + code: 'unauthorized', + message: 'Access Token Invalid', + }, + ], + }, + }); + + try { + const result = await searchContact(message, destination); + expect(result).toEqual(''); + } catch (error) { + expect(error.message).toEqual( + 'Unable to search contact due to : [{"code":"unauthorized","message":"Access Token Invalid"}]', + ); + } + }); +}); + +describe('createOrUpdateCompany utility test', () => { + it('Should successfully create company', async () => { + const payload = { + company_id: 'rudderlabs', + name: 'RudderStack', + website: 'www.rudderstack.com', + plan: 'enterprise', + size: 500, + industry: 'CDP', + custom_attributes: {}, + }; + const destination = { Config: { apiKey: 'testApiKey', apiServer: 'us' } }; + axios.post.mockResolvedValue({ + status: 200, + data: { + type: 'company', + company_id: 'rudderlabs', + id: '1', + name: 'RudderStack', + website: 'www.rudderstack.com', + plan: 'enterprise', + size: 500, + industry: 'CDP', + remote_created_at: 1374138000, + created_at: 1701930212, + updated_at: 1701930212, + }, + }); + + const result = await createOrUpdateCompany(payload, destination); + expect(result).toEqual('1'); + }); + + it('Should throw an error in case if axios calls returns an error', async () => { + const payload = { + company_id: 'rudderlabs', + name: 'RudderStack', + website: 'www.rudderstack.com', + plan: 'enterprise', + size: 500, + industry: 'CDP', + testData: true, + }; + const destination = { Config: { apiKey: 'testApiKey', apiServer: 'us' } }; + axios.post.mockRejectedValue({ + status: 400, + data: { + type: 'error.list', + request_id: 'request_400', + errors: [ + { + code: 'bad_request', + message: "bad 'testData' parameter", + }, + ], + }, + }); + + try { + const result = await createOrUpdateCompany(payload, destination); + expect(result).toEqual(''); + } catch (error) { + expect(error.message).toEqual( + 'Unable to Create or Update Company due to : [{"code":"bad_request","message":"bad \'testData\' parameter"}]', + ); + } + }); + + it('Should throw an error in case if axios calls returns an error', async () => { + const payload = { + company_id: 'rudderlabs', + name: 'RudderStack', + website: 'www.rudderstack.com', + plan: 'enterprise', + size: 500, + industry: 'CDP', + testData: true, + }; + const destination = { Config: { apiKey: 'invalidTestApiKey', apiServer: 'us' } }; + axios.post.mockRejectedValue({ + status: 400, + data: { + type: 'error.list', + request_id: 'request_400', + errors: [ + { + code: 'unauthorized', + message: 'Access Token Invalid', + }, + ], + }, + }); + + try { + const result = await createOrUpdateCompany(payload, destination); + expect(result).toEqual(''); + } catch (error) { + expect(error.message).toEqual( + 'Unable to Create or Update Company due to : [{"code":"unauthorized","message":"Access Token Invalid"}]', + ); + } + }); +}); + +describe('checkIfEmailOrUserIdPresent utility test', () => { + it('Should return true when userId is present in message', () => { + const message = { + userId: '12345', + context: { + traits: { + email: 'test@example.com', + }, + }, + }; + const Config = { + sendAnonymousId: true, + apiKey: '1234567890', + }; + const result = checkIfEmailOrUserIdPresent(message, Config); + expect(result).toBe(true); + }); + + it('Should return true when email is present in message', () => { + const message = { + context: { + traits: { + email: 'test@example.com', + }, + }, + }; + const Config = { + sendAnonymousId: true, + apiKey: '1234567890', + }; + const result = checkIfEmailOrUserIdPresent(message, Config); + expect(result).toBe(true); + }); + + it('Should return true when both userId and email are present in message', () => { + const message = { + userId: '12345', + context: { + traits: { + email: 'test@example.com', + }, + }, + }; + const Config = { + sendAnonymousId: true, + apiKey: '1234567890', + }; + const result = checkIfEmailOrUserIdPresent(message, Config); + expect(result).toBe(true); + }); + + it('Should return false when no email or userId is present', () => { + const message = { anonymousId: 'anon@123' }; + const Config = { + sendAnonymousId: false, + apiKey: '1234567890', + }; + const result = checkIfEmailOrUserIdPresent(message, Config); + expect(result).toBe(false); + }); +}); + +describe('getCompaniesList utility test', () => { + it('Should return an array with one object containing the company_id, custom_attributes, name and industry properties when the payload contains a company object with name or id properties', () => { + const payload = { + custom_attributes: { + company: { + name: 'rudderlabs', + industry: 'Tech', + }, + }, + }; + + const result = getCompaniesList(payload); + + expect(result).toEqual([ + { + company_id: md5('rudderlabs'), + custom_attributes: {}, + name: 'rudderlabs', + industry: 'Tech', + }, + ]); + }); + + it('Should return undefined when the payload does not contain a company object', () => { + const payload = {}; + const result = getCompaniesList(payload); + expect(result).toBeUndefined(); + }); + + it('Should return an empty array when the company object in the payload does not have name or id properties', () => { + const payload = { + custom_attributes: { + company: {}, + }, + }; + const result = getCompaniesList(payload); + expect(result).toEqual([]); + }); + + it('Should return an array with one object containing the company_id, custom_attributes, name and industry properties when the payload contains a company object with name and id properties', () => { + const payload = { + custom_attributes: { + company: { + name: 'Company A', + id: '123', + industry: 'Tech', + }, + }, + }; + const result = getCompaniesList(payload); + expect(result).toEqual([ + { + company_id: '123', + custom_attributes: {}, + name: 'Company A', + industry: 'Tech', + }, + ]); + }); +}); + +describe('attachUserAndCompany utility test', () => { + it('should return a valid response object when only email and groupId are present', () => { + const message = { + context: { + traits: { + email: 'test@example.com', + }, + }, + groupId: 'group123', + }; + const Config = { + sendAnonymousId: false, + apiKey: 'testApiKey', + }; + + const expectedResponse = { + method: 'POST', + params: {}, + type: 'REST', + version: '1', + endpoint: 'https://api.intercom.io/users', + files: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer testApiKey', + Accept: 'application/json', + 'Intercom-Version': '1.4', + }, + body: { + FORM: {}, + JSON: { + email: 'test@example.com', + companies: [ + { + company_id: 'group123', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + userId: undefined, + }; + const response = attachUserAndCompany(message, Config); + expect(response).toEqual(expectedResponse); + }); +}); diff --git a/src/cdk/v2/destinations/koala/procWorkflow.yaml b/src/cdk/v2/destinations/koala/procWorkflow.yaml new file mode 100644 index 00000000000..9ec0202b131 --- /dev/null +++ b/src/cdk/v2/destinations/koala/procWorkflow.yaml @@ -0,0 +1,65 @@ +bindings: + - name: EventType + path: ../../../../constants + - path: ../../bindings/jsontemplate + - name: defaultRequestConfig + path: ../../../../v0/util + +steps: + - name: validateInput + template: | + $.assert(.message.type, "message Type is not present. Aborting message"); + $.assert(.message.type in {{$.EventType.([.IDENTIFY, .TRACK])}}, + "message type " + .message.type + " is not supported"); + $.assertConfig(.destination.Config.publicKey, "publicKey is not present. Aborting message"); + $.context.email = .message.().({{{{$.getGenericPaths("emailOnly")}}}}); + $.context.ko_profile_id = .message.traits.ko_profile_id ?? .message.context.traits.ko_profile_id ?? .message.properties.ko_profile_id; + $.assert($.context.email || $.context.ko_profile_id, "Neither email or ko_profile_id are present on traits. Aborting message"); + - name: setMessageType + template: | + $.context.messageType = .message.type.toLowerCase(); + - name: preparePayloadForIdentify + condition: $.context.messageType === {{$.EventType.IDENTIFY}} + template: | + const traits = .message.traits ?? .message.context.traits ?? {}; + const koTraits = traits{~['ko_profile_id']} + const basePayload = { + email: $.context.email, + profile_id: $.context.ko_profile_id, + identifies: [{ + type: $.context.messageType, + sent_at: .message.().({{{{$.getGenericPaths("timestamp")}}}}), + traits: koTraits + }] + }; + + $.context.payload = basePayload + - name: preparePayloadForTrack + condition: $.context.messageType === {{$.EventType.TRACK}} + template: | + const properties = .message.properties ?? {}; + const koProperties = properties{~['ko_profile_id']} + const basePayload = { + ip: .message.context.ip ?? .message.request_ip, + email: $.context.email, + profile_id: $.context.ko_profile_id, + events: [{ + type: $.context.messageType, + event: .message.event, + message_id: .message.messageId, + sent_at: .message.().({{{{$.getGenericPaths("timestamp")}}}}), + properties: koProperties, + context: .message.context + }] + }; + + $.context.payload = basePayload + - name: buildResponseForProcessTransformation + template: | + const response = $.defaultRequestConfig(); + response.body.JSON = $.context.payload; + response.endpoint = "https://api2.getkoala.com/web/projects/" + .destination.Config.publicKey + "/batch"; + response.headers = { + "content-type": "application/json" + }; + response diff --git a/src/cdk/v2/destinations/koala/rtWorkflow.yaml b/src/cdk/v2/destinations/koala/rtWorkflow.yaml new file mode 100644 index 00000000000..335293b6dbc --- /dev/null +++ b/src/cdk/v2/destinations/koala/rtWorkflow.yaml @@ -0,0 +1,31 @@ +bindings: + - name: handleRtTfSingleEventError + path: ../../../../v0/util/index + +steps: + - name: validateInput + template: | + $.assert(Array.isArray(^) && ^.length > 0, "Invalid event array") + + - name: transform + externalWorkflow: + path: ./procWorkflow.yaml + loopOverInput: true + + - name: successfulEvents + template: | + $.outputs.transform#idx.output.({ + "batchedRequest": ., + "batched": false, + "destination": ^[idx].destination, + "metadata": ^[idx].metadata[], + "statusCode": 200 + })[] + - name: failedEvents + template: | + $.outputs.transform#idx.error.( + $.handleRtTfSingleEventError(^[idx], .originalError ?? ., {}) + )[] + - name: finalPayload + template: | + [...$.outputs.failedEvents, ...$.outputs.successfulEvents] diff --git a/src/cdk/v2/destinations/kochava/procWorkflow.yaml b/src/cdk/v2/destinations/kochava/procWorkflow.yaml index 557b1a0b630..3e73ee15206 100644 --- a/src/cdk/v2/destinations/kochava/procWorkflow.yaml +++ b/src/cdk/v2/destinations/kochava/procWorkflow.yaml @@ -10,7 +10,6 @@ bindings: - path: ../../bindings/jsontemplate - path: ./config.js - steps: - name: validateInput template: | diff --git a/src/cdk/v2/destinations/lytics/procWorkflow.yaml b/src/cdk/v2/destinations/lytics/procWorkflow.yaml index 1d6177fe09e..26221462213 100644 --- a/src/cdk/v2/destinations/lytics/procWorkflow.yaml +++ b/src/cdk/v2/destinations/lytics/procWorkflow.yaml @@ -45,7 +45,7 @@ steps: $.context.payload._e = .message.event; - name: pageOrScreenPayload condition: $.context.messageType === {{$.EventType.PAGE}} || - $.context.messageType === {{$.EventType.SCREEN}} + $.context.messageType === {{$.EventType.SCREEN}} template: | $.context.payload.event = .message.name - name: cleanPaylod @@ -66,4 +66,3 @@ steps: "Content-Type": "application/json" }; response - diff --git a/src/cdk/v2/destinations/movable_ink/config.js b/src/cdk/v2/destinations/movable_ink/config.js new file mode 100644 index 00000000000..673e94620ea --- /dev/null +++ b/src/cdk/v2/destinations/movable_ink/config.js @@ -0,0 +1,3 @@ +module.exports = { + MAX_REQUEST_SIZE_IN_BYTES: 13500, +}; diff --git a/src/cdk/v2/destinations/movable_ink/procWorkflow.yaml b/src/cdk/v2/destinations/movable_ink/procWorkflow.yaml new file mode 100644 index 00000000000..43dbb3cbce9 --- /dev/null +++ b/src/cdk/v2/destinations/movable_ink/procWorkflow.yaml @@ -0,0 +1,73 @@ +bindings: + - name: EventType + path: ../../../../constants + - path: ../../bindings/jsontemplate + - name: defaultRequestConfig + path: ../../../../v0/util + - name: toUnixTimestampInMS + path: ../../../../v0/util + - name: base64Convertor + path: ../../../../v0/util + - path: ./utils + +steps: + - name: messageType + template: | + .message.type.toLowerCase(); + + - name: validateInput + template: | + let messageType = $.outputs.messageType; + $.assert(messageType, "message Type is not present. Aborting"); + $.assert(messageType in {{$.EventType.([.IDENTIFY,.TRACK])}}, "message type " + messageType + " is not supported"); + $.assertConfig(.destination.Config.endpoint, "Movable Ink Endpoint is not present. Aborting"); + $.assertConfig(.destination.Config.accessKey, "Access key is not present . Aborting"); + $.assertConfig(.destination.Config.accessSecret, "Access Secret is not present. Aborting"); + $.assert(.message.timestamp ?? .message.originalTimestamp, "Timestamp is not present. Aborting"); + + const userId = .message.().( + {{{{$.getGenericPaths("userIdOnly")}}}}; + ); + const email = .message.().( + {{{{$.getGenericPaths("email")}}}}; + ); + + $.assert(userId ?? email ?? .message.anonymousId, "Either one of userId or email or anonymousId is required. Aborting"); + $.validateEventPayload(.message); + + - name: preparePayload + description: Prepare payload for identify and track. This payload schema needs to be configured in the Movable Ink dashboard. Movable Ink will discard any additional fields from the input payload. + template: | + const userId = .message.().( + {{{{$.getGenericPaths("userIdOnly")}}}}; + ); + const email = .message.().( + {{{{$.getGenericPaths("email")}}}}; + ); + const timestampInUnix = $.toUnixTimestampInMS(.message.().( + {{{{$.getGenericPaths("timestamp")}}}}; + )); + $.context.payload = { + ...(.message), + userId: userId ?? email, + timestamp: timestampInUnix, + anonymousId: .message.anonymousId + } + + - name: buildResponse + description: In batchMode we return payload directly + condition: $.batchMode + template: | + $.context.payload + else: + name: buildResponseForProcessTransformation + template: | + const response = $.defaultRequestConfig(); + response.body.JSON = $.context.payload; + response.endpoint = .destination.Config.endpoint; + response.method = "POST"; + response.headers = { + "Content-Type": "application/json", + "Authorization": "Basic " + $.base64Convertor(.destination.Config.accessKey + ":" + .destination.Config.accessSecret) + } + response; diff --git a/src/cdk/v2/destinations/movable_ink/rtWorkflow.yaml b/src/cdk/v2/destinations/movable_ink/rtWorkflow.yaml new file mode 100644 index 00000000000..46afb34d537 --- /dev/null +++ b/src/cdk/v2/destinations/movable_ink/rtWorkflow.yaml @@ -0,0 +1,74 @@ +bindings: + - name: handleRtTfSingleEventError + path: ../../../../v0/util/index + - path: ./utils + exportAll: true + - name: base64Convertor + path: ../../../../v0/util + - name: BatchUtils + path: '@rudderstack/workflow-engine' + - path: ./config + +steps: + - name: validateInput + template: | + $.assert(Array.isArray(^) && ^.length > 0, "Invalid event array") + + - name: transform + externalWorkflow: + path: ./procWorkflow.yaml + bindings: + - name: batchMode + value: true + loopOverInput: true + + - name: successfulEvents + template: | + $.outputs.transform#idx.output.({ + "batchedRequest": ., + "batched": false, + "destination": ^[idx].destination, + "metadata": ^[idx].metadata, + "statusCode": 200 + })[] + + - name: failedEvents + template: | + $.outputs.transform#idx.error.( + $.handleRtTfSingleEventError(^[idx], .originalError ?? ., {}) + )[] + + - name: batchSuccessfulEvents + description: Batches the successfulEvents + template: | + let batches = $.BatchUtils.chunkArrayBySizeAndLength( + $.outputs.successfulEvents, {maxSizeInBytes: $.MAX_REQUEST_SIZE_IN_BYTES}).items; + + batches@batch.({ + "batchedRequest": { + "body": { + "JSON": {"events": ~r batch.batchedRequest[]}, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": batch[0].destination.Config.().(.endpoint), + "headers": batch[0].destination.Config.().({ + "Content-Type": "application/json", + "Authorization": "Basic " + $.base64Convertor(.accessKey + ":" + .accessSecret) + }), + "params": {}, + "files": {} + }, + "metadata": ~r batch.metadata[], + "batched": true, + "statusCode": 200, + "destination": batch[0].destination + })[]; + + - name: finalPayload + template: | + [...$.outputs.batchSuccessfulEvents, ...$.outputs.failedEvents] diff --git a/src/cdk/v2/destinations/movable_ink/utils.js b/src/cdk/v2/destinations/movable_ink/utils.js new file mode 100644 index 00000000000..04d7046b1a3 --- /dev/null +++ b/src/cdk/v2/destinations/movable_ink/utils.js @@ -0,0 +1,21 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); + +const validateEventPayload = (message) => { + const { event } = message; + const { properties } = message; + if (event === 'Products Searched' && !properties?.query) { + throw new InstrumentationError("Missing 'query' property in properties. Aborting"); + } + + if ( + (event === 'Product Added' || + event === 'Product Removed' || + event === 'Product Viewed' || + event === 'Category Viewed') && + !properties?.product_id + ) { + throw new InstrumentationError("Missing 'product_id' property in properties. Aborting"); + } +}; + +module.exports = { validateEventPayload }; diff --git a/src/cdk/v2/destinations/ninetailed/config.js b/src/cdk/v2/destinations/ninetailed/config.js new file mode 100644 index 00000000000..c38496a4155 --- /dev/null +++ b/src/cdk/v2/destinations/ninetailed/config.js @@ -0,0 +1,31 @@ +const { getMappingConfig } = require('../../../../v0/util'); + +const ConfigCategories = { + GENERAL: { + type: 'general', + name: 'generalPayloadMapping', + }, + CONTEXT: { + type: 'context', + name: 'contextMapping', + }, + TRACK: { + type: 'track', + name: 'trackMapping', + }, + IDENTIFY: { + type: 'identify', + name: 'identifyMapping', + }, + PAGE: { + type: 'page', + name: 'pageMapping', + }, +}; + +// MAX_BATCH_SIZE : // Maximum number of events to send in a single batch +const mappingConfig = getMappingConfig(ConfigCategories, __dirname); +const batchEndpoint = + 'https://experience.ninetailed.co/v2/organizations/{{organisationId}}/environments/{{environment}}/events'; + +module.exports = { ConfigCategories, mappingConfig, batchEndpoint, MAX_BATCH_SIZE: 200 }; diff --git a/src/cdk/v2/destinations/ninetailed/data/contextMapping.json b/src/cdk/v2/destinations/ninetailed/data/contextMapping.json new file mode 100644 index 00000000000..f2373b61c15 --- /dev/null +++ b/src/cdk/v2/destinations/ninetailed/data/contextMapping.json @@ -0,0 +1,46 @@ +[ + { + "sourceKeys": "app.name", + "required": true, + "destKey": "app.name" + }, + { + "sourceKeys": "app.version", + "required": true, + "destKey": "app.version" + }, + { + "sourceKeys": "campaign", + "destKey": "campaign" + }, + { + "sourceKeys": "library.name", + "required": true, + "destKey": "library.name" + }, + { + "sourceKeys": "library.version", + "required": true, + "destKey": "library.version" + }, + { + "sourceKeys": "locale", + "destKey": "locale" + }, + { + "sourceKeys": "page", + "destKey": "page" + }, + { + "sourceKeys": "userAgent", + "destKey": "userAgent" + }, + { + "sourceKeys": "location", + "required": false, + "metadata": { + "defaultValue": {} + }, + "destKey": "location" + } +] diff --git a/src/cdk/v2/destinations/ninetailed/data/generalPayloadMapping.json b/src/cdk/v2/destinations/ninetailed/data/generalPayloadMapping.json new file mode 100644 index 00000000000..3ab72d1b9f4 --- /dev/null +++ b/src/cdk/v2/destinations/ninetailed/data/generalPayloadMapping.json @@ -0,0 +1,25 @@ +[ + { + "sourceKeys": "anonymousId", + "required": true, + "destKey": "anonymousId" + }, + { + "sourceKeys": "messageId", + "required": true, + "destKey": "messageId" + }, + { + "sourceKeys": "channel", + "required": true, + "destKey": "channel" + }, + { + "sourceKeys": "type", + "destKey": "type" + }, + { + "sourceKeys": "originalTimestamp", + "destKey": "originalTimestamp" + } +] diff --git a/src/cdk/v2/destinations/ninetailed/data/identifyMapping.json b/src/cdk/v2/destinations/ninetailed/data/identifyMapping.json new file mode 100644 index 00000000000..e8d3f7797d6 --- /dev/null +++ b/src/cdk/v2/destinations/ninetailed/data/identifyMapping.json @@ -0,0 +1,14 @@ +[ + { + "sourceKeys": "traits", + "sourceFromGenericMap": true, + "required": true, + "destKey": "traits" + }, + { + "sourceKeys": "userIdOnly", + "sourceFromGenericMap": true, + "required": true, + "destKey": "userId" + } +] diff --git a/src/cdk/v2/destinations/ninetailed/data/pageMapping.json b/src/cdk/v2/destinations/ninetailed/data/pageMapping.json new file mode 100644 index 00000000000..80ec2f58f12 --- /dev/null +++ b/src/cdk/v2/destinations/ninetailed/data/pageMapping.json @@ -0,0 +1,7 @@ +[ + { + "sourceKeys": "properties", + "required": true, + "destKey": "properties" + } +] diff --git a/src/cdk/v2/destinations/ninetailed/data/trackMapping.json b/src/cdk/v2/destinations/ninetailed/data/trackMapping.json new file mode 100644 index 00000000000..44af6dd1a34 --- /dev/null +++ b/src/cdk/v2/destinations/ninetailed/data/trackMapping.json @@ -0,0 +1,12 @@ +[ + { + "sourceKeys": "properties", + "required": true, + "destKey": "properties" + }, + { + "sourceKeys": "event", + "required": true, + "destKey": "event" + } +] diff --git a/src/cdk/v2/destinations/ninetailed/procWorkflow.yaml b/src/cdk/v2/destinations/ninetailed/procWorkflow.yaml new file mode 100644 index 00000000000..6f5056ce100 --- /dev/null +++ b/src/cdk/v2/destinations/ninetailed/procWorkflow.yaml @@ -0,0 +1,33 @@ +bindings: + - name: EventType + path: ../../../../constants + - path: ../../bindings/jsontemplate + - name: defaultRequestConfig + path: ../../../../v0/util + - name: removeUndefinedAndNullValues + path: ../../../../v0/util + - path: ./utils + +steps: + - name: messageType + template: | + .message.type.toLowerCase(); + - name: validateInput + template: | + let messageType = $.outputs.messageType; + $.assert(messageType, "message Type is not present. Aborting"); + $.assert(messageType in {{$.EventType.([.TRACK,.IDENTIFY,.PAGE])}}, "message type " + messageType + " is not supported"); + $.assertConfig(.destination.Config.organisationId, "Organisation ID is not present. Aborting"); + $.assertConfig(.destination.Config.environment, "Environment is not present. Aborting"); + - name: preparePayload + template: | + const payload = $.constructFullPayload(.message); + $.context.payload = $.removeUndefinedAndNullValues(payload); + + - name: buildResponse + template: | + const response = $.defaultRequestConfig(); + response.body.JSON.events = [$.context.payload]; + response.endpoint = $.getEndpoint(.destination.Config); + response.method = "POST"; + response diff --git a/src/cdk/v2/destinations/ninetailed/rtWorkflow.yaml b/src/cdk/v2/destinations/ninetailed/rtWorkflow.yaml new file mode 100644 index 00000000000..30dd3fdd95d --- /dev/null +++ b/src/cdk/v2/destinations/ninetailed/rtWorkflow.yaml @@ -0,0 +1,35 @@ +bindings: + - path: ./config + - name: handleRtTfSingleEventError + path: ../../../../v0/util/index + - path: ./utils +steps: + - name: validateInput + template: | + $.assert(Array.isArray(^) && ^.length > 0, "Invalid event array") + + - name: transform + externalWorkflow: + path: ./procWorkflow.yaml + loopOverInput: true + + - name: successfulEvents + template: | + $.outputs.transform#idx.output.({ + "output": .body.JSON.events[0], + "destination": ^[idx].destination, + "metadata": ^[idx].metadata + })[] + - name: failedEvents + template: | + $.outputs.transform#idx.error.( + $.handleRtTfSingleEventError(^[idx], .originalError ?? ., {}) + )[] + - name: batchSuccessfulEvents + description: Batches the successfulEvents + template: | + $.batchResponseBuilder($.outputs.successfulEvents); + + - name: finalPayload + template: | + [...$.outputs.failedEvents, ...$.outputs.batchSuccessfulEvents] diff --git a/src/cdk/v2/destinations/ninetailed/utils.js b/src/cdk/v2/destinations/ninetailed/utils.js new file mode 100644 index 00000000000..b716422a0e8 --- /dev/null +++ b/src/cdk/v2/destinations/ninetailed/utils.js @@ -0,0 +1,109 @@ +const { BatchUtils } = require('@rudderstack/workflow-engine'); +const config = require('./config'); +const { constructPayload } = require('../../../../v0/util'); + +/** + * This fucntion constructs payloads based upon mappingConfig for all calls + * We build context as it has some specific payloads with default values so just breaking them down + * @param {*} message + * @returns + */ +const constructFullPayload = (message) => { + const context = constructPayload( + message?.context || {}, + config.mappingConfig[config.ConfigCategories.CONTEXT.name], + ); + const payload = constructPayload( + message, + config.mappingConfig[config.ConfigCategories.GENERAL.name], + ); + let typeSpecifcPayload; + switch (message.type) { + case 'track': + typeSpecifcPayload = constructPayload( + message, + config.mappingConfig[config.ConfigCategories.TRACK.name], + ); + break; + case 'identify': + typeSpecifcPayload = constructPayload( + message, + config.mappingConfig[config.ConfigCategories.IDENTIFY.name], + ); + break; + case 'page': + typeSpecifcPayload = constructPayload( + message, + config.mappingConfig[config.ConfigCategories.PAGE.name], + ); + break; + default: + break; + } + payload.context = context; + return { ...payload, ...typeSpecifcPayload }; // merge base and type-specific payloads; +}; + +const getEndpoint = (Config) => { + const { organisationId, environment } = Config; + return config.batchEndpoint + .replace('{{organisationId}}', organisationId) + .replace('{{environment}}', environment); +}; + +const mergeMetadata = (batch) => { + const metadata = []; + batch.forEach((event) => { + metadata.push(event.metadata); + }); + return metadata; +}; + +const getMergedEvents = (batch) => { + const events = []; + batch.forEach((event) => { + events.push(event.output); + }); + return events; +}; + +const batchBuilder = (batch) => ({ + batchedRequest: { + body: { + JSON: { events: getMergedEvents(batch) }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: getEndpoint(batch[0].destination.Config), + headers: { + 'Content-Type': 'application/json', + }, + params: {}, + files: {}, + }, + metadata: mergeMetadata(batch), + batched: true, + statusCode: 200, + destination: batch[0].destination, +}); + +/** + * This fucntions make chunk of successful events based on MAX_BATCH_SIZE + * and then build the response for each chunk to be returned as object of an array + * @param {*} events + * @returns + */ +const batchResponseBuilder = (events) => { + const batches = BatchUtils.chunkArrayBySizeAndLength(events, { maxItems: config.MAX_BATCH_SIZE }); + const response = []; + batches.items.forEach((batch) => { + response.push(batchBuilder(batch)); + }); + return response; +}; + +module.exports = { constructFullPayload, getEndpoint, batchResponseBuilder }; diff --git a/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml b/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml index 8a956e905ca..1122a80404c 100644 --- a/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml +++ b/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml @@ -246,4 +246,4 @@ steps: }, "params": $.outputs.checkSendTestEventConfig, "files": {} - })[] \ No newline at end of file + })[] diff --git a/src/cdk/v2/destinations/pinterest_tag/rtWorkflow.yaml b/src/cdk/v2/destinations/pinterest_tag/rtWorkflow.yaml index 227942dfea8..215ead12b12 100644 --- a/src/cdk/v2/destinations/pinterest_tag/rtWorkflow.yaml +++ b/src/cdk/v2/destinations/pinterest_tag/rtWorkflow.yaml @@ -12,7 +12,7 @@ steps: If sendTestEvent is enabled, we send test event to the destination ref: https://help.pinterest.com/en/business/article/track-conversions-with-the-conversions-api template: | - ^[0].destination.Config.sendAsTestEvent ? {"test": true} : {} + ^[0].destination.Config.sendAsTestEvent ? {"test": true} : {} - name: transform externalWorkflow: diff --git a/src/cdk/v2/destinations/rakuten/config.js b/src/cdk/v2/destinations/rakuten/config.js new file mode 100644 index 00000000000..6a4c93ea3ab --- /dev/null +++ b/src/cdk/v2/destinations/rakuten/config.js @@ -0,0 +1,34 @@ +const { getMappingConfig } = require('../../../../v0/util'); + +const ConfigCategories = { + TRACK: { + type: 'track', + name: 'propertiesMapping', + }, +}; +const mappingConfig = getMappingConfig(ConfigCategories, __dirname); +// Following contains the keys at item level mapping where key can be considered as destkey and value can be considered as sourcekey +const productProperties = { + skulist: 'sku', + qlist: 'quantity', + namelist: 'name', + brandlist: 'brand', + couponlist: 'coupon', + catidlist: 'categoryId', + catlist: 'category', + disamtlist: 'discountAmount', + distypelist: 'discountType', + isclearancelist: 'isClearance', + ismarketplacelist: 'isMarketPlace', + issalelist: 'isSale', + itmstatuslist: 'itmStatus', + marginlist: 'margin', + markdownlist: 'markdown', + shipidlist: 'shipId', + shipbylist: 'shipBy', + taxexemptlist: 'taxExempt', + sequencelist: 'sequence', +}; +// list of all properties that are required +const requiredProductProperties = ['skulist', 'qlist', 'namelist']; +module.exports = { ConfigCategories, mappingConfig, productProperties, requiredProductProperties }; diff --git a/src/cdk/v2/destinations/rakuten/data/propertiesMapping.json b/src/cdk/v2/destinations/rakuten/data/propertiesMapping.json new file mode 100644 index 00000000000..db5d36fc4d1 --- /dev/null +++ b/src/cdk/v2/destinations/rakuten/data/propertiesMapping.json @@ -0,0 +1,141 @@ +[ + { + "sourceKeys": ["properties.order_id", "properties.orderId"], + "required": true, + "destKey": "ord" + }, + { + "sourceKeys": ["properties.tr", "properties.ran_site_id", "properties.ranSiteID"], + "required": true, + "destKey": "tr" + }, + { + "sourceKeys": ["properties.land", "properties.land_time", "properties.landTime"], + "required": true, + "destKey": "land" + }, + { + "sourceKeys": [ + "properties.date", + "properties.order_completed_time", + "properties.orderCompletedTime" + ], + "destKey": "date" + }, + { + "sourceKeys": [ + "properties.alt_ord", + "properties.altord", + "properties.alter_order_id", + "properties.alterOrderId" + ], + "destKey": "altord" + }, + { + "sourceKeys": "properties.currency", + "destKey": "cur" + }, + { + "sourceKeys": ["properties.credit_card_type", "properties.creditCardType"], + "destKey": "cc" + }, + { + "sourceKeys": ["properties.comm_reason", "properties.commReason"], + "destKey": "commreason" + }, + { + "sourceKeys": ["properties.is_comm", "properties.isComm"], + "destKey": "iscomm" + }, + { + "sourceKeys": "properties.consumed", + "destKey": "consumed" + }, + { + "sourceKeys": "properties.coupon", + "destKey": "coupon" + }, + { + "sourceKeys": [ + "properties.cust_id", + "properties.custId", + "properties.customer_id", + "properties.customerId", + "properties.userId" + ], + "destKey": "custid" + }, + { + "sourceKeys": [ + "properties.cust_score", + "properties.custScore", + "properties.customer_score", + "properties.customerScore" + ], + "destKey": "custscore" + }, + { + "sourceKeys": [ + "properties.cust_status", + "properties.custStatus", + "properties.customer_status", + "properties.customerStatus" + ], + "destKey": "custstatus" + }, + { + "sourceKeys": ["properties.dId", "properties.advertising_id", "properties.advertisingId"], + "destKey": "did" + }, + { + "sourceKeys": ["properties.disamt", "properties.discount_amount", "properties.discountAmount"], + "destKey": "disamt" + }, + { + "sourceKeys": [ + "properties.ord_status", + "properties.ordStatus", + "properties.order_status", + "properties.orderStatus" + ], + "destKey": "ordstatus" + }, + { + "sourceKeys": "properties.segment", + "destKey": "segment" + }, + { + "sourceKeys": ["properties.ship_country", "properties.shipcountry"], + "destKey": "shipcountry" + }, + { + "sourceKeys": "properties.shipped", + "destKey": "shipped" + }, + { + "sourceKeys": [ + "properties.site_name", + "properties.sitename", + "properties.url", + "context.page.url" + ], + "destKey": "sitename" + }, + { + "sourceKeys": ["properties.store_id", "properties.storeId"], + "destKey": "storeid" + }, + { + "sourceKeys": [ + "properties.store_cat", + "properties.storecat", + "properties.store_category", + "properties.storeCategory" + ], + "destKey": "storecat" + }, + { + "sourceKeys": "properties.currency", + "destKey": "cur" + } +] diff --git a/src/cdk/v2/destinations/rakuten/procWorkflow.yaml b/src/cdk/v2/destinations/rakuten/procWorkflow.yaml new file mode 100644 index 00000000000..b4dcacfa092 --- /dev/null +++ b/src/cdk/v2/destinations/rakuten/procWorkflow.yaml @@ -0,0 +1,39 @@ +bindings: + - name: EventType + path: ../../../../constants + - path: ../../bindings/jsontemplate + - name: defaultRequestConfig + path: ../../../../v0/util + - name: removeUndefinedAndNullValues + path: ../../../../v0/util + - path: ./utils + +steps: + - name: messageType + template: | + .message.type.toLowerCase(); + - name: validateInput + template: | + let messageType = $.outputs.messageType; + $.assert(messageType, "message Type is not present. Aborting"); + $.assert(messageType in {{$.EventType.([.TRACK])}}, "message type " + messageType + " is not supported"); + $.assertConfig(.destination.Config.mid, "Merchant ID is not present. Aborting"); + - name: prepareTrackPayload + condition: $.outputs.messageType === {{$.EventType.TRACK}} + template: | + const properties = $.constructProperties(.message); + const lineItems = $.constructLineItems(.message.properties) + $.context.payload = {...properties,...lineItems,xml:1,source:'rudderstack', mid:.destination.Config.mid} + $.context.payload = $.removeUndefinedAndNullValues($.context.payload); + + - name: buildResponse + template: | + const response = $.defaultRequestConfig(); + response.params = $.context.payload; + response.method = "GET"; + response.endpoint = "https://track.linksynergy.com/ep"; + response.headers = { + "accept": "application/json", + "content-type": "application/json" + }; + response diff --git a/src/cdk/v2/destinations/rakuten/utils.js b/src/cdk/v2/destinations/rakuten/utils.js new file mode 100644 index 00000000000..ef6b197db7a --- /dev/null +++ b/src/cdk/v2/destinations/rakuten/utils.js @@ -0,0 +1,70 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); +const { isDefinedAndNotNull } = require('rudder-transformer-cdk/build/utils'); +const { + mappingConfig, + ConfigCategories, + productProperties, + requiredProductProperties, +} = require('./config'); +const { constructPayload } = require('../../../../v0/util'); + +/** + * This fucntion constructs payloads based upon mappingConfig for Track call type + * @param {*} message + * @returns + */ +const constructProperties = (message) => { + const payload = constructPayload(message, mappingConfig[ConfigCategories.TRACK.name]); + return payload; +}; + +/** + * This fucntion build the item level list + * @param {*} properties + * @returns + */ +const constructLineItems = (properties) => { + // Validate the existence and non-emptiness of the 'products' array in 'properties' + if (!Array.isArray(properties?.products) || properties.products.length === 0) { + throw new InstrumentationError('Either properties.product is not an array or is empty'); + } + + const { products } = properties; + const productList = {}; + + // Iterate over product properties to construct the payload + Object.keys(productProperties).forEach((property) => { + const propertyKey = productProperties[property]; + + // Extract values for the current property from the 'products' array + const values = products.map((product) => + isDefinedAndNotNull(product?.[propertyKey]) ? product[propertyKey] : '', + ); + + // Validate if a required property is missing + if (requiredProductProperties.includes(property) && values.includes('')) { + throw new InstrumentationError(`${propertyKey} is a required field. Aborting`); + } + + // Include property in the payload if values are non-empty + if (values.some((element) => element !== '')) { + productList[property] = values.join('|'); + } + }); + + // Map 'amountList' by evaluating 'amount' or deriving it from 'price' and 'quantity' + const amountList = products.map((product) => { + if (!product?.amount && !product?.price) { + throw new InstrumentationError('Either amount or price is required for every product'); + } + + if (product.price) { + return product.quantity * product.price * 100; + } + return product.amount * 100; + }); + productList.amtlist = amountList.join('|'); + return productList; +}; + +module.exports = { constructProperties, constructLineItems }; diff --git a/src/cdk/v2/destinations/rakuten/utils.test.js b/src/cdk/v2/destinations/rakuten/utils.test.js new file mode 100644 index 00000000000..9cc7f5fd4cc --- /dev/null +++ b/src/cdk/v2/destinations/rakuten/utils.test.js @@ -0,0 +1,117 @@ +const { constructLineItems } = require('./utils'); +describe('constructLineItems', () => { + it('should return a non-empty object when given a valid properties object with at least one product', () => { + const properties = { + products: [ + { + name: 'Product 1', + sku: 'sku_1', + price: 10, + quantity: 2, + amount: 20, + }, + ], + }; + const result = constructLineItems(properties); + const expectedObj = { + namelist: 'Product 1', + skulist: 'sku_1', + qlist: '2', + amtlist: '2000', + }; + expect(result).toEqual(expectedObj); + }); + + it('should include all mapped properties in the returned object when present in at least one product', () => { + const properties = { + products: [ + { + name: 'Product 1', + category: 'Category 1', + sku: 'sku_1', + brand: 'Brand 1', + price: 10, + quantity: 2, + amount: 20, + }, + ], + }; + + const result = constructLineItems(properties); + + const expectedObj = { + namelist: 'Product 1', + catlist: 'Category 1', + skulist: 'sku_1', + brandlist: 'Brand 1', + qlist: '2', + amtlist: '2000', + }; + expect(result).toEqual(expectedObj); + }); + + it('should include amtlist property in the returned object with calculated values', () => { + const properties = { + products: [ + { + name: 'Product 1', + sku: 'sku_1', + price: 10, + quantity: 2, + }, + { + name: 'Product 2', + sku: 'sku_2', + price: 5, + quantity: 3, + }, + ], + }; + + const result = constructLineItems(properties); + + expect(result).toHaveProperty('amtlist'); + expect(result.amtlist).toBe('2000|1500'); + }); + + it('should throw an InstrumentationError when properties object is missing or has an empty products array', () => { + const properties = {}; + + expect(() => constructLineItems(properties)).toThrow( + 'Either properties.product is not an array or is empty', + ); + + properties.products = []; + + expect(() => constructLineItems(properties)).toThrow( + 'Either properties.product is not an array or is empty', + ); + }); + it('should throw an InstrumentationError when a product is missing quantity property', () => { + const properties = { + products: [ + { + name: 'Product 1', + sku: 'sku_1', + amount: '1234', + }, + ], + }; + expect(() => constructLineItems(properties)).toThrow('quantity is a required field. Aborting'); + }); + it('should throw an InstrumentationError when a product is missing both amount and price properties', () => { + const properties = { + products: [ + { + name: 'Product 1', + sku: 'sku_1', + quantity: 2, + }, + ], + }; + + expect(() => constructLineItems(properties)).toThrow( + 'Either amount or price is required for every product', + ); + }); +}); diff --git a/src/cdk/v2/destinations/reddit/procWorkflow.yaml b/src/cdk/v2/destinations/reddit/procWorkflow.yaml index 65b466bc7cc..59725c1257a 100644 --- a/src/cdk/v2/destinations/reddit/procWorkflow.yaml +++ b/src/cdk/v2/destinations/reddit/procWorkflow.yaml @@ -56,13 +56,15 @@ steps: const event_type = (eventNames.length === 0 || eventNames[0]==="") ? ({"tracking_type": "Custom", "custom_event_name": event}): ({tracking_type: eventNames[0]}); - name: customFields - condition: $.outputs.eventType.tracking_type === "Purchase" + condition: $.outputs.prepareTrackPayload.eventType.tracking_type === "Purchase" + reference: 'https://ads-api.reddit.com/docs/v2/#tag/Conversions/paths/~1api~1v2.0~1conversions~1events~1%7Baccount_id%7D/post' template: | + const revenue_in_cents = .message.properties.revenue ? Math.round(Number(.message.properties.revenue)*100) const customFields = .message.().({ "currency": .properties.currency, - "value": .properties.revenue !== undefined ? Number(.properties.revenue) : undefined, + "value_decimal": revenue_in_cents ? revenue_in_cents / 100, "item_count": (Array.isArray(.properties.products) && .properties.products.length) || (.properties.itemCount && Number(.properties.itemCount)), - "value_decimal": .properties.revenue !== undefined ? Number(.properties.revenue)/100 : undefined, + "value": revenue_in_cents, "conversion_id": .properties.conversionId || .messageId, }); $.removeUndefinedAndNullValues(customFields) diff --git a/src/cdk/v2/destinations/sprig/procWorkflow.yaml b/src/cdk/v2/destinations/sprig/procWorkflow.yaml index 18b46913fd6..4dcebeffcda 100644 --- a/src/cdk/v2/destinations/sprig/procWorkflow.yaml +++ b/src/cdk/v2/destinations/sprig/procWorkflow.yaml @@ -69,5 +69,3 @@ steps: "authorization": "API-Key " + .destination.Config.apiKey }; response - - diff --git a/src/cdk/v2/destinations/statsig/procWorkflow.yaml b/src/cdk/v2/destinations/statsig/procWorkflow.yaml index b3c85e31dcf..6d3328b87e2 100644 --- a/src/cdk/v2/destinations/statsig/procWorkflow.yaml +++ b/src/cdk/v2/destinations/statsig/procWorkflow.yaml @@ -26,4 +26,3 @@ steps: "content-type": "application/json" }; response - diff --git a/src/cdk/v2/destinations/the_trade_desk/config.js b/src/cdk/v2/destinations/the_trade_desk/config.js index 9455c818fdd..300325223b3 100644 --- a/src/cdk/v2/destinations/the_trade_desk/config.js +++ b/src/cdk/v2/destinations/the_trade_desk/config.js @@ -1,8 +1,9 @@ -const SUPPORTED_EVENT_TYPE = 'record'; +const SUPPORTED_EVENT_TYPE = ['record']; const ACTION_TYPES = ['insert', 'delete']; const DATA_PROVIDER_ID = 'rudderstack'; // ref:- https://partner.thetradedesk.com/v3/portal/data/doc/DataEnvironments +// api ref:- https://partner.thetradedesk.com/v3/portal/data/doc/post-data-advertiser-external const DATA_SERVERS_BASE_ENDPOINTS_MAP = { apac: 'https://sin-data.adsrvr.org', tokyo: 'https://tok-data.adsrvr.org', diff --git a/src/cdk/v2/destinations/the_trade_desk/rtWorkflow.yaml b/src/cdk/v2/destinations/the_trade_desk/rtWorkflow.yaml index 0c8963e0ac7..5f0476dd624 100644 --- a/src/cdk/v2/destinations/the_trade_desk/rtWorkflow.yaml +++ b/src/cdk/v2/destinations/the_trade_desk/rtWorkflow.yaml @@ -1,17 +1,41 @@ bindings: - - name: processRouterDest - path: ./utils + - name: EventType + path: ../../../../constants + - name: processRecordInputs + path: ./transformRecord + - name: handleRtTfSingleEventError + path: ../../../../v0/util/index + - name: InstrumentationError + path: '@rudderstack/integrations-lib' steps: - - name: validateInput + - name: validateConfig template: | - $.assert(Array.isArray(^) && ^.length > 0, "Invalid event array") const config = ^[0].destination.Config - $.assertConfig(config.audienceId, "Segment name is not present. Aborting") + $.assertConfig(config.audienceId, "Segment name/Audience ID is not present. Aborting") $.assertConfig(config.advertiserId, "Advertiser ID is not present. Aborting") $.assertConfig(config.advertiserSecretKey, "Advertiser Secret Key is not present. Aborting") config.ttlInDays ? $.assertConfig(config.ttlInDays >=0 && config.ttlInDays <= 180, "TTL is out of range. Allowed values are 0 to 180 days") - - name: processRouterDest + - name: validateInput + template: | + $.assert(Array.isArray(^) && ^.length > 0, "Invalid event array") + + - name: processRecordEvents + template: | + $.processRecordInputs(^.{.message.type === $.EventType.RECORD}[], ^[0].destination) + + - name: failOtherEvents + template: | + const otherEvents = ^.{.message.type !== $.EventType.RECORD}[] + let failedEvents = otherEvents.map( + function(event) { + const error = new $.InstrumentationError("Event type " + event.message.type + " is not supported"); + $.handleRtTfSingleEventError(event, error, {}) + } + ) + failedEvents ?? [] + + - name: finalPayload template: | - $.processRouterDest(^) + [...$.outputs.processRecordEvents, ...$.outputs.failOtherEvents] diff --git a/src/cdk/v2/destinations/the_trade_desk/transformRecord.js b/src/cdk/v2/destinations/the_trade_desk/transformRecord.js new file mode 100644 index 00000000000..b452f8d7bc7 --- /dev/null +++ b/src/cdk/v2/destinations/the_trade_desk/transformRecord.js @@ -0,0 +1,97 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); +const { BatchUtils } = require('@rudderstack/workflow-engine'); +const { + defaultPostRequestConfig, + defaultRequestConfig, + getSuccessRespEvents, + removeUndefinedAndNullValues, + handleRtTfSingleEventError, + isEmptyObject, +} = require('../../../../v0/util'); +const { getTTLInMin, getFirstPartyEndpoint } = require('./utils'); +const tradeDeskConfig = require('./config'); + +const { DATA_PROVIDER_ID } = tradeDeskConfig; + +const responseBuilder = (items, config) => { + const { advertiserId, dataServer } = config; + + const payload = { DataProviderId: DATA_PROVIDER_ID, AdvertiserId: advertiserId, Items: items }; + + const response = defaultRequestConfig(); + response.endpoint = getFirstPartyEndpoint(dataServer); + response.method = defaultPostRequestConfig.requestMethod; + response.body.JSON = removeUndefinedAndNullValues(payload); + return response; +}; + +const batchResponseBuilder = (items, config) => { + const response = []; + const itemsChunks = BatchUtils.chunkArrayBySizeAndLength(items, { + // TODO: use destructuring at the top of file once proper 'mocking' is implemented. + // eslint-disable-next-line unicorn/consistent-destructuring + maxSizeInBytes: tradeDeskConfig.MAX_REQUEST_SIZE_IN_BYTES, + }); + + itemsChunks.items.forEach((chunk) => { + response.push(responseBuilder(chunk, config)); + }); + + return response; +}; + +const processRecordInputs = (inputs, destination) => { + const { Config } = destination; + const items = []; + const successMetadata = []; + const errorResponseList = []; + + if (!inputs || inputs.length === 0) { + return []; + } + + const invalidActionTypeError = new InstrumentationError( + 'Invalid action type. You can only add or remove IDs from the audience/segment', + ); + const emptyFieldsError = new InstrumentationError('`fields` cannot be empty'); + inputs.forEach((input) => { + const { fields, action } = input.message; + const isInsertOrDelete = action === 'insert' || action === 'delete'; + + if (!isInsertOrDelete) { + errorResponseList.push(handleRtTfSingleEventError(input, invalidActionTypeError, {})); + return; + } + + if (isEmptyObject(fields)) { + errorResponseList.push(handleRtTfSingleEventError(input, emptyFieldsError, {})); + return; + } + + successMetadata.push(input.metadata); + const data = [ + { + Name: Config.audienceId, + TTLInMinutes: action === 'insert' ? getTTLInMin(Config.ttlInDays) : 0, + }, + ]; + + Object.keys(fields).forEach((id) => { + const value = fields[id]; + if (value) { + // adding only non empty ID's + items.push({ [id]: value, Data: data }); + } + }); + }); + + const payloads = batchResponseBuilder(items, Config); + if (payloads.length === 0) { + return errorResponseList; + } + + const response = getSuccessRespEvents(payloads, successMetadata, destination, true); + return [response, ...errorResponseList]; +}; + +module.exports = { processRecordInputs }; diff --git a/src/cdk/v2/destinations/the_trade_desk/utils.js b/src/cdk/v2/destinations/the_trade_desk/utils.js index 632442d74e5..71b479438cb 100644 --- a/src/cdk/v2/destinations/the_trade_desk/utils.js +++ b/src/cdk/v2/destinations/the_trade_desk/utils.js @@ -1,23 +1,19 @@ -const lodash = require('lodash'); const CryptoJS = require('crypto-js'); -const { InstrumentationError, AbortedError } = require('@rudderstack/integrations-lib'); -const { BatchUtils } = require('@rudderstack/workflow-engine'); -const { - defaultPostRequestConfig, - defaultRequestConfig, - getSuccessRespEvents, - removeUndefinedAndNullValues, - handleRtTfSingleEventError, - isEmptyObject, -} = require('../../../../v0/util'); -const tradeDeskConfig = require('./config'); +const { AbortedError } = require('@rudderstack/integrations-lib'); +const { DATA_SERVERS_BASE_ENDPOINTS_MAP } = require('./config'); -const { DATA_PROVIDER_ID, DATA_SERVERS_BASE_ENDPOINTS_MAP } = tradeDeskConfig; - -const ttlInMin = (ttl) => parseInt(ttl, 10) * 1440; +const getTTLInMin = (ttl) => parseInt(ttl, 10) * 1440; const getBaseEndpoint = (dataServer) => DATA_SERVERS_BASE_ENDPOINTS_MAP[dataServer]; const getFirstPartyEndpoint = (dataServer) => `${getBaseEndpoint(dataServer)}/data/advertiser`; +/** + * Generates a signature header for a given request using a secret key. + * + * @param {Object} request - The request object to generate the signature for. + * @param {string} secretKey - The secret key used to generate the signature. + * @returns {string} - The generated signature header. + * @throws {AbortedError} - If the secret key is missing. + */ const getSignatureHeader = (request, secretKey) => { if (!secretKey) { throw new AbortedError('Secret key is missing. Aborting'); @@ -27,92 +23,8 @@ const getSignatureHeader = (request, secretKey) => { return base; }; -const responseBuilder = (items, config) => { - const { advertiserId, dataServer } = config; - - const payload = { DataProviderId: DATA_PROVIDER_ID, AdvertiserId: advertiserId, Items: items }; - - const response = defaultRequestConfig(); - response.endpoint = getFirstPartyEndpoint(dataServer); - response.method = defaultPostRequestConfig.requestMethod; - response.body.JSON = removeUndefinedAndNullValues(payload); - return response; -}; - -const batchResponseBuilder = (items, config) => { - const response = []; - const itemsChunks = BatchUtils.chunkArrayBySizeAndLength(items, { - // TODO: use destructuring at the top of file once proper 'mocking' is implemented. - // eslint-disable-next-line unicorn/consistent-destructuring - maxSizeInBytes: tradeDeskConfig.MAX_REQUEST_SIZE_IN_BYTES, - }); - - itemsChunks.items.forEach((chunk) => { - response.push(responseBuilder(chunk, config)); - }); - - return response; +module.exports = { + getTTLInMin, + getFirstPartyEndpoint, + getSignatureHeader, }; - -const processRecordInputs = (inputs, destination) => { - const { Config } = destination; - const items = []; - const successMetadata = []; - const errorResponseList = []; - - const invalidActionTypeError = new InstrumentationError('Invalid action type'); - const emptyFieldsError = new InstrumentationError('Fields cannot be empty'); - - inputs.forEach((input) => { - const { fields, action } = input.message; - const isInsertOrDelete = action === 'insert' || action === 'delete'; - - if (!isInsertOrDelete) { - errorResponseList.push(handleRtTfSingleEventError(input, invalidActionTypeError, {})); - return; - } - - if (isEmptyObject(fields)) { - errorResponseList.push(handleRtTfSingleEventError(input, emptyFieldsError, {})); - return; - } - - successMetadata.push(input.metadata); - const data = [ - { - Name: Config.audienceId, - TTLInMinutes: action === 'insert' ? ttlInMin(Config.ttlInDays) : 0, - }, - ]; - - Object.keys(fields).forEach((id) => { - const value = fields[id]; - if (value) { - // adding only non empty ID's - items.push({ [id]: value, Data: data }); - } - }); - }); - - const payloads = batchResponseBuilder(items, Config); - if (payloads.length === 0) { - return errorResponseList; - } - - const response = getSuccessRespEvents(payloads, successMetadata, destination, true); - return [response, ...errorResponseList]; -}; - -const processRouterDest = (inputs) => { - const respList = []; - const { destination } = inputs[0]; - const groupedInputs = lodash.groupBy(inputs, (input) => input.message.type); - if (groupedInputs.record) { - const transformedRecordEvent = processRecordInputs(groupedInputs.record, destination); - respList.push(...transformedRecordEvent); - } - - return respList; -}; - -module.exports = { getSignatureHeader, processRouterDest }; diff --git a/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/config.js b/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/config.js new file mode 100644 index 00000000000..7af732185f9 --- /dev/null +++ b/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/config.js @@ -0,0 +1,63 @@ +const { getMappingConfig } = require('../../../../v0/util'); + +const SUPPORTED_EVENT_TYPE = ['track']; + +// ref:- https://partner.thetradedesk.com/v3/portal/data/doc/DataConversionEventsApi +const REAL_TIME_CONVERSION_ENDPOINT = 'https://insight.adsrvr.org/track/realtimeconversion'; + +const CONVERSION_SUPPORTED_ID_TYPES = [ + 'TDID', + 'IDFA', + 'AAID', + 'DAID', + 'NAID', + 'IDL', + 'EUID', + 'UID2', +]; + +const ECOMM_EVENT_MAP = { + 'product added': { + event: 'addtocart', + rootLevelPriceSupported: true, + }, + 'order completed': { + event: 'purchase', + itemsArray: true, + revenueFieldSupported: true, + }, + 'product viewed': { + event: 'viewitem', + rootLevelPriceSupported: true, + }, + 'checkout started': { + event: 'startcheckout', + itemsArray: true, + revenueFieldSupported: true, + }, + 'cart viewed': { + event: 'viewcart', + itemsArray: true, + }, + 'product added to wishlist': { + event: 'wishlistitem', + rootLevelPriceSupported: true, + }, +}; + +const CONFIG_CATEGORIES = { + COMMON_CONFIGS: { name: 'TTDCommonConfig' }, + ITEM_CONFIGS: { name: 'TTDItemConfig' }, +}; + +const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); + +module.exports = { + SUPPORTED_EVENT_TYPE, + CONFIG_CATEGORIES, + CONVERSION_SUPPORTED_ID_TYPES, + COMMON_CONFIGS: MAPPING_CONFIG[CONFIG_CATEGORIES.COMMON_CONFIGS.name], + ITEM_CONFIGS: MAPPING_CONFIG[CONFIG_CATEGORIES.ITEM_CONFIGS.name], + ECOMM_EVENT_MAP, + REAL_TIME_CONVERSION_ENDPOINT, +}; diff --git a/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/data/TTDCommonConfig.json b/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/data/TTDCommonConfig.json new file mode 100644 index 00000000000..848d16b4058 --- /dev/null +++ b/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/data/TTDCommonConfig.json @@ -0,0 +1,22 @@ +[ + { + "destKey": "currency", + "sourceKeys": "properties.currency" + }, + { + "destKey": "client_ip", + "sourceKeys": ["context.ip", "request_ip"] + }, + { + "destKey": "referrer_url", + "sourceKeys": "context.page.referrer" + }, + { + "destKey": "imp", + "sourceKeys": "messageId" + }, + { + "destKey": "order_id", + "sourceKeys": "properties.order_id" + } +] diff --git a/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/data/TTDItemConfig.json b/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/data/TTDItemConfig.json new file mode 100644 index 00000000000..45aeb711ab5 --- /dev/null +++ b/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/data/TTDItemConfig.json @@ -0,0 +1,22 @@ +[ + { + "destKey": "item_code", + "sourceKeys": ["product_id", "sku"] + }, + { + "destKey": "name", + "sourceKeys": "name" + }, + { + "destKey": "qty", + "sourceKeys": "quantity" + }, + { + "destKey": "price", + "sourceKeys": "price" + }, + { + "destKey": "cat", + "sourceKeys": "category_id" + } +] diff --git a/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/procWorkflow.yaml b/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/procWorkflow.yaml new file mode 100644 index 00000000000..5191320cdc1 --- /dev/null +++ b/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/procWorkflow.yaml @@ -0,0 +1,59 @@ +bindings: + - name: EventType + path: ../../../../constants + - path: ../../bindings/jsontemplate + - name: defaultRequestConfig + path: ../../../../v0/util + - name: removeUndefinedAndNullValues + path: ../../../../v0/util + - path: ./config + exportAll: true + - path: ./utils + exportAll: true + +steps: + - name: validateConfig + template: | + $.assertConfig(.destination.Config.advertiserId, "Advertiser ID is not present. Aborting") + $.assertConfig(.destination.Config.trackerId, "Tracking Tag ID is not present. Aborting") + + - name: validateInput + template: | + let messageType = .message.type; + $.assert(messageType, "message Type is not present. Aborting."); + $.assert(messageType.toLowerCase() === $.EventType.TRACK, "Event type " + messageType + " is not supported"); + $.assert(.message.event, "Event is not present. Aborting."); + + - name: prepareTrackPayload + template: | + const configPayload = $.prepareFromConfig(.destination); + const commonPayload = $.prepareCommonPayload(.message); + const { id, type } = $.getAdvertisingId(.message); + const items = $.prepareItemsPayload(.message); + const customProperties = $.prepareCustomProperties(.message, .destination); + const eventName = $.populateEventName(.message, .destination); + const value = $.getRevenue(.message); + let payload = { + ...configPayload, + ...commonPayload, + event_name: eventName, + value, + items, + adid: id, + adid_type: type, + ...customProperties, + data_processing_option: $.getDataProcessingOptions(.message), + privacy_settings: $.getPrivacySetting(.message), + }; + payload = $.enrichTrackPayload(.message, payload); + payload; + + - name: buildResponseForProcessTransformation + template: | + const response = $.defaultRequestConfig(); + response.body.JSON = {data: [$.removeUndefinedAndNullValues($.outputs.prepareTrackPayload)]}; + response.endpoint = $.REAL_TIME_CONVERSION_ENDPOINT; + response.headers = { + "Content-Type": "application/json" + }; + response; diff --git a/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/utils.js b/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/utils.js new file mode 100644 index 00000000000..2232be61f06 --- /dev/null +++ b/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/utils.js @@ -0,0 +1,315 @@ +const lodash = require('lodash'); +const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); +const { + constructPayload, + getHashFromArray, + isDefinedAndNotNull, + isAppleFamily, + getIntegrationsObj, + extractCustomFields, + generateExclusionList, +} = require('../../../../v0/util'); +const { + CONVERSION_SUPPORTED_ID_TYPES, + COMMON_CONFIGS, + ITEM_CONFIGS, + ECOMM_EVENT_MAP, +} = require('./config'); + +const prepareCommonPayload = (message) => constructPayload(message, COMMON_CONFIGS); + +const prepareFromConfig = (destination) => ({ + tracker_id: destination.Config?.trackerId, + adv: destination.Config?.advertiserId, +}); + +/** + * Calculates the revenue based on the given message. + * + * @param {Object} message - The message object containing the event and properties. + * @returns {number} - The calculated revenue. + * @throws {InstrumentationError} - If the event is 'Order Completed' and revenue is not provided. + */ +const getRevenue = (message) => { + const { event, properties } = message; + let revenue = properties?.value; + const eventsMapInfo = ECOMM_EVENT_MAP[event.toLowerCase()]; + if (eventsMapInfo?.rootLevelPriceSupported) { + const { price, quantity = 1 } = properties; + if (price && !Number.isNaN(parseFloat(price)) && !Number.isNaN(parseInt(quantity, 10))) { + revenue = parseFloat(price) * parseInt(quantity, 10); + } + } else if (eventsMapInfo?.revenueFieldSupported) { + revenue = properties?.revenue || revenue; + if (event.toLowerCase() === 'order completed' && !revenue) { + throw new InstrumentationError('value is required for `Order Completed` event'); + } + } + + return revenue; +}; + +/** + * Generates items from properties of a given message. + * + * @param {Object} message - The message object containing properties. + * @returns {Array} - An array of items generated from the properties. + */ +const prepareItemsFromProperties = (message) => { + const { properties } = message; + const items = []; + const item = constructPayload(properties, ITEM_CONFIGS); + items.push(item); + return items; +}; + +/** + * Generates items payload from products. + * + * @param {Object} message - The message object. + * @returns {Array} - The items payload. + */ +const prepareItemsFromProducts = (message) => { + const products = get(message, 'properties.products'); + const items = []; + products.forEach((product) => { + const item = constructPayload(product, ITEM_CONFIGS); + const itemExclusionList = generateExclusionList(ITEM_CONFIGS); + extractCustomFields(product, item, 'root', itemExclusionList); + items.push(item); + }); + return items; +}; + +/** + * Generates items payload from root properties or products. + * + * @param {Object} message - The message object containing event and properties. + * @returns {Array} - The array of items payload. + */ +const prepareItemsPayload = (message) => { + const { event } = message; + let items; + const eventMapInfo = ECOMM_EVENT_MAP[event.toLowerCase()]; + if (eventMapInfo?.itemsArray) { + // if event is one of the supported ecommerce events and products array is present + items = prepareItemsFromProducts(message); + } else if (eventMapInfo) { + // if event is one of the supported ecommerce events and products array is not present + items = prepareItemsFromProperties(message); + } + return items; +}; + +/** + * Retrieves the device advertising ID and type based on the provided message. + * + * @param {Object} message - The message object containing the context. + * @returns {Object} - An object containing the device advertising ID and type. + */ +const getDeviceAdvertisingId = (message) => { + const { context } = message; + const deviceId = context?.device?.advertisingId; + const osName = context?.os?.name?.toLowerCase(); + + let type; + switch (osName) { + case 'android': + type = 'AAID'; + break; + case 'windows': + type = 'NAID'; + break; + default: + type = isAppleFamily(osName) ? 'IDFA' : undefined; + break; + } + + return { deviceId, type }; +}; + +/** + * Retrieves the external ID object from the given message context. + * + * @param {Object} message - The message object containing the context. + * @returns {Object|undefined} - The external ID object, or undefined if not found. + */ +const getDestinationExternalIDObject = (message) => { + const { context } = message; + const externalIdArray = context?.externalId || []; + + let externalIdObj; + + if (Array.isArray(externalIdArray)) { + externalIdObj = externalIdArray.find( + (extIdObj) => + CONVERSION_SUPPORTED_ID_TYPES.includes(extIdObj?.type?.toUpperCase()) && extIdObj?.id, + ); + } + return externalIdObj; +}; + +/** + * Retrieves the advertising ID and type from the given message. + * + * @param {Object} message - The message object containing the context. + * @returns {Object} - An object containing the advertising ID and type. + * If the advertising ID and type are found in the device context, they are returned. + * If not, the external ID object is checked and if found, its ID and type are returned. + * If neither the device context nor the external ID object contain the required information, + * an object with null values for ID and type is returned. + */ +const getAdvertisingId = (message) => { + const { deviceId, type } = getDeviceAdvertisingId(message); + if (deviceId && type) { + return { id: deviceId, type }; + } + const externalIdObj = getDestinationExternalIDObject(message); + if (externalIdObj?.id && externalIdObj?.type) { + return { id: externalIdObj.id, type: externalIdObj.type.toUpperCase() }; + } + + return { id: null, type: null }; +}; + +/** + * Prepares custom properties (td1-td10) for a given message and destination. + * + * @param {object} message - The message object. + * @param {object} destination - The destination object. + * @returns {object} - The prepared payload object. + */ +const prepareCustomProperties = (message, destination) => { + const { customProperties } = destination.Config; + const payload = {}; + if (customProperties) { + customProperties.forEach((customProperty) => { + const { rudderProperty, tradeDeskProperty } = customProperty; + const value = get(message, rudderProperty); + if (value) { + payload[tradeDeskProperty] = value; + // unset the rudder property from the message, since it is already mapped to a trade desk property + lodash.unset(message, rudderProperty); + } + }); + } + return payload; +}; + +/** + * Retrieves the event name based on the provided message and destination. + * + * @param {object} message - The message object containing the event. + * @param {object} destination - The destination object containing the events mapping configuration. + * @returns {string} - The event name. + */ +const populateEventName = (message, destination) => { + let eventName; + const { event } = message; + const { eventsMapping } = destination.Config; + + // if event is mapped on dashboard, use the mapped event name + if (Array.isArray(eventsMapping) && eventsMapping.length > 0) { + const keyMap = getHashFromArray(eventsMapping, 'from', 'to'); + eventName = keyMap[event.toLowerCase()]; + } + + if (eventName) { + return eventName; + } + + // if event is one of the supported ecommerce events, use the mapped trade desk event name + const eventMapInfo = ECOMM_EVENT_MAP[event.toLowerCase()]; + if (isDefinedAndNotNull(eventMapInfo)) { + return eventMapInfo.event; + } + + // else return the event name as it is + return event; +}; + +/** + * Retrieves the data processing options based on the provided message. + * + * @param {string} message - The message to process. + * @throws {InstrumentationError} - Throws an error if the region is not supported, if no policies are provided, if multiple policies are provided, or if the policy is not supported. + * @returns {Object} - The data processing options, including the policies and region. + */ +const getDataProcessingOptions = (message) => { + const integrationObj = getIntegrationsObj(message, 'THE_TRADE_DESK') || {}; + let { policies } = integrationObj; + const { region } = integrationObj; + let dataProcessingOptions; + + if (region && !region.toLowerCase().startsWith('us')) { + throw new InstrumentationError('Only US states are supported'); + } + + if (!policies || (Array.isArray(policies) && policies.length === 0)) { + policies = ['LDU']; + } + + if (policies.length > 1) { + throw new InstrumentationError('Only one policy is allowed'); + } + + if (policies[0] !== 'LDU') { + throw new InstrumentationError('Only LDU policy is supported'); + } + + if (policies && region) { + dataProcessingOptions = { policies, region }; + } + + return dataProcessingOptions; +}; + +const getPrivacySetting = (message) => { + const integrationObj = getIntegrationsObj(message, 'THE_TRADE_DESK'); + return integrationObj?.privacy_settings; +}; + +/** + * Enriches the track payload with extra properties present in 'properties' other than the ones defined in TTDCommonConfig.json and TTDItemConfig.json + * + * @param {Object} message - The message object containing the event information. + * @param {Object} payload - The payload object to be enriched. + * @returns {Object} - The enriched payload object. + */ +const enrichTrackPayload = (message, payload) => { + let rawPayload = { ...payload }; + const eventsMapInfo = ECOMM_EVENT_MAP[message.event.toLowerCase()]; + // checking if event is an ecomm one and itemsArray/products support is not present. e.g Product Added event + if (eventsMapInfo && !eventsMapInfo.itemsArray) { + const itemExclusionList = generateExclusionList(ITEM_CONFIGS); + rawPayload = extractCustomFields(message, rawPayload, ['properties'], itemExclusionList); + } else if (eventsMapInfo) { + // for ecomm events with products array supports. e.g Order Completed event + rawPayload = extractCustomFields( + message, + rawPayload, + ['properties'], + ['products', 'revenue', 'value'], + ); + } else { + // for custom events + rawPayload = extractCustomFields(message, rawPayload, ['properties'], ['value']); + } + return rawPayload; +}; + +module.exports = { + prepareFromConfig, + getRevenue, + prepareCommonPayload, + prepareItemsPayload, + getDeviceAdvertisingId, + getDestinationExternalIDObject, + getAdvertisingId, + prepareCustomProperties, + populateEventName, + getDataProcessingOptions, + getPrivacySetting, + enrichTrackPayload, +}; diff --git a/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/utils.test.js b/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/utils.test.js new file mode 100644 index 00000000000..20b39fab937 --- /dev/null +++ b/src/cdk/v2/destinations/the_trade_desk_real_time_conversions/utils.test.js @@ -0,0 +1,621 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); +const { + getRevenue, + getDeviceAdvertisingId, + getDestinationExternalIDObject, + getAdvertisingId, + prepareCustomProperties, + populateEventName, + getDataProcessingOptions, + getPrivacySetting, + enrichTrackPayload, +} = require('./utils'); + +describe('getRevenue', () => { + it('should return revenue value from message properties for custom events', () => { + const message = { + event: 'customEvent', + properties: { + value: 100, + }, + }; + const result = getRevenue(message); + expect(result).toBe(100); + }); + + it('should calculate revenue based on price and quantity from message properties if ecomm event is supported for price calculation', () => { + const message = { + event: 'Product Added', + properties: { + price: 10, + quantity: 5, + }, + }; + const result = getRevenue(message); + expect(result).toBe(50); + }); + + it('should return revenue value from message properties if ecomm event is supported for revenue calculation', () => { + const message = { + event: 'Order Completed', + properties: { + revenue: 200, + }, + }; + const result = getRevenue(message); + expect(result).toBe(200); + }); + + it('should return default revenue value from properties.value for ecomm events', () => { + let message = { + event: 'Product Added', + properties: { + price: '', + value: 200, + }, + }; + let result = getRevenue(message); + expect(result).toBe(200); + + message = { + event: 'Order Completed', + properties: { + value: 200, + }, + }; + result = getRevenue(message); + expect(result).toBe(200); + }); + + it('should throw an Instrumentation error if revenue is missing for `Order Completed` event', () => { + const message = { + event: 'Order Completed', + properties: {}, + }; + expect(() => { + getRevenue(message); + }).toThrow(InstrumentationError); + }); +}); + +describe('getDeviceAdvertisingId', () => { + it('should return an object with deviceId and type properties when context.device.advertisingId and context.os.name are present', () => { + let message = { + context: { + device: { + advertisingId: '123456789', + }, + os: { + name: 'android', + }, + }, + }; + let result = getDeviceAdvertisingId(message); + expect(result).toEqual({ deviceId: '123456789', type: 'AAID' }); + + message = { + context: { + device: { + advertisingId: '123456789', + }, + os: { + name: 'ios', + }, + }, + }; + result = getDeviceAdvertisingId(message); + expect(result).toEqual({ deviceId: '123456789', type: 'IDFA' }); + + message = { + context: { + device: { + advertisingId: '123456789', + }, + os: { + name: 'windows', + }, + }, + }; + result = getDeviceAdvertisingId(message); + expect(result).toEqual({ deviceId: '123456789', type: 'NAID' }); + }); + + it('should return an object with undefined type property when osName is not "android", "windows", or an Apple OS', () => { + const message = { + context: { + device: { + advertisingId: '123456789', + }, + os: { + name: 'linux', + }, + }, + }; + const result = getDeviceAdvertisingId(message); + expect(result).toEqual({ deviceId: '123456789', type: undefined }); + }); + + it('should return an object with undefined deviceId and type properties when context is undefined', () => { + let message = {}; + let result = getDeviceAdvertisingId(message); + expect(result).toEqual({ deviceId: undefined, type: undefined }); + + message = { + context: {}, + }; + result = getDeviceAdvertisingId(message); + expect(result).toEqual({ deviceId: undefined, type: undefined }); + + message = { + context: { + device: {}, + }, + }; + result = getDeviceAdvertisingId(message); + expect(result).toEqual({ deviceId: undefined, type: undefined }); + }); +}); + +describe('getDestinationExternalIDObject', () => { + it('should return the external ID object when it exists in the message context', () => { + const message = { + context: { + externalId: [ + { id: '123', type: 'daid' }, + { id: '456', type: 'type123' }, + ], + }, + }; + const result = getDestinationExternalIDObject(message); + expect(result).toEqual({ id: '123', type: 'daid' }); + }); + + it('should return undefined when no external ID object exists in the message context', () => { + let message = { + context: { + externalId: [], + }, + }; + let result = getDestinationExternalIDObject(message); + expect(result).toBeUndefined(); + + message = { + context: {}, + }; + result = getDestinationExternalIDObject(message); + expect(result).toBeUndefined(); + }); + + it('should return the first matching external ID object in the array', () => { + const message = { + context: { + externalId: [ + { id: '', type: 'daid' }, + { id: '456', type: 'tdid' }, + { id: '789', type: 'UID2' }, + ], + }, + }; + const result = getDestinationExternalIDObject(message); + expect(result).toEqual({ id: '456', type: 'tdid' }); + }); +}); + +describe('getAdvertisingId', () => { + it('should return an object with the ID and type when the message contains a valid device advertising ID and OS type', () => { + const message = { + context: { + device: { + advertisingId: '1234567890', + }, + os: { + name: 'android', + }, + }, + }; + + const result = getAdvertisingId(message); + expect(result).toEqual({ id: '1234567890', type: 'AAID' }); + }); + + it('should return an object with the ID and type when the message contains a valid external ID object with a supported type', () => { + const message = { + context: { + externalId: [ + { + type: 'IDFA', + id: 'abcdefg', + }, + ], + }, + }; + + const result = getAdvertisingId(message); + expect(result).toEqual({ id: 'abcdefg', type: 'IDFA' }); + }); + + it('should return an object with undefined ID and type when the message contains a valid external ID object with an unsupported type', () => { + let message = { + context: { + externalId: [ + { + type: 'unsupported', + id: '1234567890', + }, + ], + }, + }; + + let result = getAdvertisingId(message); + expect(result).toEqual({ id: null, type: null }); + + message = { + context: { + device: { + advertisingId: '1234567890', + }, + }, + }; + + result = getAdvertisingId(message); + expect(result).toEqual({ id: null, type: null }); + }); + + it('should return an object with undefined ID and type when the message contains an external ID object with a supported type but no ID or missing externalId', () => { + let message = { + context: { + externalId: [ + { + type: 'IDFA', + }, + ], + }, + }; + let result = getAdvertisingId(message); + expect(result).toEqual({ id: null, type: null }); + + message = { + context: {}, + }; + result = getAdvertisingId(message); + expect(result).toEqual({ id: null, type: null }); + }); +}); + +describe('prepareCustomProperties', () => { + it('should return an empty object when customProperties is an empty array', () => { + const message = {}; + let destination = { Config: { customProperties: [] } }; + let result = prepareCustomProperties(message, destination); + expect(result).toEqual({}); + + destination = { Config: { customProperties: [{ rudderProperty: '', tradeDeskProperty: '' }] } }; + result = prepareCustomProperties(message, destination); + expect(result).toEqual({}); + + destination = { Config: { customProperties: undefined } }; + result = prepareCustomProperties(message, destination); + expect(result).toEqual({}); + }); + + it('should return an object with `tradeDeskProperty` as key and `rudderProperty` value as value when `rudderProperty` exists in message', () => { + const message = { + rudderProperty1: 'value1', + rudderProperty2: 'value2', + }; + const destination = { + Config: { + customProperties: [ + { + rudderProperty: 'rudderProperty1', + tradeDeskProperty: 'tradeDeskProperty1', + }, + { + rudderProperty: 'rudderProperty2', + tradeDeskProperty: 'tradeDeskProperty2', + }, + { + rudderProperty: 'rudderProperty3', + tradeDeskProperty: 'tradeDeskProperty3', + }, + ], + }, + }; + const result = prepareCustomProperties(message, destination); + expect(result).toEqual({ + tradeDeskProperty1: 'value1', + tradeDeskProperty2: 'value2', + }); + }); +}); + +describe('populateEventName', () => { + it('should return the eventName if it exists in the eventsMapping of destination.Config', () => { + const message = { event: 'someEvent' }; + const destination = { Config: { eventsMapping: [{ from: 'someEvent', to: 'mappedEvent' }] } }; + const result = populateEventName(message, destination); + expect(result).toBe('mappedEvent'); + }); + + it('should return the eventName if it exists in the ECOMM_EVENT_MAP', () => { + const message = { event: 'product added' }; + let destination = { Config: { eventsMapping: [{ from: 'someEvent', to: 'mappedEvent' }] } }; + let result = populateEventName(message, destination); + expect(result).toBe('addtocart'); + + destination = { Config: { eventsMapping: [] } }; + result = populateEventName(message, destination); + expect(result).toBe('addtocart'); + }); + + it('should return undefined if eventsMapping is an empty array', () => { + const message = { event: 'someEvent' }; + const destination = { Config: { eventsMapping: [] } }; + const result = populateEventName(message, destination); + expect(result).toBe('someEvent'); + }); +}); + +describe('getDataProcessingOptions', () => { + it('should return an object with policies and region when provided a integrationObj in message', () => { + const message = { + integrations: { + All: true, + THE_TRADE_DESK: { + policies: ['LDU'], + region: 'US-CO', + }, + }, + }; + const expected = { + policies: ['LDU'], + region: 'US-CO', + }; + const result = getDataProcessingOptions(message); + expect(result).toEqual(expected); + }); + + it('should throw an InstrumentationError if the region is not a US state', () => { + const message = { + integrations: { + All: true, + THE_TRADE_DESK: { + policies: ['LDU'], + region: 'EU-abc', + }, + }, + }; + expect(() => { + getDataProcessingOptions(message); + }).toThrow(InstrumentationError); + }); + + it('should throw an InstrumentationError if multiple policies are provided', () => { + const message = { + integrations: { + All: true, + THE_TRADE_DESK: { + policies: ['LDU', 'Policy2'], + region: 'US-CO', + }, + }, + }; + + expect(() => { + getDataProcessingOptions(message); + }).toThrow(InstrumentationError); + }); + + it('should throw an InstrumentationError if a policy other than `LDU` is provided', () => { + const message = { + integrations: { + All: true, + THE_TRADE_DESK: { + policies: ['Policy1'], + region: 'US-CO', + }, + }, + }; + + expect(() => { + getDataProcessingOptions(message); + }).toThrow(InstrumentationError); + }); + + it('should return an object with default policy `LDU` when policies are not provided', () => { + const message = { + integrations: { + All: true, + THE_TRADE_DESK: { + policies: [], + region: 'US-CO', + }, + }, + }; + + const expected = { + policies: ['LDU'], + region: 'US-CO', + }; + + expect(getDataProcessingOptions(message)).toEqual(expected); + }); + + it('should handle empty cases', () => { + let message = { + integrations: { + All: true, + THE_TRADE_DESK: {}, + }, + }; + + expect(getDataProcessingOptions(message)).toBeUndefined(); + + message = { + integrations: { + All: true, + }, + }; + + expect(getDataProcessingOptions(message)).toBeUndefined(); + + message = { + integrations: { + All: true, + THE_TRADE_DESK: { region: 'US-CO' }, + }, + }; + + expect(getDataProcessingOptions(message)).toEqual({ policies: ['LDU'], region: 'US-CO' }); + }); +}); + +describe('getPrivacySetting', () => { + it('should return the privacy settings object when it exists in the integration object', () => { + const message = { + integrations: { + All: true, + THE_TRADE_DESK: { + privacy_settings: [ + { + privacy_type: 'GDPR', + is_applicable: 1, + consent_string: 'ok', + }, + ], + }, + }, + }; + const expected = [ + { + privacy_type: 'GDPR', + is_applicable: 1, + consent_string: 'ok', + }, + ]; + const result = getPrivacySetting(message); + expect(result).toEqual(expected); + }); + + it('should return null when the privacy settings object does not exist in the integration object', () => { + let message = { integrations: {} }; + expect(getPrivacySetting(message)).toBeUndefined(); + + message = { integrations: { THE_TRADE_DESK: {} } }; + expect(getPrivacySetting(message)).toBeUndefined(); + + message = { integrations: { THE_TRADE_DESK: { privacy_settings: null } } }; + expect(getPrivacySetting(message)).toBeNull(); + }); +}); + +describe('enrichTrackPayload', () => { + it('should correctly enrich the payload with custom fields for ecomm events where product array is not supported', () => { + const message = { + event: 'Product Added', + properties: { + product_id: 'prd123', + sku: 'sku123', + brand: 'brand123', + property1: 'value1', + property2: 'value2', + }, + }; + const payload = { + items: [ + { + item_code: 'prd123', + }, + ], + property1: 'value1', + property2: 'value2', + }; + const expectedPayload = { + items: [ + { + item_code: 'prd123', + }, + ], + brand: 'brand123', + property1: 'value1', + property2: 'value2', + }; + + const result = enrichTrackPayload(message, payload); + expect(result).toEqual(expectedPayload); + }); + + it('should correctly enrich the payload with custom fields when the for ecomm events with products array support', () => { + const message = { + event: 'order completed', + properties: { + order_id: 'ord123', + total: 52.0, + subtotal: 45.0, + revenue: 50.0, + products: [{ product_id: 'prd123', sku: 'sku123', brand: 'brand123' }], + property1: 'value1', + property2: 'value2', + }, + }; + const payload = { + order_id: 'ord123', + value: 50.0, + items: [{ item_code: 'prd123', brand: 'brand123' }], + property1: 'value1', + property2: 'value2', + }; + const expectedPayload = { + order_id: 'ord123', + total: 52.0, + subtotal: 45.0, + value: 50.0, + items: [{ item_code: 'prd123', brand: 'brand123' }], + property1: 'value1', + property2: 'value2', + }; + + const result = enrichTrackPayload(message, payload); + + expect(result).toEqual(expectedPayload); + }); + + it('should return the enriched payload for custom event', () => { + const message = { + event: 'someEvent', + properties: { + order_id: 'ord123', + property1: 'value1', + property2: 'value2', + revenue: 10, + value: 11, + products: [ + { + product_id: 'prd123', + test: 'test', + }, + ], + }, + }; + const payload = { + order_id: 'ord123', + value: 11, + }; + const expectedPayload = { + order_id: 'ord123', + property1: 'value1', + property2: 'value2', + revenue: 10, + value: 11, + products: [ + { + product_id: 'prd123', + test: 'test', + }, + ], + }; + + const result = enrichTrackPayload(message, payload); + expect(result).toEqual(expectedPayload); + }); +}); diff --git a/src/cdk/v2/destinations/tiktok_audience/procWorkflow.yaml b/src/cdk/v2/destinations/tiktok_audience/procWorkflow.yaml index cd84ecbc876..5862fbf3724 100644 --- a/src/cdk/v2/destinations/tiktok_audience/procWorkflow.yaml +++ b/src/cdk/v2/destinations/tiktok_audience/procWorkflow.yaml @@ -1,4 +1,3 @@ - bindings: - name: EventType path: ../../../../constants @@ -48,7 +47,6 @@ steps: "action": $.ACTION_MAP[action], })[] - - name: buildResponseForProcessTransformation description: build response template: | diff --git a/src/cdk/v2/destinations/zapier/procWorkflow.yaml b/src/cdk/v2/destinations/zapier/procWorkflow.yaml index 82d15cdec0f..9f1512836ea 100644 --- a/src/cdk/v2/destinations/zapier/procWorkflow.yaml +++ b/src/cdk/v2/destinations/zapier/procWorkflow.yaml @@ -44,4 +44,3 @@ steps: "content-type": "application/json" }; response - diff --git a/src/cdk/v2/handler.ts b/src/cdk/v2/handler.ts index 47d6d101797..edd14e72988 100644 --- a/src/cdk/v2/handler.ts +++ b/src/cdk/v2/handler.ts @@ -50,16 +50,20 @@ export async function getWorkflowEngine( const workflowEnginePromiseMap = new Map(); -export function getCachedWorkflowEngine( +export async function getCachedWorkflowEngine( destName: string, feature: string, bindings: Record = {}, -): WorkflowEngine { +): Promise { // Create a new instance of the engine for the destination if needed // TODO: Use cache to avoid long living engine objects workflowEnginePromiseMap[destName] = workflowEnginePromiseMap[destName] || new Map(); if (!workflowEnginePromiseMap[destName][feature]) { - workflowEnginePromiseMap[destName][feature] = getWorkflowEngine(destName, feature, bindings); + workflowEnginePromiseMap[destName][feature] = await getWorkflowEngine( + destName, + feature, + bindings, + ); } return workflowEnginePromiseMap[destName][feature]; } @@ -97,5 +101,8 @@ export function executeStep( ): Promise { return workflowEngine .getStepExecutor(stepName) - .execute(input, Object.assign(workflowEngine.bindings, getEmptyExecutionBindings(), bindings)); + .execute( + input, + Object.assign(workflowEngine.getBindings(), getEmptyExecutionBindings(), bindings), + ); } diff --git a/src/constants/destinationCanonicalNames.js b/src/constants/destinationCanonicalNames.js index d1e199c9e2d..b84aff1089d 100644 --- a/src/constants/destinationCanonicalNames.js +++ b/src/constants/destinationCanonicalNames.js @@ -141,6 +141,30 @@ const DestCanonicalNames = { 'TWITTER_ADS', ], BRAZE: ['BRAZE', 'Braze', 'braze'], + THE_TRADE_DESK: [ + 'THE_TRADE_DESK', + 'the_trade_desk', + 'The_Trade_Desk', + 'The Trade Desk', + 'thetradedesk', + 'theTradeDesk', + 'TheTradeDesk', + 'the trade desk', + ], + INTERCOM: ['INTERCOM', 'intercom', 'Intercom'], + GOOGLE_ADWORDS_REMARKETING_LISTS: [ + 'GOOGLE_ADWORDS_REMARKETING_LISTS', + 'google_adwords_remarketing_lists', + 'Google Adwords Remarketing Lists', + 'google adwords remarketing lists', + ], + GOOGLE_ADWORDS_OFFLINE_CONVERSIONS: [ + 'GOOGLE_ADWORDS_OFFLINE_CONVERSIONS', + 'google_adwords_offline_conversions', + 'Google Adwords Offline Conversions', + 'google adwords offline conversions', + ], + koala: ['Koala', 'koala', 'KOALA'], }; module.exports = { DestHandlerMap, DestCanonicalNames }; diff --git a/src/constants/index.js b/src/constants/index.js index a8976bc07e2..f8ca53a94c9 100644 --- a/src/constants/index.js +++ b/src/constants/index.js @@ -6,6 +6,7 @@ const EventType = { ALIAS: 'alias', GROUP: 'group', RESET: 'reset', + RECORD: 'record', }; const Address = { diff --git a/src/controllers/__tests__/delivery.test.ts b/src/controllers/__tests__/delivery.test.ts new file mode 100644 index 00000000000..0f91913f9d0 --- /dev/null +++ b/src/controllers/__tests__/delivery.test.ts @@ -0,0 +1,186 @@ +import request from 'supertest'; +import { createHttpTerminator } from 'http-terminator'; +import Koa from 'koa'; +import bodyParser from 'koa-bodyparser'; +import { applicationRoutes } from '../../routes'; +import { NativeIntegrationDestinationService } from '../../services/destination/nativeIntegration'; +import { ServiceSelector } from '../../helpers/serviceSelector'; + +let server: any; +const OLD_ENV = process.env; + +beforeAll(async () => { + process.env = { ...OLD_ENV }; // Make a copy + const app = new Koa(); + app.use( + bodyParser({ + jsonLimit: '200mb', + }), + ); + applicationRoutes(app); + server = app.listen(9090); +}); + +afterAll(async () => { + process.env = OLD_ENV; // Restore old environment + const httpTerminator = createHttpTerminator({ + server, + }); + await httpTerminator.terminate(); +}); + +afterEach(() => { + jest.clearAllMocks(); +}); + +const getData = () => { + return { body: { JSON: { a: 'b' } }, metadata: [{ a1: 'b1' }], destinationConfig: { a2: 'b2' } }; +}; + +describe('Delivery controller tests', () => { + describe('Delivery V0 tests', () => { + test('successful delivery', async () => { + const testOutput = { status: 200, message: 'success' }; + const mockDestinationService = new NativeIntegrationDestinationService(); + mockDestinationService.deliver = jest + .fn() + .mockImplementation((event, destinationType, requestMetadata, version) => { + expect(event).toEqual(getData()); + expect(destinationType).toEqual('__rudder_test__'); + expect(version).toEqual('v0'); + return testOutput; + }); + const getNativeDestinationServiceSpy = jest + .spyOn(ServiceSelector, 'getNativeDestinationService') + .mockImplementation(() => { + return mockDestinationService; + }); + + const response = await request(server) + .post('/v0/destinations/__rudder_test__/proxy') + .set('Accept', 'application/json') + .send(getData()); + + expect(response.status).toEqual(200); + expect(response.body).toEqual({ output: testOutput }); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getNativeDestinationServiceSpy).toHaveBeenCalledTimes(1); + expect(mockDestinationService.deliver).toHaveBeenCalledTimes(1); + }); + + test('delivery failure', async () => { + const mockDestinationService = new NativeIntegrationDestinationService(); + mockDestinationService.deliver = jest + .fn() + .mockImplementation((event, destinationType, requestMetadata, version) => { + expect(event).toEqual(getData()); + expect(destinationType).toEqual('__rudder_test__'); + expect(version).toEqual('v0'); + throw new Error('test error'); + }); + const getNativeDestinationServiceSpy = jest + .spyOn(ServiceSelector, 'getNativeDestinationService') + .mockImplementation(() => { + return mockDestinationService; + }); + + const response = await request(server) + .post('/v0/destinations/__rudder_test__/proxy') + .set('Accept', 'application/json') + .send(getData()); + + const expectedResp = { + output: { + message: 'test error', + statTags: { + errorCategory: 'transformation', + }, + destinationResponse: '', + status: 500, + }, + }; + expect(response.status).toEqual(500); + expect(response.body).toEqual(expectedResp); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getNativeDestinationServiceSpy).toHaveBeenCalledTimes(1); + expect(mockDestinationService.deliver).toHaveBeenCalledTimes(1); + }); + }); + + describe('Delivery V1 tests', () => { + test('successful delivery', async () => { + const testOutput = { status: 200, message: 'success' }; + const mockDestinationService = new NativeIntegrationDestinationService(); + mockDestinationService.deliver = jest + .fn() + .mockImplementation((event, destinationType, requestMetadata, version) => { + expect(event).toEqual(getData()); + expect(destinationType).toEqual('__rudder_test__'); + expect(version).toEqual('v1'); + return testOutput; + }); + const getNativeDestinationServiceSpy = jest + .spyOn(ServiceSelector, 'getNativeDestinationService') + .mockImplementation(() => { + return mockDestinationService; + }); + + const response = await request(server) + .post('/v1/destinations/__rudder_test__/proxy') + .set('Accept', 'application/json') + .send(getData()); + + expect(response.status).toEqual(200); + expect(response.body).toEqual({ output: testOutput }); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getNativeDestinationServiceSpy).toHaveBeenCalledTimes(1); + expect(mockDestinationService.deliver).toHaveBeenCalledTimes(1); + }); + + test('delivery failure', async () => { + const mockDestinationService = new NativeIntegrationDestinationService(); + mockDestinationService.deliver = jest + .fn() + .mockImplementation((event, destinationType, requestMetadata, version) => { + expect(event).toEqual(getData()); + expect(destinationType).toEqual('__rudder_test__'); + expect(version).toEqual('v1'); + throw new Error('test error'); + }); + const getNativeDestinationServiceSpy = jest + .spyOn(ServiceSelector, 'getNativeDestinationService') + .mockImplementation(() => { + return mockDestinationService; + }); + + const response = await request(server) + .post('/v1/destinations/__rudder_test__/proxy') + .set('Accept', 'application/json') + .send(getData()); + + const expectedResp = { + output: { + message: 'test error', + statTags: { + errorCategory: 'transformation', + }, + status: 500, + response: [{ error: 'test error', metadata: { a1: 'b1' }, statusCode: 500 }], + }, + }; + expect(response.status).toEqual(200); + expect(response.body).toEqual(expectedResp); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getNativeDestinationServiceSpy).toHaveBeenCalledTimes(1); + expect(mockDestinationService.deliver).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/src/controllers/__tests__/destination.test.ts b/src/controllers/__tests__/destination.test.ts new file mode 100644 index 00000000000..3c49a9a0aff --- /dev/null +++ b/src/controllers/__tests__/destination.test.ts @@ -0,0 +1,337 @@ +import request from 'supertest'; +import { createHttpTerminator } from 'http-terminator'; +import Koa from 'koa'; +import bodyParser from 'koa-bodyparser'; +import { applicationRoutes } from '../../routes'; +import { ServiceSelector } from '../../helpers/serviceSelector'; +import { DynamicConfigParser } from '../../util/dynamicConfigParser'; +import { NativeIntegrationDestinationService } from '../../services/destination/nativeIntegration'; + +let server: any; +const OLD_ENV = process.env; + +beforeAll(async () => { + process.env = { ...OLD_ENV }; // Make a copy + const app = new Koa(); + app.use( + bodyParser({ + jsonLimit: '200mb', + }), + ); + applicationRoutes(app); + server = app.listen(9090); +}); + +afterAll(async () => { + process.env = OLD_ENV; // Restore old environment + const httpTerminator = createHttpTerminator({ + server, + }); + await httpTerminator.terminate(); +}); + +afterEach(() => { + jest.clearAllMocks(); +}); + +const getData = () => { + return [{ event: { a: 'b1' } }, { event: { a: 'b2' } }]; +}; + +const getRouterTransformInputData = () => { + return { + input: [ + { message: { a: 'b1' }, destination: {}, metadata: { jobId: 1 } }, + { message: { a: 'b2' }, destination: {}, metadata: { jobId: 2 } }, + ], + destType: '__rudder_test__', + }; +}; + +describe('Destination controller tests', () => { + describe('Destination processor transform tests', () => { + test('successful transformation at processor', async () => { + const mockDestinationService = new NativeIntegrationDestinationService(); + + const expectedOutput = [ + { + event: { a: 'b1' }, + request: { query: {} }, + message: {}, + }, + { + event: { a: 'b2' }, + request: { query: {} }, + message: {}, + }, + ]; + mockDestinationService.doProcessorTransformation = jest + .fn() + .mockImplementation((events, destinationType, version, requestMetadata) => { + expect(events).toEqual(expectedOutput); + expect(destinationType).toEqual('__rudder_test__'); + expect(version).toEqual('v0'); + + return events; + }); + const getDestinationServiceSpy = jest + .spyOn(ServiceSelector, 'getDestinationService') + .mockImplementation(() => { + return mockDestinationService; + }); + + DynamicConfigParser.process = jest.fn().mockImplementation((events) => { + return events; + }); + + const response = await request(server) + .post('/v0/destinations/__rudder_test__') + .set('Accept', 'application/json') + .send(getData()); + + expect(response.status).toEqual(200); + expect(response.body).toEqual(expectedOutput); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getDestinationServiceSpy).toHaveBeenCalledTimes(1); + expect(mockDestinationService.doProcessorTransformation).toHaveBeenCalledTimes(1); + }); + + test('transformation at processor failure', async () => { + const mockDestinationService = new NativeIntegrationDestinationService(); + + const expectedOutput = [ + { + statusCode: 500, + error: 'Processor transformation failed', + statTags: { errorCategory: 'transformation' }, + }, + { + statusCode: 500, + error: 'Processor transformation failed', + statTags: { errorCategory: 'transformation' }, + }, + ]; + + mockDestinationService.doProcessorTransformation = jest + .fn() + .mockImplementation((events, destinationType, version, requestMetadata) => { + expect(destinationType).toEqual('__rudder_test__'); + expect(version).toEqual('v0'); + + throw new Error('Processor transformation failed'); + }); + const getDestinationServiceSpy = jest + .spyOn(ServiceSelector, 'getDestinationService') + .mockImplementation(() => { + return mockDestinationService; + }); + + DynamicConfigParser.process = jest.fn().mockImplementation((events) => { + return events; + }); + + const response = await request(server) + .post('/v0/destinations/__rudder_test__') + .set('Accept', 'application/json') + .send(getData()); + + expect(response.status).toEqual(200); + expect(response.body).toEqual(expectedOutput); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getDestinationServiceSpy).toHaveBeenCalledTimes(1); + expect(mockDestinationService.doProcessorTransformation).toHaveBeenCalledTimes(1); + }); + }); + + describe('Destination router transform tests', () => { + test('successful transformation at router', async () => { + const mockDestinationService = new NativeIntegrationDestinationService(); + + const expectedOutput = [ + { + message: { a: 'b1' }, + destination: {}, + metadata: { jobId: 1 }, + request: { query: {} }, + }, + { + message: { a: 'b2' }, + destination: {}, + metadata: { jobId: 2 }, + request: { query: {} }, + }, + ]; + + mockDestinationService.doRouterTransformation = jest + .fn() + .mockImplementation((events, destinationType, version, requestMetadata) => { + expect(events).toEqual(expectedOutput); + expect(destinationType).toEqual('__rudder_test__'); + expect(version).toEqual('v0'); + + return events; + }); + const getDestinationServiceSpy = jest + .spyOn(ServiceSelector, 'getDestinationService') + .mockImplementation(() => { + return mockDestinationService; + }); + + DynamicConfigParser.process = jest.fn().mockImplementation((events) => { + return events; + }); + + const response = await request(server) + .post('/routerTransform') + .set('Accept', 'application/json') + .send(getRouterTransformInputData()); + + expect(response.status).toEqual(200); + expect(response.body).toEqual({ output: expectedOutput }); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getDestinationServiceSpy).toHaveBeenCalledTimes(1); + expect(mockDestinationService.doRouterTransformation).toHaveBeenCalledTimes(1); + }); + + test('transformation at router failure', async () => { + const mockDestinationService = new NativeIntegrationDestinationService(); + + mockDestinationService.doRouterTransformation = jest + .fn() + .mockImplementation((events, destinationType, version, requestMetadata) => { + throw new Error('Router transformation failed'); + }); + const getDestinationServiceSpy = jest + .spyOn(ServiceSelector, 'getDestinationService') + .mockImplementation(() => { + return mockDestinationService; + }); + + DynamicConfigParser.process = jest.fn().mockImplementation((events) => { + return events; + }); + + const response = await request(server) + .post('/routerTransform') + .set('Accept', 'application/json') + .send(getRouterTransformInputData()); + + const expectedOutput = [ + { + metadata: [{ jobId: 1 }, { jobId: 2 }], + batched: false, + statusCode: 500, + error: 'Router transformation failed', + statTags: { errorCategory: 'transformation' }, + }, + ]; + expect(response.status).toEqual(200); + expect(response.body).toEqual({ output: expectedOutput }); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getDestinationServiceSpy).toHaveBeenCalledTimes(1); + expect(mockDestinationService.doRouterTransformation).toHaveBeenCalledTimes(1); + }); + }); + + describe('Batch transform tests', () => { + test('successful batching at router', async () => { + const mockDestinationService = new NativeIntegrationDestinationService(); + + const expectedOutput = [ + { + message: { a: 'b1' }, + destination: {}, + metadata: { jobId: 1 }, + request: { query: {} }, + }, + { + message: { a: 'b2' }, + destination: {}, + metadata: { jobId: 2 }, + request: { query: {} }, + }, + ]; + + mockDestinationService.doBatchTransformation = jest + .fn() + .mockImplementation((events, destinationType, version, requestMetadata) => { + expect(events).toEqual(expectedOutput); + expect(destinationType).toEqual('__rudder_test__'); + expect(version).toEqual('v0'); + + return events; + }); + const getDestinationServiceSpy = jest + .spyOn(ServiceSelector, 'getDestinationService') + .mockImplementation(() => { + return mockDestinationService; + }); + + DynamicConfigParser.process = jest.fn().mockImplementation((events) => { + return events; + }); + + const response = await request(server) + .post('/batch') + .set('Accept', 'application/json') + .send(getRouterTransformInputData()); + + expect(response.status).toEqual(200); + expect(response.body).toEqual(expectedOutput); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getDestinationServiceSpy).toHaveBeenCalledTimes(1); + expect(mockDestinationService.doBatchTransformation).toHaveBeenCalledTimes(1); + }); + + test('batch transformation failure', async () => { + const mockDestinationService = new NativeIntegrationDestinationService(); + + mockDestinationService.doBatchTransformation = jest + .fn() + .mockImplementation((events, destinationType, version, requestMetadata) => { + throw new Error('Batch transformation failed'); + }); + const getDestinationServiceSpy = jest + .spyOn(ServiceSelector, 'getDestinationService') + .mockImplementation(() => { + return mockDestinationService; + }); + + DynamicConfigParser.process = jest.fn().mockImplementation((events) => { + return events; + }); + + const response = await request(server) + .post('/batch') + .set('Accept', 'application/json') + .send(getRouterTransformInputData()); + + const expectedOutput = [ + { + metadata: [{ jobId: 1 }, { jobId: 2 }], + batched: false, + statusCode: 500, + error: 'Batch transformation failed', + statTags: { errorCategory: 'transformation' }, + }, + ]; + expect(response.status).toEqual(200); + expect(response.body).toEqual(expectedOutput); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getDestinationServiceSpy).toHaveBeenCalledTimes(1); + expect(mockDestinationService.doBatchTransformation).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/src/controllers/__tests__/regulation.test.ts b/src/controllers/__tests__/regulation.test.ts new file mode 100644 index 00000000000..55cd8f2d376 --- /dev/null +++ b/src/controllers/__tests__/regulation.test.ts @@ -0,0 +1,107 @@ +import request from 'supertest'; +import { createHttpTerminator } from 'http-terminator'; +import Koa from 'koa'; +import bodyParser from 'koa-bodyparser'; +import { applicationRoutes } from '../../routes'; +import { ServiceSelector } from '../../helpers/serviceSelector'; +import { NativeIntegrationDestinationService } from '../../services/destination/nativeIntegration'; + +let server: any; +const OLD_ENV = process.env; + +beforeAll(async () => { + process.env = { ...OLD_ENV }; // Make a copy + const app = new Koa(); + app.use( + bodyParser({ + jsonLimit: '200mb', + }), + ); + applicationRoutes(app); + server = app.listen(9090); +}); + +afterAll(async () => { + process.env = OLD_ENV; // Restore old environment + const httpTerminator = createHttpTerminator({ + server, + }); + await httpTerminator.terminate(); +}); + +afterEach(() => { + jest.clearAllMocks(); +}); + +const getDeletionData = () => { + return [ + { userAttributes: [{ a: 'b1' }], destType: '__rudder_test__' }, + { userAttributes: [{ a: 'b1' }], destType: '__rudder_test__' }, + ]; +}; + +describe('Regulation controller tests', () => { + describe('Delete users tests', () => { + test('successful delete users request', async () => { + const mockDestinationService = new NativeIntegrationDestinationService(); + + const expectedOutput = [{ statusCode: 400 }, { statusCode: 200 }]; + + mockDestinationService.processUserDeletion = jest + .fn() + .mockImplementation((reqs, destInfo) => { + expect(reqs).toEqual(getDeletionData()); + expect(destInfo).toEqual({ a: 'test' }); + + return expectedOutput; + }); + const getDestinationServiceSpy = jest + .spyOn(ServiceSelector, 'getNativeDestinationService') + .mockImplementation(() => { + return mockDestinationService; + }); + + const response = await request(server) + .post('/deleteUsers') + .set('Accept', 'application/json') + .set('x-rudder-dest-info', '{"a": "test"}') + .send(getDeletionData()); + + expect(response.status).toEqual(400); + expect(response.body).toEqual(expectedOutput); + + expect(getDestinationServiceSpy).toHaveBeenCalledTimes(1); + expect(mockDestinationService.processUserDeletion).toHaveBeenCalledTimes(1); + }); + + test('delete users request failure', async () => { + const mockDestinationService = new NativeIntegrationDestinationService(); + + mockDestinationService.processUserDeletion = jest + .fn() + .mockImplementation((reqs, destInfo) => { + expect(reqs).toEqual(getDeletionData()); + expect(destInfo).toEqual({ a: 'test' }); + + throw new Error('processUserDeletion error'); + }); + const getDestinationServiceSpy = jest + .spyOn(ServiceSelector, 'getNativeDestinationService') + .mockImplementation(() => { + return mockDestinationService; + }); + + const response = await request(server) + .post('/deleteUsers') + .set('Accept', 'application/json') + .set('x-rudder-dest-info', '{"a": "test"}') + .send(getDeletionData()); + + expect(response.status).toEqual(500); + expect(response.body).toEqual([{ error: {}, statusCode: 500 }]); + + expect(getDestinationServiceSpy).toHaveBeenCalledTimes(1); + expect(mockDestinationService.processUserDeletion).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/src/controllers/__tests__/source.test.ts b/src/controllers/__tests__/source.test.ts new file mode 100644 index 00000000000..565f39d559f --- /dev/null +++ b/src/controllers/__tests__/source.test.ts @@ -0,0 +1,220 @@ +import request from 'supertest'; +import { createHttpTerminator } from 'http-terminator'; +import Koa from 'koa'; +import bodyParser from 'koa-bodyparser'; +import { applicationRoutes } from '../../routes'; +import { NativeIntegrationSourceService } from '../../services/source/nativeIntegration'; +import { ServiceSelector } from '../../helpers/serviceSelector'; +import { ControllerUtility } from '../util/index'; + +let server: any; +const OLD_ENV = process.env; + +beforeAll(async () => { + process.env = { ...OLD_ENV }; // Make a copy + const app = new Koa(); + app.use( + bodyParser({ + jsonLimit: '200mb', + }), + ); + applicationRoutes(app); + server = app.listen(9090); +}); + +afterAll(async () => { + process.env = OLD_ENV; // Restore old environment + const httpTerminator = createHttpTerminator({ + server, + }); + await httpTerminator.terminate(); +}); + +afterEach(() => { + jest.clearAllMocks(); +}); + +const getData = () => { + return [{ event: { a: 'b1' } }, { event: { a: 'b2' } }]; +}; + +describe('Source controller tests', () => { + describe('V0 Source transform tests', () => { + test('successful source transform', async () => { + const sourceType = '__rudder_test__'; + const version = 'v0'; + const testOutput = [{ event: { a: 'b' } }]; + + const mockSourceService = new NativeIntegrationSourceService(); + mockSourceService.sourceTransformRoutine = jest + .fn() + .mockImplementation((i, s, v, requestMetadata) => { + expect(i).toEqual(getData()); + expect(s).toEqual(sourceType); + expect(v).toEqual(version); + return testOutput; + }); + const getNativeSourceServiceSpy = jest + .spyOn(ServiceSelector, 'getNativeSourceService') + .mockImplementation(() => { + return mockSourceService; + }); + + const adaptInputToVersionSpy = jest + .spyOn(ControllerUtility, 'adaptInputToVersion') + .mockImplementation((s, v, e) => { + expect(s).toEqual(sourceType); + expect(v).toEqual(version); + expect(e).toEqual(getData()); + return { implementationVersion: version, input: e }; + }); + + const response = await request(server) + .post('/v0/sources/__rudder_test__') + .set('Accept', 'application/json') + .send(getData()); + + expect(response.status).toEqual(200); + expect(response.body).toEqual(testOutput); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getNativeSourceServiceSpy).toHaveBeenCalledTimes(1); + expect(adaptInputToVersionSpy).toHaveBeenCalledTimes(1); + expect(mockSourceService.sourceTransformRoutine).toHaveBeenCalledTimes(1); + }); + + test('failing source transform', async () => { + const sourceType = '__rudder_test__'; + const version = 'v0'; + + const mockSourceService = new NativeIntegrationSourceService(); + const getNativeSourceServiceSpy = jest + .spyOn(ServiceSelector, 'getNativeSourceService') + .mockImplementation(() => { + return mockSourceService; + }); + + const adaptInputToVersionSpy = jest + .spyOn(ControllerUtility, 'adaptInputToVersion') + .mockImplementation((s, v, e) => { + expect(s).toEqual(sourceType); + expect(v).toEqual(version); + expect(e).toEqual(getData()); + throw new Error('test error'); + }); + + const response = await request(server) + .post('/v0/sources/__rudder_test__') + .set('Accept', 'application/json') + .send(getData()); + + const expectedResp = [ + { + error: 'test error', + statTags: { + errorCategory: 'transformation', + }, + statusCode: 500, + }, + ]; + + expect(response.status).toEqual(200); + expect(response.body).toEqual(expectedResp); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getNativeSourceServiceSpy).toHaveBeenCalledTimes(1); + expect(adaptInputToVersionSpy).toHaveBeenCalledTimes(1); + }); + }); + + describe('V1 Source transform tests', () => { + test('successful source transform', async () => { + const sourceType = '__rudder_test__'; + const version = 'v1'; + const testOutput = [{ event: { a: 'b' }, source: { id: 'id' } }]; + + const mockSourceService = new NativeIntegrationSourceService(); + mockSourceService.sourceTransformRoutine = jest + .fn() + .mockImplementation((i, s, v, requestMetadata) => { + expect(i).toEqual(getData()); + expect(s).toEqual(sourceType); + expect(v).toEqual(version); + return testOutput; + }); + const getNativeSourceServiceSpy = jest + .spyOn(ServiceSelector, 'getNativeSourceService') + .mockImplementation(() => { + return mockSourceService; + }); + + const adaptInputToVersionSpy = jest + .spyOn(ControllerUtility, 'adaptInputToVersion') + .mockImplementation((s, v, e) => { + expect(s).toEqual(sourceType); + expect(v).toEqual(version); + expect(e).toEqual(getData()); + return { implementationVersion: version, input: e }; + }); + + const response = await request(server) + .post('/v1/sources/__rudder_test__') + .set('Accept', 'application/json') + .send(getData()); + + expect(response.status).toEqual(200); + expect(response.body).toEqual(testOutput); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getNativeSourceServiceSpy).toHaveBeenCalledTimes(1); + expect(adaptInputToVersionSpy).toHaveBeenCalledTimes(1); + expect(mockSourceService.sourceTransformRoutine).toHaveBeenCalledTimes(1); + }); + + test('failing source transform', async () => { + const sourceType = '__rudder_test__'; + const version = 'v1'; + const mockSourceService = new NativeIntegrationSourceService(); + const getNativeSourceServiceSpy = jest + .spyOn(ServiceSelector, 'getNativeSourceService') + .mockImplementation(() => { + return mockSourceService; + }); + + const adaptInputToVersionSpy = jest + .spyOn(ControllerUtility, 'adaptInputToVersion') + .mockImplementation((s, v, e) => { + expect(s).toEqual(sourceType); + expect(v).toEqual(version); + expect(e).toEqual(getData()); + throw new Error('test error'); + }); + + const response = await request(server) + .post('/v1/sources/__rudder_test__') + .set('Accept', 'application/json') + .send(getData()); + + const expectedResp = [ + { + error: 'test error', + statTags: { + errorCategory: 'transformation', + }, + statusCode: 500, + }, + ]; + + expect(response.status).toEqual(200); + expect(response.body).toEqual(expectedResp); + + expect(response.header['apiversion']).toEqual('2'); + + expect(getNativeSourceServiceSpy).toHaveBeenCalledTimes(1); + expect(adaptInputToVersionSpy).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/src/controllers/bulkUpload.ts b/src/controllers/bulkUpload.ts index babb8b6db16..dbd77dc07f8 100644 --- a/src/controllers/bulkUpload.ts +++ b/src/controllers/bulkUpload.ts @@ -1,14 +1,14 @@ /* eslint-disable global-require, import/no-dynamic-require, @typescript-eslint/no-unused-vars */ import { client as errNotificationClient } from '../util/errorNotifier'; import logger from '../logger'; +import { + getJobStatusHandler, + getPollStatusHandler, + getDestFileUploadHandler, +} from '../util/fetchDestinationHandlers'; import { CatchErr, ContextBodySimple } from '../util/types'; // TODO: To be refactored and redisgned -const getDestFileUploadHandler = (version, dest) => - require(`../${version}/destinations/${dest}/fileUpload`); -const getPollStatusHandler = (version, dest) => require(`../${version}/destinations/${dest}/poll`); -const getJobStatusHandler = (version, dest) => - require(`../${version}/destinations/${dest}/fetchJobStatus`); const ERROR_MESSAGE_PROCESSOR_STRING = 'Error occurred while processing payload.'; const getCommonMetadata = (ctx) => diff --git a/src/controllers/delivery.ts b/src/controllers/delivery.ts index eba24ccf583..4334dc33b2c 100644 --- a/src/controllers/delivery.ts +++ b/src/controllers/delivery.ts @@ -1,13 +1,14 @@ /* eslint-disable prefer-destructuring */ /* eslint-disable sonarjs/no-duplicate-string */ import { Context } from 'koa'; +import { isDefinedAndNotNullAndNotEmpty } from '@rudderstack/integrations-lib'; import { MiscService } from '../services/misc'; import { - DeliveriesResponse, - DeliveryResponse, + DeliveryV1Response, + DeliveryV0Response, ProcessorTransformationOutput, - ProxyDeliveriesRequest, - ProxyDeliveryRequest, + ProxyV0Request, + ProxyV1Request, } from '../types/index'; import { ServiceSelector } from '../helpers/serviceSelector'; import { DeliveryTestService } from '../services/delivertTest/deliveryTest'; @@ -22,9 +23,9 @@ const NON_DETERMINABLE = 'Non-determinable'; export class DeliveryController { public static async deliverToDestination(ctx: Context) { logger.debug('Native(Delivery):: Request to transformer::', JSON.stringify(ctx.request.body)); - let deliveryResponse: DeliveryResponse; + let deliveryResponse: DeliveryV0Response; const requestMetadata = MiscService.getRequestMetadata(ctx); - const deliveryRequest = ctx.request.body as ProxyDeliveryRequest; + const deliveryRequest = ctx.request.body as ProxyV0Request; const { destination }: { destination: string } = ctx.params; const integrationService = ServiceSelector.getNativeDestinationService(); try { @@ -33,7 +34,7 @@ export class DeliveryController { destination, requestMetadata, 'v0', - )) as DeliveryResponse; + )) as DeliveryV0Response; } catch (error: any) { const { metadata } = deliveryRequest; const metaTO = integrationService.getTags( @@ -57,9 +58,9 @@ export class DeliveryController { public static async deliverToDestinationV1(ctx: Context) { logger.debug('Native(Delivery):: Request to transformer::', JSON.stringify(ctx.request.body)); - let deliveryResponse: DeliveriesResponse; + let deliveryResponse: DeliveryV1Response; const requestMetadata = MiscService.getRequestMetadata(ctx); - const deliveryRequest = ctx.request.body as ProxyDeliveriesRequest; + const deliveryRequest = ctx.request.body as ProxyV1Request; const { destination }: { destination: string } = ctx.params; const integrationService = ServiceSelector.getNativeDestinationService(); try { @@ -68,7 +69,7 @@ export class DeliveryController { destination, requestMetadata, 'v1', - )) as DeliveriesResponse; + )) as DeliveryV1Response; } catch (error: any) { const { metadata } = deliveryRequest; const metaTO = integrationService.getTags( @@ -84,7 +85,11 @@ export class DeliveryController { ); } ctx.body = { output: deliveryResponse }; - ControllerUtility.deliveryPostProcess(ctx, deliveryResponse.status); + if (isDefinedAndNotNullAndNotEmpty(deliveryResponse.authErrorCategory)) { + ControllerUtility.deliveryPostProcess(ctx, deliveryResponse.status); + } else { + ControllerUtility.deliveryPostProcess(ctx); + } logger.debug('Native(Delivery):: Response from transformer::', JSON.stringify(ctx.body)); return ctx; diff --git a/src/controllers/destination.ts b/src/controllers/destination.ts index 71075d1b4ce..d8b3c945247 100644 --- a/src/controllers/destination.ts +++ b/src/controllers/destination.ts @@ -15,6 +15,7 @@ import logger from '../logger'; import { getIntegrationVersion } from '../util/utils'; import tags from '../v0/util/tags'; import { DynamicConfigParser } from '../util/dynamicConfigParser'; +import { checkInvalidRtTfEvents } from '../v0/util'; export class DestinationController { public static async destinationTransformAtProcessor(ctx: Context) { @@ -101,6 +102,20 @@ export class DestinationController { const routerRequest = ctx.request.body as RouterTransformationRequest; const destination = routerRequest.destType; let events = routerRequest.input; + const errorRespEvents = checkInvalidRtTfEvents(events); + if (errorRespEvents.length > 0) { + errorRespEvents[0].metadata = [ + { + destType: destination, + }, + ]; + logger.debug( + `[${destination}] Invalid router transform payload structure: ${JSON.stringify(events)}`, + ); + ctx.body = { output: errorRespEvents }; + ControllerUtility.postProcess(ctx); + return ctx; + } const metaTags = MiscService.getMetaTags(events[0].metadata); stats.histogram('dest_transform_input_events', events.length, { destination, diff --git a/src/controllers/obs.delivery.js b/src/controllers/obs.delivery.js index 4a93afe1dcb..8e99650af64 100644 --- a/src/controllers/obs.delivery.js +++ b/src/controllers/obs.delivery.js @@ -1,7 +1,7 @@ /** * -------------------------------------- * -------------------------------------- - * ---------TO BE DEPRICIATED------------ + * ---------TO BE DEPRECATED------------- * -------------------------------------- * -------------------------------------- */ @@ -96,11 +96,15 @@ const DestProxyController = { destination, }); - response = generateErrorObject(err, { - [tags.TAG_NAMES.DEST_TYPE]: destination.toUpperCase(), - [tags.TAG_NAMES.MODULE]: tags.MODULES.DESTINATION, - [tags.TAG_NAMES.FEATURE]: tags.FEATURES.DATA_DELIVERY, - }, false); + response = generateErrorObject( + err, + { + [tags.TAG_NAMES.DEST_TYPE]: destination.toUpperCase(), + [tags.TAG_NAMES.MODULE]: tags.MODULES.DESTINATION, + [tags.TAG_NAMES.FEATURE]: tags.FEATURES.DATA_DELIVERY, + }, + false, + ); response.message = `[TransformerProxyTest] Error occurred while testing proxy for destination ("${destination}"): "${err.message}"`; logger.error(response.message); logger.error(err); diff --git a/src/controllers/regulation.ts b/src/controllers/regulation.ts index a50541780d6..318b5ed4e78 100644 --- a/src/controllers/regulation.ts +++ b/src/controllers/regulation.ts @@ -34,7 +34,7 @@ export class RegulationController { rudderDestInfo, ); ctx.body = resplist; - ctx.status = resplist[0].statusCode; + ctx.status = resplist[0].statusCode; // TODO: check if this is the right way to set status } catch (error: CatchErr) { const metaTO = integrationService.getTags( userDeletionRequests[0].destType, @@ -46,8 +46,8 @@ export class RegulationController { const errResp = DestinationPostTransformationService.handleUserDeletionFailureEvents( error, metaTO, - ); - ctx.body = [{ error, statusCode: 500 }] as UserDeletionResponse[]; + ); // TODO: this is not used. Fix it. + ctx.body = [{ error, statusCode: 500 }] as UserDeletionResponse[]; // TODO: responses array length is always 1. Is that okay? ctx.status = 500; } stats.timing('dest_transform_request_latency', startTime, { diff --git a/src/controllers/trackingPlan.ts b/src/controllers/trackingPlan.ts index 74e47e0ec92..e4802cfc4d8 100644 --- a/src/controllers/trackingPlan.ts +++ b/src/controllers/trackingPlan.ts @@ -7,7 +7,7 @@ export class TrackingPlanController { const events = ctx.request.body; const requestSize = Number(ctx.request.get('content-length')); const reqParams = ctx.request.query; - const response = await TrackingPlanservice.validateTrackingPlan(events, requestSize, reqParams); + const response = await TrackingPlanservice.validate(events, requestSize, reqParams); ctx.body = response.body; ControllerUtility.postProcess(ctx, response.status); return ctx; diff --git a/src/controllers/userTransform.ts b/src/controllers/userTransform.ts index c344bd072ad..3e01686a52a 100644 --- a/src/controllers/userTransform.ts +++ b/src/controllers/userTransform.ts @@ -15,9 +15,10 @@ export class UserTransformController { '(User transform - router:/customTransform ):: Request to transformer', JSON.stringify(ctx.request.body), ); + const requestSize = Number(ctx.request.get('content-length')); const events = ctx.request.body as ProcessorTransformationRequest[]; const processedRespone: UserTransformationServiceResponse = - await UserTransformService.transformRoutine(events, ctx.state.features); + await UserTransformService.transformRoutine(events, ctx.state.features, requestSize); ctx.body = processedRespone.transformedEvents; ControllerUtility.postProcess(ctx, processedRespone.retryStatus); logger.debug( diff --git a/src/controllers/util/index.ts b/src/controllers/util/index.ts index 75d3d8ffa7c..c5bf7ab3580 100644 --- a/src/controllers/util/index.ts +++ b/src/controllers/util/index.ts @@ -51,7 +51,7 @@ export class ControllerUtility { private static convertSourceInputv0Tov1(sourceEvents: unknown[]): SourceInput[] { return sourceEvents.map( - (sourceEvent) => ({ event: sourceEvent, source: undefined } as SourceInput), + (sourceEvent) => ({ event: sourceEvent, source: undefined }) as SourceInput, ); } diff --git a/src/features.json b/src/features.json index 8709dce4326..267923fdb4d 100644 --- a/src/features.json +++ b/src/features.json @@ -65,7 +65,10 @@ "TIKTOK_AUDIENCE": true, "REDDIT": true, "THE_TRADE_DESK": true, - "INTERCOM": true + "INTERCOM": true, + "NINETAILED": true, + "MOVABLE_INK": true, + "KOALA": true }, "regulations": [ "BRAZE", @@ -82,5 +85,5 @@ "SPRIG" ], "supportSourceTransformV1": true, - "supportTransformerProxyV1": false + "supportTransformerProxyV1": true } diff --git a/src/helpers/__tests__/fetchHandlers.test.ts b/src/helpers/__tests__/fetchHandlers.test.ts new file mode 100644 index 00000000000..2135317cafb --- /dev/null +++ b/src/helpers/__tests__/fetchHandlers.test.ts @@ -0,0 +1,36 @@ +import { FetchHandler } from '../fetchHandlers'; +import { MiscService } from '../../services/misc'; + +afterEach(() => { + jest.clearAllMocks(); +}); + +describe('FetchHandlers Service', () => { + test('should save the handlers in the respective maps', async () => { + const dest = 'dest'; + const source = 'source'; + const version = 'version'; + + MiscService.getDestHandler = jest.fn().mockImplementation((dest, version) => { + return {}; + }); + MiscService.getSourceHandler = jest.fn().mockImplementation((source, version) => { + return {}; + }); + MiscService.getDeletionHandler = jest.fn().mockImplementation((source, version) => { + return {}; + }); + + expect(FetchHandler['sourceHandlerMap'].get(dest)).toBeUndefined(); + FetchHandler.getSourceHandler(dest, version); + expect(FetchHandler['sourceHandlerMap'].get(dest)).toBeDefined(); + + expect(FetchHandler['destHandlerMap'].get(dest)).toBeUndefined(); + FetchHandler.getDestHandler(dest, version); + expect(FetchHandler['destHandlerMap'].get(dest)).toBeDefined(); + + expect(FetchHandler['deletionHandlerMap'].get(dest)).toBeUndefined(); + FetchHandler.getDeletionHandler(dest, version); + expect(FetchHandler['deletionHandlerMap'].get(dest)).toBeDefined(); + }); +}); diff --git a/src/helpers/__tests__/serviceSelector.test.ts b/src/helpers/__tests__/serviceSelector.test.ts new file mode 100644 index 00000000000..c48d6bbe8b7 --- /dev/null +++ b/src/helpers/__tests__/serviceSelector.test.ts @@ -0,0 +1,105 @@ +import { ServiceSelector } from '../serviceSelector'; +import { INTEGRATION_SERVICE } from '../../routes/utils/constants'; +import { ProcessorTransformationRequest } from '../../types/index'; +import { CDKV1DestinationService } from '../../services/destination/cdkV1Integration'; +import { CDKV2DestinationService } from '../../services/destination/cdkV2Integration'; +import { NativeIntegrationDestinationService } from '../../services/destination/nativeIntegration'; + +afterEach(() => { + jest.clearAllMocks(); +}); + +describe('ServiceSelector Service', () => { + test('should save the service in the cache', async () => { + expect(ServiceSelector['serviceMap'].get(INTEGRATION_SERVICE.NATIVE_DEST)).toBeUndefined(); + expect(ServiceSelector['serviceMap'].get(INTEGRATION_SERVICE.NATIVE_SOURCE)).toBeUndefined(); + + ServiceSelector.getNativeDestinationService(); + ServiceSelector.getNativeSourceService(); + + expect(ServiceSelector['serviceMap'].get(INTEGRATION_SERVICE.NATIVE_DEST)).toBeDefined(); + expect(ServiceSelector['serviceMap'].get(INTEGRATION_SERVICE.NATIVE_SOURCE)).toBeDefined(); + }); + + test('fetchCachedService should throw error for invalidService', async () => { + expect(() => ServiceSelector['fetchCachedService']('invalidService')).toThrow( + 'Invalid Service', + ); + }); + + test('isCdkDestination should return true', async () => { + const destinationDefinitionConfig = { + cdkEnabled: true, + }; + expect(ServiceSelector['isCdkDestination'](destinationDefinitionConfig)).toBe(true); + }); + + test('isCdkDestination should return false', async () => { + const destinationDefinitionConfig = { + cdkEnabledXYZ: true, + }; + expect(ServiceSelector['isCdkDestination'](destinationDefinitionConfig)).toBe(false); + }); + + test('isCdkV2Destination should return true', async () => { + const destinationDefinitionConfig = { + cdkV2Enabled: true, + }; + expect(ServiceSelector['isCdkV2Destination'](destinationDefinitionConfig)).toBe(true); + }); + + test('isCdkV2Destination should return false', async () => { + const destinationDefinitionConfig = { + cdkV2EnabledXYZ: true, + }; + expect(ServiceSelector['isCdkV2Destination'](destinationDefinitionConfig)).toBe(false); + }); + + test('getPrimaryDestinationService should return cdk v1 dest service', async () => { + const events = [ + { + destination: { + DestinationDefinition: { + Config: { + cdkEnabled: true, + }, + }, + }, + }, + ] as ProcessorTransformationRequest[]; + expect(ServiceSelector['getPrimaryDestinationService'](events)).toBeInstanceOf( + CDKV1DestinationService, + ); + }); + + test('getPrimaryDestinationService should return cdk v2 dest service', async () => { + const events = [ + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + }, + ] as ProcessorTransformationRequest[]; + expect(ServiceSelector['getPrimaryDestinationService'](events)).toBeInstanceOf( + CDKV2DestinationService, + ); + }); + + test('getPrimaryDestinationService should return native dest service', async () => { + const events = [{}] as ProcessorTransformationRequest[]; + expect(ServiceSelector['getPrimaryDestinationService'](events)).toBeInstanceOf( + NativeIntegrationDestinationService, + ); + }); + + test('getDestinationService should return native dest service', async () => { + const events = [{}] as ProcessorTransformationRequest[]; + expect(ServiceSelector.getDestinationService(events)).toBeInstanceOf( + NativeIntegrationDestinationService, + ); + }); +}); diff --git a/src/helpers/serviceSelector.ts b/src/helpers/serviceSelector.ts index 89678e94074..faa1c58240c 100644 --- a/src/helpers/serviceSelector.ts +++ b/src/helpers/serviceSelector.ts @@ -79,7 +79,7 @@ export class ServiceSelector { // eslint-disable-next-line @typescript-eslint/no-unused-vars public static getSourceService(arg: unknown) { - // Implement source event based descision logic for selecting service + // Implement source event based decision logic for selecting service } public static getDestinationService( diff --git a/src/interfaces/DestinationService.ts b/src/interfaces/DestinationService.ts index bf39024d85e..4947089b5d1 100644 --- a/src/interfaces/DestinationService.ts +++ b/src/interfaces/DestinationService.ts @@ -1,5 +1,5 @@ import { - DeliveryResponse, + DeliveryV0Response, MetaTransferObject, ProcessorTransformationRequest, ProcessorTransformationResponse, @@ -8,7 +8,7 @@ import { UserDeletionRequest, UserDeletionResponse, ProxyRequest, - DeliveriesResponse, + DeliveryV1Response, } from '../types/index'; export interface DestinationService { @@ -49,7 +49,7 @@ export interface DestinationService { destinationType: string, requestMetadata: NonNullable, version: string, - ): Promise; + ): Promise; processUserDeletion( requests: UserDeletionRequest[], diff --git a/src/legacy/router.js b/src/legacy/router.js index f8deb3fe622..9dd83b5988f 100644 --- a/src/legacy/router.js +++ b/src/legacy/router.js @@ -7,7 +7,7 @@ const Router = require('@koa/router'); const lodash = require('lodash'); const fs = require('fs'); const path = require('path'); -const { PlatformError } = require('@rudderstack/integrations-lib'); +const { PlatformError, getErrorRespEvents } = require('@rudderstack/integrations-lib'); const logger = require('../logger'); const stats = require('../util/stats'); const { SUPPORTED_VERSIONS, API_VERSION } = require('../routes/utils/constants'); @@ -18,7 +18,6 @@ const { isNonFuncObject, getMetadata, generateErrorObject, - getErrorRespEvents, isCdkDestination, checkAndCorrectUserId, } = require('../v0/util'); diff --git a/src/services/__tests__/misc.test.ts b/src/services/__tests__/misc.test.ts new file mode 100644 index 00000000000..5dcd948b34e --- /dev/null +++ b/src/services/__tests__/misc.test.ts @@ -0,0 +1,26 @@ +import { DestHandlerMap } from '../../constants/destinationCanonicalNames'; +import { MiscService } from '../misc'; + +describe('Misc tests', () => { + test('should return the right transform', async () => { + const version = 'v0'; + + Object.keys(DestHandlerMap).forEach((key) => { + expect(MiscService.getDestHandler(key, version)).toEqual( + require(`../../${version}/destinations/${DestHandlerMap[key]}/transform`), + ); + }); + + expect(MiscService.getDestHandler('am', version)).toEqual( + require(`../../${version}/destinations/am/transform`), + ); + + expect(MiscService.getSourceHandler('shopify', version)).toEqual( + require(`../../${version}/sources/shopify/transform`), + ); + + expect(MiscService.getDeletionHandler('intercom', version)).toEqual( + require(`../../${version}/destinations/intercom/deleteUsers`), + ); + }); +}); diff --git a/src/services/comparator.ts b/src/services/comparator.ts index d1e085b4bd6..36cb0ebd5a4 100644 --- a/src/services/comparator.ts +++ b/src/services/comparator.ts @@ -1,8 +1,8 @@ /* eslint-disable class-methods-use-this */ import { DestinationService } from '../interfaces/DestinationService'; import { - DeliveriesResponse, - DeliveryResponse, + DeliveryV0Response, + DeliveryV1Response, Destination, ErrorDetailer, MetaTransferObject, @@ -370,7 +370,7 @@ export class ComparatorService implements DestinationService { destinationType: string, requestMetadata: NonNullable, version: string, - ): Promise { + ): Promise { const primaryResplist = await this.primaryService.deliver( event, destinationType, diff --git a/src/services/destination/__tests__/nativeIntegration.test.ts b/src/services/destination/__tests__/nativeIntegration.test.ts new file mode 100644 index 00000000000..59c8b418817 --- /dev/null +++ b/src/services/destination/__tests__/nativeIntegration.test.ts @@ -0,0 +1,100 @@ +import { NativeIntegrationDestinationService } from '../nativeIntegration'; +import { DestinationPostTransformationService } from '../postTransformation'; +import { + ProcessorTransformationRequest, + ProcessorTransformationOutput, + ProcessorTransformationResponse, +} from '../../../types/index'; +import { FetchHandler } from '../../../helpers/fetchHandlers'; + +afterEach(() => { + jest.clearAllMocks(); +}); + +describe('NativeIntegration Service', () => { + test('doProcessorTransformation - success', async () => { + const destType = '__rudder_test__'; + const version = 'v0'; + const requestMetadata = {}; + const event = { message: { a: 'b' } } as ProcessorTransformationRequest; + const events: ProcessorTransformationRequest[] = [event, event]; + + const tevent = { version: 'v0', endpoint: 'http://abc' } as ProcessorTransformationOutput; + const tresp = { output: tevent, statusCode: 200 } as ProcessorTransformationResponse; + const tresponse: ProcessorTransformationResponse[] = [tresp, tresp]; + + FetchHandler.getDestHandler = jest.fn().mockImplementation((d, v) => { + expect(d).toEqual(destType); + expect(v).toEqual(version); + return { + process: jest.fn(() => { + return tevent; + }), + }; + }); + + const postTransformSpy = jest + .spyOn(DestinationPostTransformationService, 'handleProcessorTransformSucessEvents') + .mockImplementation((e, p, d) => { + expect(e).toEqual(event); + expect(p).toEqual(tevent); + return [tresp]; + }); + + const service = new NativeIntegrationDestinationService(); + const resp = await service.doProcessorTransformation( + events, + destType, + version, + requestMetadata, + ); + + expect(resp).toEqual(tresponse); + + expect(postTransformSpy).toHaveBeenCalledTimes(2); + }); + + test('doProcessorTransformation - failure', async () => { + const destType = '__rudder_test__'; + const version = 'v0'; + const requestMetadata = {}; + const event = { message: { a: 'b' } } as ProcessorTransformationRequest; + const events: ProcessorTransformationRequest[] = [event, event]; + + FetchHandler.getDestHandler = jest.fn().mockImplementation((d, v) => { + expect(d).toEqual(destType); + expect(v).toEqual(version); + return { + process: jest.fn(() => { + throw new Error('test error'); + }), + }; + }); + + const service = new NativeIntegrationDestinationService(); + const resp = await service.doProcessorTransformation( + events, + destType, + version, + requestMetadata, + ); + + const expected = [ + { + metadata: undefined, + statusCode: 500, + error: 'test error', + statTags: { errorCategory: 'transformation' }, + }, + { + metadata: undefined, + statusCode: 500, + error: 'test error', + statTags: { errorCategory: 'transformation' }, + }, + ]; + + console.log('resp:', resp); + expect(resp).toEqual(expected); + }); +}); diff --git a/src/services/destination/__tests__/postTransformation.test.ts b/src/services/destination/__tests__/postTransformation.test.ts new file mode 100644 index 00000000000..f961dcbce7e --- /dev/null +++ b/src/services/destination/__tests__/postTransformation.test.ts @@ -0,0 +1,22 @@ +import { MetaTransferObject, ProcessorTransformationRequest } from '../../../types/index'; +import { DestinationPostTransformationService } from '../postTransformation'; +import { ProcessorTransformationResponse } from '../../../types'; + +describe('PostTransformation Service', () => { + test('should handleProcessorTransformFailureEvents', async () => { + const e = new Error('test error'); + const metaTo = { errorContext: 'error Context' } as MetaTransferObject; + const resp = DestinationPostTransformationService.handleProcessorTransformFailureEvents( + e, + metaTo, + ); + + const expected = { + statusCode: 500, + error: 'test error', + statTags: { errorCategory: 'transformation' }, + } as ProcessorTransformationResponse; + + expect(resp).toEqual(expected); + }); +}); diff --git a/src/services/destination/__tests__/preTransformation.test.ts b/src/services/destination/__tests__/preTransformation.test.ts new file mode 100644 index 00000000000..c10bab78acb --- /dev/null +++ b/src/services/destination/__tests__/preTransformation.test.ts @@ -0,0 +1,23 @@ +import { createMockContext } from '@shopify/jest-koa-mocks'; +import { ProcessorTransformationRequest } from '../../../types/index'; +import { DestinationPreTransformationService } from '../../destination/preTransformation'; + +describe('PreTransformation Service', () => { + test('should enhance events with query params', async () => { + const ctx = createMockContext(); + ctx.request.query = { cycle: 'true', x: 'y' }; + + const events: ProcessorTransformationRequest[] = [ + { message: { a: 'b' } } as ProcessorTransformationRequest, + ]; + const expected: ProcessorTransformationRequest[] = [ + { + message: { a: 'b' }, + request: { query: { cycle: 'true', x: 'y' } }, + } as ProcessorTransformationRequest, + ]; + + const resp = DestinationPreTransformationService.preProcess(events, ctx); + expect(resp).toEqual(expected); + }); +}); diff --git a/src/services/destination/cdkV1Integration.ts b/src/services/destination/cdkV1Integration.ts index 197e3162ea6..c6e60f58577 100644 --- a/src/services/destination/cdkV1Integration.ts +++ b/src/services/destination/cdkV1Integration.ts @@ -4,7 +4,7 @@ import path from 'path'; import { TransformationError } from '@rudderstack/integrations-lib'; import { DestinationService } from '../../interfaces/DestinationService'; import { - DeliveryResponse, + DeliveryV0Response, ErrorDetailer, MetaTransferObject, ProcessorTransformationRequest, @@ -14,7 +14,7 @@ import { UserDeletionRequest, UserDeletionResponse, ProxyRequest, - DeliveriesResponse, + DeliveryV1Response, } from '../../types/index'; import { DestinationPostTransformationService } from './postTransformation'; import tags from '../../v0/util/tags'; @@ -121,7 +121,7 @@ export class CDKV1DestinationService implements DestinationService { _event: ProxyRequest, _destinationType: string, _requestMetadata: NonNullable, - ): Promise { + ): Promise { throw new TransformationError('CDV1 Does not Implement Delivery Routine'); } diff --git a/src/services/destination/cdkV2Integration.ts b/src/services/destination/cdkV2Integration.ts index be7f0e51d5c..c18a5cd936d 100644 --- a/src/services/destination/cdkV2Integration.ts +++ b/src/services/destination/cdkV2Integration.ts @@ -5,7 +5,7 @@ import { TransformationError } from '@rudderstack/integrations-lib'; import { processCdkV2Workflow } from '../../cdk/v2/handler'; import { DestinationService } from '../../interfaces/DestinationService'; import { - DeliveryResponse, + DeliveryV0Response, ErrorDetailer, MetaTransferObject, ProcessorTransformationRequest, @@ -16,7 +16,7 @@ import { UserDeletionRequest, UserDeletionResponse, ProxyRequest, - DeliveriesResponse, + DeliveryV1Response, } from '../../types/index'; import tags from '../../v0/util/tags'; import { DestinationPostTransformationService } from './postTransformation'; @@ -170,7 +170,7 @@ export class CDKV2DestinationService implements DestinationService { _event: ProxyRequest, _destinationType: string, _requestMetadata: NonNullable, - ): Promise { + ): Promise { throw new TransformationError('CDKV2 Does not Implement Delivery Routine'); } diff --git a/src/services/destination/nativeIntegration.ts b/src/services/destination/nativeIntegration.ts index 6b680e3f4a1..2bb82fc602f 100644 --- a/src/services/destination/nativeIntegration.ts +++ b/src/services/destination/nativeIntegration.ts @@ -5,7 +5,7 @@ import groupBy from 'lodash/groupBy'; import cloneDeep from 'lodash/cloneDeep'; import { DestinationService } from '../../interfaces/DestinationService'; import { - DeliveryResponse, + DeliveryV0Response, ErrorDetailer, MetaTransferObject, ProcessorTransformationRequest, @@ -16,9 +16,9 @@ import { UserDeletionRequest, UserDeletionResponse, ProxyRequest, - ProxyDeliveriesRequest, - ProxyDeliveryRequest, - DeliveriesResponse, + ProxyV0Request, + ProxyV1Request, + DeliveryV1Response, DeliveryJobState, } from '../../types/index'; import { DestinationPostTransformationService } from './postTransformation'; @@ -181,7 +181,7 @@ export class NativeIntegrationDestinationService implements DestinationService { destinationType: string, _requestMetadata: NonNullable, version: string, - ): Promise { + ): Promise { try { const { networkHandler, handlerVersion } = networkHandlerFactory.getNetworkHandler( destinationType, @@ -191,37 +191,39 @@ export class NativeIntegrationDestinationService implements DestinationService { const processedProxyResponse = networkHandler.processAxiosResponse(rawProxyResponse); let rudderJobMetadata = version.toLowerCase() === 'v1' - ? (deliveryRequest as ProxyDeliveriesRequest).metadata - : (deliveryRequest as ProxyDeliveryRequest).metadata; + ? (deliveryRequest as ProxyV1Request).metadata + : (deliveryRequest as ProxyV0Request).metadata; if (version.toLowerCase() === 'v1' && handlerVersion.toLowerCase() === 'v0') { rudderJobMetadata = rudderJobMetadata[0]; } - - let responseProxy = networkHandler.responseHandler( - { - ...processedProxyResponse, - rudderJobMetadata, - }, - destinationType, - ); + const responseParams = { + destinationResponse: processedProxyResponse, + rudderJobMetadata, + destType: destinationType, + }; + let responseProxy = networkHandler.responseHandler(responseParams); // Adaption Logic for V0 to V1 if (handlerVersion.toLowerCase() === 'v0' && version.toLowerCase() === 'v1') { - const v0Response = responseProxy as DeliveryResponse; - const jobStates = (deliveryRequest as ProxyDeliveriesRequest).metadata.map( + const v0Response = responseProxy as DeliveryV0Response; + const jobStates = (deliveryRequest as ProxyV1Request).metadata.map( (metadata) => ({ - error: JSON.stringify(v0Response.destinationResponse?.response), + error: JSON.stringify( + v0Response.destinationResponse?.response === undefined + ? v0Response.destinationResponse + : v0Response.destinationResponse?.response, + ), statusCode: v0Response.status, metadata, - } as DeliveryJobState), + }) as DeliveryJobState, ); responseProxy = { response: jobStates, status: v0Response.status, message: v0Response.message, authErrorCategory: v0Response.authErrorCategory, - } as DeliveriesResponse; + } as DeliveryV1Response; } return responseProxy; } catch (err: any) { @@ -236,10 +238,10 @@ export class NativeIntegrationDestinationService implements DestinationService { ); if (version.toLowerCase() === 'v1') { - metaTO.metadatas = (deliveryRequest as ProxyDeliveriesRequest).metadata; + metaTO.metadatas = (deliveryRequest as ProxyV1Request).metadata; return DestinationPostTransformationService.handlevV1DeliveriesFailureEvents(err, metaTO); } - metaTO.metadata = (deliveryRequest as ProxyDeliveryRequest).metadata; + metaTO.metadata = (deliveryRequest as ProxyV0Request).metadata; return DestinationPostTransformationService.handleDeliveryFailureEvents(err, metaTO); } } diff --git a/src/services/destination/postTransformation.ts b/src/services/destination/postTransformation.ts index eef4152b2bd..161547683b5 100644 --- a/src/services/destination/postTransformation.ts +++ b/src/services/destination/postTransformation.ts @@ -8,10 +8,10 @@ import { ProcessorTransformationResponse, RouterTransformationResponse, ProcessorTransformationOutput, - DeliveryResponse, + DeliveryV0Response, MetaTransferObject, UserDeletionResponse, - DeliveriesResponse, + DeliveryV1Response, DeliveryJobState, } from '../../types/index'; import { generateErrorObject } from '../../v0/util'; @@ -75,7 +75,13 @@ export class DestinationPostTransformationService { ): RouterTransformationResponse[] { const resultantPayloads: RouterTransformationResponse[] = cloneDeep(transformedPayloads); resultantPayloads.forEach((resultantPayload) => { - if (resultantPayload.batchedRequest && resultantPayload.batchedRequest.userId) { + if (Array.isArray(resultantPayload.batchedRequest)) { + resultantPayload.batchedRequest.forEach((batchedRequest) => { + if (batchedRequest.userId) { + batchedRequest.userId = `${batchedRequest.userId}`; + } + }); + } else if (resultantPayload.batchedRequest && resultantPayload.batchedRequest.userId) { resultantPayload.batchedRequest.userId = `${resultantPayload.batchedRequest.userId}`; } }); @@ -145,7 +151,7 @@ export class DestinationPostTransformationService { public static handleDeliveryFailureEvents( error: any, metaTo: MetaTransferObject, - ): DeliveryResponse { + ): DeliveryV0Response { const errObj = generateErrorObject(error, metaTo.errorDetails, false); const resp = { status: errObj.status, @@ -155,7 +161,7 @@ export class DestinationPostTransformationService { ...(errObj.authErrorCategory && { authErrorCategory: errObj.authErrorCategory, }), - } as DeliveryResponse; + } as DeliveryV0Response; ErrorReportingService.reportError(error, metaTo.errorContext, resp); return resp; @@ -164,7 +170,7 @@ export class DestinationPostTransformationService { public static handlevV1DeliveriesFailureEvents( error: FixMe, metaTo: MetaTransferObject, - ): DeliveriesResponse { + ): DeliveryV1Response { const errObj = generateErrorObject(error, metaTo.errorDetails, false); const metadataArray = metaTo.metadatas; if (!Array.isArray(metadataArray)) { @@ -186,10 +192,12 @@ export class DestinationPostTransformationService { const resp = { response: responses, statTags: errObj.statTags, - authErrorCategory: errObj.authErrorCategory, message: errObj.message.toString(), status: errObj.status, - } as DeliveriesResponse; + ...(errObj.authErrorCategory && { + authErrorCategory: errObj.authErrorCategory, + }), + } as DeliveryV1Response; ErrorReportingService.reportError(error, metaTo.errorContext, resp); return resp; diff --git a/src/services/source/__tests__/nativeIntegration.test.ts b/src/services/source/__tests__/nativeIntegration.test.ts new file mode 100644 index 00000000000..bb40438811f --- /dev/null +++ b/src/services/source/__tests__/nativeIntegration.test.ts @@ -0,0 +1,89 @@ +import { NativeIntegrationSourceService } from '../nativeIntegration'; +import { SourcePostTransformationService } from '../postTransformation'; +import { SourceTransformationResponse, RudderMessage } from '../../../types/index'; +import stats from '../../../util/stats'; +import { FetchHandler } from '../../../helpers/fetchHandlers'; + +afterEach(() => { + jest.clearAllMocks(); +}); + +describe('NativeIntegration Source Service', () => { + test('sourceTransformRoutine - success', async () => { + const sourceType = '__rudder_test__'; + const version = 'v0'; + const requestMetadata = {}; + + const event = { message: { a: 'b' } }; + const events = [event, event]; + + const tevent = { anonymousId: 'test' } as RudderMessage; + const tresp = { output: { batch: [tevent] }, statusCode: 200 } as SourceTransformationResponse; + + const tresponse = [ + { output: { batch: [{ anonymousId: 'test' }] }, statusCode: 200 }, + { output: { batch: [{ anonymousId: 'test' }] }, statusCode: 200 }, + ]; + + FetchHandler.getSourceHandler = jest.fn().mockImplementationOnce((d, v) => { + expect(d).toEqual(sourceType); + expect(v).toEqual(version); + return { + process: jest.fn(() => { + return tevent; + }), + }; + }); + + const postTransformSpy = jest + .spyOn(SourcePostTransformationService, 'handleSuccessEventsSource') + .mockImplementation((e) => { + expect(e).toEqual(tevent); + return tresp; + }); + + const service = new NativeIntegrationSourceService(); + const resp = await service.sourceTransformRoutine(events, sourceType, version, requestMetadata); + + expect(resp).toEqual(tresponse); + + expect(postTransformSpy).toHaveBeenCalledTimes(2); + }); + + test('sourceTransformRoutine - failure', async () => { + const sourceType = '__rudder_test__'; + const version = 'v0'; + const requestMetadata = {}; + + const event = { message: { a: 'b' } }; + const events = [event, event]; + + const tresp = { error: 'error' } as SourceTransformationResponse; + + const tresponse = [{ error: 'error' }, { error: 'error' }]; + + FetchHandler.getSourceHandler = jest.fn().mockImplementationOnce((d, v) => { + expect(d).toEqual(sourceType); + expect(v).toEqual(version); + return { + process: jest.fn(() => { + throw new Error('test error'); + }), + }; + }); + + const postTransformSpy = jest + .spyOn(SourcePostTransformationService, 'handleFailureEventsSource') + .mockImplementation((e, m) => { + return tresp; + }); + jest.spyOn(stats, 'increment').mockImplementation(() => {}); + + const service = new NativeIntegrationSourceService(); + const resp = await service.sourceTransformRoutine(events, sourceType, version, requestMetadata); + + expect(resp).toEqual(tresponse); + + expect(postTransformSpy).toHaveBeenCalledTimes(2); + }); +}); diff --git a/src/services/source/__tests__/postTransformation.test.ts b/src/services/source/__tests__/postTransformation.test.ts new file mode 100644 index 00000000000..e5efbe8194f --- /dev/null +++ b/src/services/source/__tests__/postTransformation.test.ts @@ -0,0 +1,49 @@ +import { + MetaTransferObject, + RudderMessage, + SourceTransformationResponse, +} from '../../../types/index'; +import { SourcePostTransformationService } from '../../source/postTransformation'; + +describe('Source PostTransformation Service', () => { + test('should handleFailureEventsSource', async () => { + const e = new Error('test error'); + const metaTo = { errorContext: 'error Context' } as MetaTransferObject; + const resp = SourcePostTransformationService.handleFailureEventsSource(e, metaTo); + + const expected = { + statusCode: 500, + error: 'test error', + statTags: { errorCategory: 'transformation' }, + } as SourceTransformationResponse; + + expect(resp).toEqual(expected); + }); + + test('should return the event as SourceTransformationResponse if it has outputToSource property', () => { + const event = { + outputToSource: {}, + output: { batch: [{ anonymousId: 'test' }] }, + } as SourceTransformationResponse; + + const result = SourcePostTransformationService.handleSuccessEventsSource(event); + + expect(result).toEqual(event); + }); + + test('should return the events as batch in SourceTransformationResponse if it is an array', () => { + const events = [{ anonymousId: 'test' }, { anonymousId: 'test' }] as RudderMessage[]; + + const result = SourcePostTransformationService.handleSuccessEventsSource(events); + + expect(result).toEqual({ output: { batch: events } }); + }); + + test('should return the event as batch in SourceTransformationResponse if it is a single object', () => { + const event = { anonymousId: 'test' } as RudderMessage; + + const result = SourcePostTransformationService.handleSuccessEventsSource(event); + + expect(result).toEqual({ output: { batch: [event] } }); + }); +}); diff --git a/src/services/trackingPlan.ts b/src/services/trackingPlan.ts index 2e68df55e99..93b6ee11ffe 100644 --- a/src/services/trackingPlan.ts +++ b/src/services/trackingPlan.ts @@ -1,88 +1,87 @@ import logger from '../logger'; import { RetryRequestError, RespStatusError, constructValidationErrors } from '../util/utils'; -import { getMetadata } from '../v0/util'; +import { getMetadata, getTrackingPlanMetadata } from '../v0/util'; import eventValidator from '../util/eventValidation'; import stats from '../util/stats'; +import { HTTP_STATUS_CODES } from '../v0/util/constant'; export class TrackingPlanservice { - public static async validateTrackingPlan(events, requestSize, reqParams) { - const requestStartTime = new Date(); + public static async validate(events, requestSize, reqParams) { + const startTime = Date.now(); const respList: any[] = []; - const metaTags = events[0].metadata ? getMetadata(events[0].metadata) : {}; + const metaTags = events.length && events[0].metadata ? getMetadata(events[0].metadata) : {}; + const tpTags: any = + events.length && events[0].metadata ? getTrackingPlanMetadata(events[0].metadata) : {}; let ctxStatusCode = 200; for (let i = 0; i < events.length; i++) { + let eventValidationResponse: any; + let exceptionOccured = false; + const eventStartTime = Date.now(); const event = events[i]; - const eventStartTime = new Date(); + try { - const parsedEvent = event; - parsedEvent.request = { query: reqParams }; - const hv = await eventValidator.handleValidation(parsedEvent); - if (hv['dropEvent']) { - respList.push({ - output: event.message, - metadata: event.metadata, - statusCode: 400, - validationErrors: hv['validationErrors'], - error: JSON.stringify(constructValidationErrors(hv['validationErrors'])), - }); - stats.counter('tp_violation_type', 1, { - violationType: hv['violationType'], - ...metaTags, - }); - } else { - respList.push({ - output: event.message, - metadata: event.metadata, - statusCode: 200, - validationErrors: hv['validationErrors'], - error: JSON.stringify(constructValidationErrors(hv['validationErrors'])), - }); - stats.counter('tp_propagated_events', 1, { - ...metaTags, - }); - } - } catch (error) { - const errMessage = `Error occurred while validating : ${error}`; - logger.error(errMessage); - let status = 200; + event.request = { query: reqParams }; + const validatedEvent = await eventValidator.handleValidation(event); + eventValidationResponse = { + output: event.message, + metadata: event.metadata, + statusCode: validatedEvent['dropEvent'] + ? HTTP_STATUS_CODES.BAD_REQUEST + : HTTP_STATUS_CODES.OK, + validationErrors: validatedEvent['validationErrors'], + error: JSON.stringify(constructValidationErrors(validatedEvent['validationErrors'])), + }; + } catch (error: any) { + logger.debug( + `Error occurred while validating event`, + 'event', + `${event.message?.event}::${event.message?.type}`, + 'trackingPlan', + `${tpTags?.trackingPlanId}`, + 'error', + error.message, + ); + + exceptionOccured = true; + // no need to process further if + // we have error of retry request error if (error instanceof RetryRequestError) { ctxStatusCode = error.statusCode; + break; } - if (error instanceof RespStatusError) { - status = error.statusCode; - } - respList.push({ + + eventValidationResponse = { output: event.message, metadata: event.metadata, - statusCode: status, + statusCode: error instanceof RespStatusError ? error.statusCode : HTTP_STATUS_CODES.OK, validationErrors: [], - error: errMessage, - }); - stats.counter('tp_errors', 1, { - ...metaTags, - workspaceId: event.metadata?.workspaceId, - trackingPlanId: event.metadata?.trackingPlanId, - }); + error: `Error occurred while validating: ${error}`, + }; } finally { - stats.timing('tp_event_latency', eventStartTime, { + // finally on every event, we need to + // capture the information related to the validates event + stats.timing('tp_event_validation_latency', eventStartTime, { ...metaTags, + ...tpTags, + status: eventValidationResponse.statusCode, + exception: exceptionOccured, }); } - } - stats.counter('tp_events_count', events.length, { - ...metaTags, - }); + respList.push(eventValidationResponse); + } - stats.histogram('tp_request_size', requestSize, { + stats.histogram('tp_batch_size', requestSize, { ...metaTags, + ...tpTags, }); - stats.timing('tp_request_latency', requestStartTime, { + // capture overall function latency + // with metadata tags + stats.histogram('tp_batch_validation_latency', (Date.now() - startTime) / 1000, { ...metaTags, - workspaceId: events[0]?.metadata?.workspaceId, - trackingPlanId: events[0]?.metadata?.trackingPlanId, + ...tpTags, }); return { body: respList, status: ctxStatusCode }; diff --git a/src/services/userTransform.ts b/src/services/userTransform.ts index bf34e3d82a3..18c47ddc83a 100644 --- a/src/services/userTransform.ts +++ b/src/services/userTransform.ts @@ -14,7 +14,7 @@ import { RetryRequestError, extractStackTraceUptoLastSubstringMatch, } from '../util/utils'; -import { getMetadata, isNonFuncObject } from '../v0/util'; +import { getMetadata, getTransformationMetadata, isNonFuncObject } from '../v0/util'; import { SUPPORTED_FUNC_NAMES } from '../util/ivmFactory'; import logger from '../logger'; import stats from '../util/stats'; @@ -28,6 +28,7 @@ export class UserTransformService { public static async transformRoutine( events: ProcessorTransformationRequest[], features: FeatureFlags = {}, + requestSize = 0, ): Promise { let retryStatus = 200; const groupedEvents: NonNullable = groupBy( @@ -158,20 +159,23 @@ export class UserTransformService { statusCode: status, metadata: e.metadata, error: errorString, - } as ProcessorTransformationResponse), + }) as ProcessorTransformationResponse, ), ); stats.counter('user_transform_errors', eventsToProcess.length, { - transformationId: eventsToProcess[0]?.metadata?.transformationId, - workspaceId: eventsToProcess[0]?.metadata?.workspaceId, status, ...metaTags, + ...getTransformationMetadata(eventsToProcess[0]?.metadata), }); } finally { stats.timing('user_transform_request_latency', userFuncStartTime, { - workspaceId: eventsToProcess[0]?.metadata?.workspaceId, - transformationId: eventsToProcess[0]?.metadata?.transformationId, ...metaTags, + ...getTransformationMetadata(eventsToProcess[0]?.metadata), + }); + + stats.histogram('user_transform_batch_size', requestSize, { + ...metaTags, + ...getTransformationMetadata(eventsToProcess[0]?.metadata), }); } diff --git a/src/types/index.ts b/src/types/index.ts index f4432e5c2ac..68dfe3870db 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -6,7 +6,7 @@ type ProcessorTransformationOutput = { type: string; method: string; endpoint: string; - userId: string; + userId?: string; headers?: Record; params?: Record; body?: { @@ -18,7 +18,7 @@ type ProcessorTransformationOutput = { files?: Record; }; -type ProxyDeliveryRequest = { +type ProxyV0Request = { version: string; type: string; method: string; @@ -33,10 +33,11 @@ type ProxyDeliveryRequest = { FORM?: Record; }; files?: Record; - metadata: Metadata; + metadata: ProxyMetdata; + destinationConfig: Record; }; -type ProxyDeliveriesRequest = { +type ProxyV1Request = { version: string; type: string; method: string; @@ -51,10 +52,24 @@ type ProxyDeliveriesRequest = { FORM?: Record; }; files?: Record; - metadata: Metadata[]; + metadata: ProxyMetdata[]; + destinationConfig: Record; }; -type ProxyRequest = ProxyDeliveryRequest | ProxyDeliveriesRequest; +type ProxyRequest = ProxyV0Request | ProxyV1Request; + +type ProxyMetdata = { + jobId: number; + attemptNum: number; + userId: string; + sourceId: string; + destinationId: string; + workspaceId: string; + secret: Record; + destInfo?: Record; + omitempty?: Record; + dontBatch: boolean; +}; type Metadata = { sourceId: string; @@ -127,7 +142,7 @@ type ProcessorTransformationRequest = { message: object; metadata: Metadata; destination: Destination; - libraries: UserTransformationLibrary[]; + libraries?: UserTransformationLibrary[]; }; type RouterTransformationRequestData = { @@ -147,17 +162,17 @@ type ProcessorTransformationResponse = { metadata: Metadata; statusCode: number; error?: string; - statTags: object; + statTags?: object; }; type RouterTransformationResponse = { - batchedRequest?: ProcessorTransformationOutput; + batchedRequest?: ProcessorTransformationOutput | ProcessorTransformationOutput[]; metadata: Metadata[]; destination: Destination; batched: boolean; statusCode: number; - error: string; - statTags: object; + error?: string; + statTags?: object; }; type SourceTransformationOutput = { @@ -172,7 +187,7 @@ type SourceTransformationResponse = { statTags: object; }; -type DeliveryResponse = { +type DeliveryV0Response = { status: number; message: string; destinationResponse: any; @@ -183,13 +198,14 @@ type DeliveryResponse = { type DeliveryJobState = { error: string; statusCode: number; - metadata: Metadata; + metadata: ProxyMetdata; }; -type DeliveriesResponse = { - status?: number; - message?: string; +type DeliveryV1Response = { + status: number; + message: string; statTags?: object; + destinationResponse?: any; authErrorCategory?: string; response: DeliveryJobState[]; }; @@ -236,13 +252,22 @@ type ErrorDetailer = { sourceId?: string; }; -type MetaTransferObject = { - metadatas?: Metadata[]; - metadata?: Metadata; +type MetaTransferObjectForProxy = { + metadata?: ProxyMetdata; + metadatas?: ProxyMetdata[]; errorDetails: ErrorDetailer; errorContext: string; }; +type MetaTransferObject = + | { + metadatas?: Metadata[]; + metadata?: Metadata; + errorDetails: ErrorDetailer; + errorContext: string; + } + | MetaTransferObjectForProxy; + type UserTransformationResponse = { transformedEvent: RudderMessage; metadata: Metadata; @@ -307,8 +332,8 @@ type SourceInput = { export { ComparatorInput, DeliveryJobState, - DeliveryResponse, - DeliveriesResponse, + DeliveryV0Response, + DeliveryV1Response, Destination, ErrorDetailer, MessageIdMetadataMap, @@ -317,9 +342,10 @@ export { ProcessorTransformationOutput, ProcessorTransformationRequest, ProcessorTransformationResponse, - ProxyDeliveriesRequest, - ProxyDeliveryRequest, + ProxyMetdata, ProxyRequest, + ProxyV0Request, + ProxyV1Request, RouterTransformationRequest, RouterTransformationRequestData, RouterTransformationResponse, diff --git a/src/types/zodTypes.ts b/src/types/zodTypes.ts new file mode 100644 index 00000000000..75f12c5e9b3 --- /dev/null +++ b/src/types/zodTypes.ts @@ -0,0 +1,242 @@ +import { isDefinedAndNotNullAndNotEmpty } from '@rudderstack/integrations-lib'; +import { z } from 'zod'; +import { isHttpStatusSuccess } from '../v0/util'; + +const ProcessorTransformationOutputSchema = z.object({ + version: z.string(), + type: z.string(), + method: z.string(), + endpoint: z.string(), + userId: z.string().optional(), + headers: z.record(z.unknown()).optional(), + params: z.record(z.unknown()).optional(), + body: z + .object({ + JSON: z.record(z.unknown()).optional(), + JSON_ARRAY: z.record(z.unknown()).optional(), + XML: z.record(z.unknown()).optional(), + FORM: z.record(z.unknown()).optional(), + }) + .optional(), + files: z.record(z.unknown()).optional(), +}); + +export const ProcessorTransformationResponseSchema = z + .object({ + output: ProcessorTransformationOutputSchema.optional(), + metadata: z.record(z.unknown()), + statusCode: z.number(), + error: z.string().optional(), + statTags: z.record(z.unknown()).optional(), + }) + .refine( + (data) => { + if (!isHttpStatusSuccess(data.statusCode)) { + return ( + isDefinedAndNotNullAndNotEmpty(data.statTags) || + isDefinedAndNotNullAndNotEmpty(data.error) + ); + } + return true; + }, + { + message: "statTags and error can't be empty when status is not a 2XX", + path: ['statTags', 'error'], // Pointing out which field is invalid + }, + ) + .refine( + (data) => { + if (isHttpStatusSuccess(data.statusCode)) { + return isDefinedAndNotNullAndNotEmpty(data.output); + } + return true; + }, + { + message: "output can't be empty when status is 2XX", + path: ['output'], // Pointing out which field is invalid + }, + ); + +export const ProcessorTransformationResponseListSchema = z.array( + ProcessorTransformationResponseSchema, +); + +export const RouterTransformationResponseSchema = z + .object({ + batchedRequest: z + .array(ProcessorTransformationOutputSchema) + .or(ProcessorTransformationOutputSchema) + .optional(), + metadata: z.array(z.record(z.unknown())), // array of metadata + destination: z.record(z.unknown()), + batched: z.boolean(), + statusCode: z.number(), + error: z.string().optional(), + statTags: z.record(z.unknown()).optional(), + }) + .refine( + (data) => { + if (!isHttpStatusSuccess(data.statusCode)) { + return ( + isDefinedAndNotNullAndNotEmpty(data.statTags) || + isDefinedAndNotNullAndNotEmpty(data.error) + ); + } + return true; + }, + { + message: "statTags and error can't be empty when status is not a 2XX", + path: ['statTags', 'error'], // Pointing out which field is invalid + }, + ) + .refine( + (data) => { + if (isHttpStatusSuccess(data.statusCode)) { + return isDefinedAndNotNullAndNotEmpty(data.batchedRequest); + } + return true; + }, + { + message: "batchedRequest can't be empty when status is 2XX", + path: ['batchedRequest'], // Pointing out which field is invalid + }, + ); + +export const RouterTransformationResponseListSchema = z.array(RouterTransformationResponseSchema); + +// Proxy related schemas +export const ProxyMetadataSchema = z.object({ + jobId: z.number(), + attemptNum: z.number(), + userId: z.string(), + sourceId: z.string(), + destinationId: z.string(), + workspaceId: z.string(), + secret: z.record(z.unknown()), + destInfo: z.record(z.unknown()).optional(), + omitempty: z.record(z.unknown()).optional(), + dontBatch: z.boolean(), +}); + +export const ProxyV0RequestSchema = z.object({ + version: z.string(), + type: z.string(), + method: z.string(), + endpoint: z.string(), + userId: z.string(), + headers: z.record(z.unknown()).optional(), + params: z.record(z.unknown()).optional(), + body: z + .object({ + JSON: z.record(z.unknown()).optional(), + JSON_ARRAY: z.record(z.unknown()).optional(), + XML: z.record(z.unknown()).optional(), + FORM: z.record(z.unknown()).optional(), + }) + .optional(), + files: z.record(z.unknown()).optional(), + metadata: ProxyMetadataSchema, + destinationConfig: z.record(z.unknown()), +}); + +export const ProxyV1RequestSchema = z.object({ + version: z.string(), + type: z.string(), + method: z.string(), + endpoint: z.string(), + userId: z.string(), + headers: z.record(z.unknown()).optional(), + params: z.record(z.unknown()).optional(), + body: z + .object({ + JSON: z.record(z.unknown()).optional(), + JSON_ARRAY: z.record(z.unknown()).optional(), + XML: z.record(z.unknown()).optional(), + FORM: z.record(z.unknown()).optional(), + }) + .optional(), + files: z.record(z.unknown()).optional(), + metadata: z.array(ProxyMetadataSchema), + destinationConfig: z.record(z.unknown()), +}); + +const validateStatTags = (data: any) => { + if (!isHttpStatusSuccess(data.status)) { + return isDefinedAndNotNullAndNotEmpty(data.statTags); + } + return true; +}; + +const validateAuthErrorCategory = (data: any) => { + if (!isHttpStatusSuccess(data.status)) { + return isDefinedAndNotNullAndNotEmpty(data.authErrorCategory); + } + return true; +}; + +export const DeliveryV0ResponseSchema = z + .object({ + status: z.number(), + message: z.string(), + destinationResponse: z.unknown(), + statTags: z.record(z.unknown()).optional(), + authErrorCategory: z.string().optional(), + }) + .refine(validateStatTags, { + // eslint-disable-next-line sonarjs/no-duplicate-string + message: "statTags can't be empty when status is not a 2XX", + path: ['statTags'], // Pointing out which field is invalid + }); + +export const DeliveryV0ResponseSchemaForOauth = z + .object({ + status: z.number(), + message: z.string(), + destinationResponse: z.unknown(), + statTags: z.record(z.unknown()).optional(), + authErrorCategory: z.string().optional(), + }) + .refine(validateStatTags, { + message: "statTags can't be empty when status is not a 2XX", + path: ['statTags'], // Pointing out which field is invalid + }) + .refine(validateAuthErrorCategory, { + message: "authErrorCategory can't be empty when status is not a 2XX", + path: ['authErrorCategory'], // Pointing out which field is invalid + }); + +const DeliveryJobStateSchema = z.object({ + error: z.string(), + statusCode: z.number(), + metadata: ProxyMetadataSchema, +}); + +export const DeliveryV1ResponseSchema = z + .object({ + status: z.number(), + message: z.string(), + statTags: z.record(z.unknown()).optional(), + authErrorCategory: z.string().optional(), + response: z.array(DeliveryJobStateSchema), + }) + .refine(validateStatTags, { + message: "statTags can't be empty when status is not a 2XX", + path: ['statTags'], // Pointing out which field is invalid + }); + +export const DeliveryV1ResponseSchemaForOauth = z + .object({ + status: z.number(), + message: z.string(), + statTags: z.record(z.unknown()).optional(), + authErrorCategory: z.string().optional(), + response: z.array(DeliveryJobStateSchema), + }) + .refine(validateStatTags, { + message: "statTags can't be empty when status is not a 2XX", + path: ['statTags'], // Pointing out which field is invalid + }) + .refine(validateAuthErrorCategory, { + message: "authErrorCategory can't be empty when status is not a 2XX", + path: ['authErrorCategory'], // Pointing out which field is invalid + }); diff --git a/src/util/customTransformer-v1.js b/src/util/customTransformer-v1.js index 60f8e493faa..7e854a3714b 100644 --- a/src/util/customTransformer-v1.js +++ b/src/util/customTransformer-v1.js @@ -55,7 +55,7 @@ async function userTransformHandlerV1( testMode = false, ) { if (!userTransformation.versionId) { - return { transformedEvents : events }; + return { transformedEvents: events }; } const isolatevmFactory = await getFactory( @@ -88,9 +88,9 @@ async function userTransformHandlerV1( const tags = { identifier: 'v1', errored: transformationError ? true : false, - ...events.length && events[0].metadata ? getMetadata(events[0].metadata) : {}, - ...events.length && events[0].metadata ? getTransformationMetadata(events[0].metadata) : {} - } + ...(events.length && events[0].metadata ? getMetadata(events[0].metadata) : {}), + ...(events.length && events[0].metadata ? getTransformationMetadata(events[0].metadata) : {}), + }; stats.counter('user_transform_function_input_events', events.length, tags); stats.timing('user_transform_function_latency', invokeTime, tags); } diff --git a/src/util/customTransformer.js b/src/util/customTransformer.js index 001fe3216cf..a87c12dd6e2 100644 --- a/src/util/customTransformer.js +++ b/src/util/customTransformer.js @@ -254,9 +254,9 @@ async function runUserTransform( const tags = { identifier: 'v0', errored: transformationError ? true : false, - ...events.length && events[0].metadata ? getMetadata(events[0].metadata) : {}, - ...events.length && events[0].metadata ? getTransformationMetadata(events[0].metadata) : {} - } + ...(events.length && events[0].metadata ? getMetadata(events[0].metadata) : {}), + ...(events.length && events[0].metadata ? getTransformationMetadata(events[0].metadata) : {}), + }; stats.counter('user_transform_function_input_events', events.length, tags); stats.timing('user_transform_function_latency', invokeTime, tags); diff --git a/src/util/customTransformerFactory.js b/src/util/customTransformerFactory.js index 1bf10e5d458..ee535319460 100644 --- a/src/util/customTransformerFactory.js +++ b/src/util/customTransformerFactory.js @@ -1,12 +1,6 @@ -const { - setOpenFaasUserTransform, - runOpenFaasUserTransform, -} = require('./customTransformer-faas'); +const { setOpenFaasUserTransform, runOpenFaasUserTransform } = require('./customTransformer-faas'); -const { - userTransformHandlerV1, - setUserTransformHandlerV1, -} = require('./customTransformer-v1'); +const { userTransformHandlerV1, setUserTransformHandlerV1 } = require('./customTransformer-v1'); const UserTransformHandlerFactory = (userTransformation) => { return { @@ -23,20 +17,10 @@ const UserTransformHandlerFactory = (userTransformation) => { switch (userTransformation.language) { case 'pythonfaas': case 'python': - return runOpenFaasUserTransform( - events, - userTransformation, - libraryVersionIds, - testMode - ); + return runOpenFaasUserTransform(events, userTransformation, libraryVersionIds, testMode); default: - return userTransformHandlerV1( - events, - userTransformation, - libraryVersionIds, - testMode - ); + return userTransformHandlerV1(events, userTransformation, libraryVersionIds, testMode); } }, }; diff --git a/src/util/error-extractor/index.ts b/src/util/error-extractor/index.ts index b8cfef4136a..6ff374b8697 100644 --- a/src/util/error-extractor/index.ts +++ b/src/util/error-extractor/index.ts @@ -1,16 +1,18 @@ /* eslint-disable max-classes-per-file */ -import { MessageDetails, StatusCode } from "./types"; +import { MessageDetails, StatusCode, Stat } from './types'; export class ErrorDetailsExtractor { status: StatusCode; messageDetails: MessageDetails; - constructor (builder: ErrorDetailsExtractorBuilder) { + stat: Stat; + + constructor(builder: ErrorDetailsExtractorBuilder) { this.status = builder.getStatus(); this.messageDetails = builder.getMessageDetails(); + this.stat = builder.getStat(); } - } export class ErrorDetailsExtractorBuilder { @@ -18,21 +20,29 @@ export class ErrorDetailsExtractorBuilder { messageDetails: MessageDetails; + stat: Stat; + constructor() { this.status = 0; this.messageDetails = {}; + this.stat = {}; } - + setStatus(status: number): ErrorDetailsExtractorBuilder { this.status = status; return this; } + setStat(stat: Record): ErrorDetailsExtractorBuilder { + this.stat = stat; + return this; + } + /** * This means we need to set a message from a specific field that we see from the destination's response - * + * * @param {string} fieldPath -- Path of the field which should be set as "error message" - * @returns + * @returns */ setMessageField(fieldPath: string): ErrorDetailsExtractorBuilder { if (this.messageDetails?.message) { @@ -40,16 +50,16 @@ export class ErrorDetailsExtractorBuilder { return this; } this.messageDetails = { - field: fieldPath - } + field: fieldPath, + }; return this; } /** * This means we need to set the message provided - * + * * @param {string} msg - error message - * @returns + * @returns */ setMessage(msg: string): ErrorDetailsExtractorBuilder { if (this.messageDetails?.field) { @@ -57,22 +67,24 @@ export class ErrorDetailsExtractorBuilder { return this; } this.messageDetails = { - message: msg - } + message: msg, + }; return this; } build(): ErrorDetailsExtractor { - return new ErrorDetailsExtractor(this) + return new ErrorDetailsExtractor(this); } getStatus(): number { return this.status; } - + + getStat(): Record { + return this.stat; + } + getMessageDetails(): Record { return this.messageDetails; } } - - diff --git a/src/util/error-extractor/types.ts b/src/util/error-extractor/types.ts index 7c500177cb3..b93d2fafe50 100644 --- a/src/util/error-extractor/types.ts +++ b/src/util/error-extractor/types.ts @@ -1,2 +1,3 @@ export type MessageDetails = Record; -export type StatusCode = number; \ No newline at end of file +export type StatusCode = number; +export type Stat = Record; diff --git a/src/util/fetchDestinationHandlers.ts b/src/util/fetchDestinationHandlers.ts new file mode 100644 index 00000000000..2661ef2e686 --- /dev/null +++ b/src/util/fetchDestinationHandlers.ts @@ -0,0 +1,42 @@ +import * as V0MarketoBulkUploadFileUpload from '../v0/destinations/marketo_bulk_upload/fileUpload'; +import * as V0MarketoBulkUploadPollStatus from '../v0/destinations/marketo_bulk_upload/poll'; +import * as V0MarketoBulkUploadJobStatus from '../v0/destinations/marketo_bulk_upload/fetchJobStatus'; + +const fileUploadHandlers = { + v0: { + marketo_bulk_upload: V0MarketoBulkUploadFileUpload, + }, +}; + +const pollStatusHandlers = { + v0: { + marketo_bulk_upload: V0MarketoBulkUploadPollStatus, + }, +}; + +const jobStatusHandlers = { + v0: { + marketo_bulk_upload: V0MarketoBulkUploadJobStatus, + }, +}; + +export const getDestFileUploadHandler = (version, dest) => { + if (fileUploadHandlers[version] && fileUploadHandlers[version][dest]) { + return fileUploadHandlers[version][dest]; + } + return undefined; +}; + +export const getPollStatusHandler = (version, dest) => { + if (pollStatusHandlers[version] && pollStatusHandlers[version][dest]) { + return pollStatusHandlers[version][dest]; + } + return undefined; +}; + +export const getJobStatusHandler = (version, dest) => { + if (jobStatusHandlers[version] && jobStatusHandlers[version][dest]) { + return jobStatusHandlers[version][dest]; + } + return undefined; +}; diff --git a/src/util/ivmFactory.js b/src/util/ivmFactory.js index 2ab5f9548aa..9a6419295d6 100644 --- a/src/util/ivmFactory.js +++ b/src/util/ivmFactory.js @@ -23,7 +23,9 @@ async function evaluateModule(isolate, context, moduleCode) { } async function loadModule(isolateInternal, contextInternal, moduleName, moduleCode) { - const module = await isolateInternal.compileModule(moduleCode, { filename: `library ${moduleName}` }); + const module = await isolateInternal.compileModule(moduleCode, { + filename: `library ${moduleName}`, + }); await module.instantiate(contextInternal, () => {}); return module; } @@ -256,7 +258,7 @@ async function createIvm(code, libraryVersionIds, versionId, secrets, testMode) } }); - await jail.set('extractStackTrace', function(trace, stringLiterals) { + await jail.set('extractStackTrace', function (trace, stringLiterals) { return extractStackTraceUptoLastSubstringMatch(trace, stringLiterals); }); @@ -346,7 +348,9 @@ async function createIvm(code, libraryVersionIds, versionId, secrets, testMode) // Now we can execute the script we just compiled: const bootstrapScriptResult = await bootstrap.run(context); // const customScript = await isolate.compileScript(`${library} ;\n; ${code}`); - const customScriptModule = await isolate.compileModule(`${codeWithWrapper}`, { filename: 'base transformation' }); + const customScriptModule = await isolate.compileModule(`${codeWithWrapper}`, { + filename: 'base transformation', + }); await customScriptModule.instantiate(context, async (spec) => { if (librariesMap[spec]) { return compiledModules[spec].module; diff --git a/src/util/prometheus.js b/src/util/prometheus.js index d7ba3b7c611..c2a7470b18e 100644 --- a/src/util/prometheus.js +++ b/src/util/prometheus.js @@ -497,7 +497,7 @@ class Prometheus { name: 'shopify_anon_id_resolve', help: 'shopify_anon_id_resolve', type: 'counter', - labelNames: ['method', 'writeKey', 'shopifyTopic'], + labelNames: ['method', 'writeKey', 'shopifyTopic', 'source'], }, { name: 'shopify_redis_calls', @@ -533,7 +533,15 @@ class Prometheus { name: 'outgoing_request_count', help: 'Outgoing HTTP requests count', type: 'counter', - labelNames: ['feature', 'destType', 'endpointPath', 'success', 'statusCode'], + labelNames: [ + 'feature', + 'destType', + 'endpointPath', + 'success', + 'statusCode', + 'requestMethod', + 'module', + ], }, // Gauges @@ -567,13 +575,31 @@ class Prometheus { type: 'gauge', labelNames: ['destination_id'], }, + { + name: 'mixpanel_batch_engage_pack_size', + help: 'mixpanel_batch_engage_pack_size', + type: 'gauge', + labelNames: ['destination_id'], + }, + { + name: 'mixpanel_batch_group_pack_size', + help: 'mixpanel_batch_group_pack_size', + type: 'gauge', + labelNames: ['destination_id'], + }, + { + name: 'mixpanel_batch_import_pack_size', + help: 'mixpanel_batch_import_pack_size', + type: 'gauge', + labelNames: ['destination_id'], + }, // Histograms { name: 'outgoing_request_latency', help: 'Outgoing HTTP requests duration in seconds', type: 'histogram', - labelNames: ['feature', 'destType', 'endpointPath'], + labelNames: ['feature', 'destType', 'endpointPath', 'requestMethod', 'module'], }, { name: 'http_request_duration', @@ -582,14 +608,38 @@ class Prometheus { labelNames: ['method', 'route', 'code'], }, { - name: 'tp_request_size', - help: 'tp_request_size', + name: 'tp_batch_size', + help: 'Size of batch of events for tracking plan validation', type: 'histogram', - labelNames: ['sourceType', 'destinationType', 'k8_namespace'], + buckets: [ + 1024, 102400, 524288, 1048576, 10485760, 20971520, 52428800, 104857600, 209715200, + 524288000, + ], + labelNames: [ + 'sourceType', + 'destinationType', + 'k8_namespace', + 'workspaceId', + 'trackingPlanId', + ], }, { - name: 'tp_request_latency', - help: 'tp_request_latency', + name: 'tp_event_validation_latency', + help: 'Latency of validating tracking plan at event level', + type: 'histogram', + labelNames: [ + 'sourceType', + 'destinationType', + 'k8_namespace', + 'workspaceId', + 'trackingPlanId', + 'status', + 'exception', + ], + }, + { + name: 'tp_batch_validation_latency', + help: 'Latency of validating tracking plan at batch level', type: 'histogram', labelNames: [ 'sourceType', @@ -642,6 +692,22 @@ class Prometheus { 'k8_namespace', ], }, + { + name: 'user_transform_batch_size', + help: 'user_transform_batch_size', + type: 'histogram', + labelNames: [ + 'workspaceId', + 'transformationId', + 'sourceType', + 'destinationType', + 'k8_namespace', + ], + buckets: [ + 1024, 102400, 524288, 1048576, 10485760, 20971520, 52428800, 104857600, 209715200, + 524288000, + ], // 1KB, 100KB, 0.5MB, 1MB, 10MB, 20MB, 50MB, 100MB, 200MB, 500MB + }, { name: 'source_transform_request_latency', help: 'source_transform_request_latency', @@ -702,7 +768,7 @@ class Prometheus { name: 'get_libraries_code_time', help: 'get_libraries_code_time', type: 'histogram', - labelNames: ['libraryVersionId', 'versionId', 'type'], + labelNames: ['libraryVersionId', 'versionId', 'type', 'version'], }, { name: 'isolate_cpu_time', diff --git a/src/util/redis/redisConnector.test.js b/src/util/redis/redisConnector.test.js index 840f222e373..e0491132ffd 100644 --- a/src/util/redis/redisConnector.test.js +++ b/src/util/redis/redisConnector.test.js @@ -70,7 +70,7 @@ describe(`Redis Class Get Tests`, () => { data.forEach((dataPoint, index) => { it(`${index}. Redis Get- ${dataPoint.description}`, async () => { try { - const output = await RedisDB.getVal(dataPoint.input.value, (isObjExpected = false)); + const output = await RedisDB.getVal(dataPoint.input.value, false); expect(output).toEqual(dataPoint.output); } catch (error) { expect(error.message).toEqual(dataPoint.output.error); diff --git a/src/util/redis/testData/shopify_source.json b/src/util/redis/testData/shopify_source.json index 53c60472988..04b80b8fc96 100644 --- a/src/util/redis/testData/shopify_source.json +++ b/src/util/redis/testData/shopify_source.json @@ -5,7 +5,8 @@ "user_id": "rudder01", "id": "shopify_test_get_items_fail", "query_parameters": { - "topic": ["carts_update"] + "topic": ["carts_update"], + "writeKey": ["wr"] }, "token": "shopify_test_get_items_fail", "email": "test@rudderstack.com", @@ -115,7 +116,8 @@ "input": { "cart_token": "shopifyGetAnonymousId", "query_parameters": { - "topic": ["checkouts_delete"] + "topic": ["checkouts_delete"], + "writeKey": ["wr"] }, "line_items": [], "note": null, @@ -154,7 +156,8 @@ "input": { "id": "shopify_test3", "query_parameters": { - "topic": ["carts_update"] + "topic": ["carts_update"], + "writeKey": ["wr"] }, "token": "shopify_test3", "line_items": [], @@ -252,7 +255,8 @@ "user_id": "rudder01", "id": "shopify_test_cart", "query_parameters": { - "topic": ["carts_update"] + "topic": ["carts_update"], + "writeKey": ["wr"] }, "token": "shopify_test_cart", "email": "test@rudderstack.com", @@ -1256,7 +1260,8 @@ "input": { "id": "shopify_test4", "query_parameters": { - "topic": ["carts_update"] + "topic": ["carts_update"], + "writeKey": ["wr"] }, "token": "shopify_test4", "line_items": [], diff --git a/src/util/stats.js b/src/util/stats.js index e57ab85731e..9a32fd1de3b 100644 --- a/src/util/stats.js +++ b/src/util/stats.js @@ -13,17 +13,19 @@ function init() { switch (statsClientType) { case 'statsd': - logger.info("setting up statsd client") + logger.info('setting up statsd client'); statsClient = new statsd.Statsd(); break; case 'prometheus': - logger.info("setting up prometheus client") + logger.info('setting up prometheus client'); statsClient = new prometheus.Prometheus(); break; default: - logger.error(`invalid stats client type: ${statsClientType}, supported values are 'statsd' and 'prometheues'`) + logger.error( + `invalid stats client type: ${statsClientType}, supported values are 'statsd' and 'prometheues'`, + ); } } diff --git a/src/v0/destinations/active_campaign/transform.js b/src/v0/destinations/active_campaign/transform.js index 981dbd7520d..3978f868b18 100644 --- a/src/v0/destinations/active_campaign/transform.js +++ b/src/v0/destinations/active_campaign/transform.js @@ -62,6 +62,8 @@ const syncContact = async (contactPayload, category, destination) => { destType: 'active_campaign', feature: 'transformation', endpointPath: endPoint, + requestMethod: 'POST', + module: 'router', }); if (res.success === false) { errorHandler(res, 'Failed to create new contact'); @@ -129,6 +131,8 @@ const customTagProcessor = async (message, category, destination, contactId) => destType: 'active_campaign', feature: 'transformation', endpointPath: `/api/3/tags`, + requestMethod: 'GET', + module: 'router', }); promises.push(resp); } @@ -253,6 +257,8 @@ const customFieldProcessor = async (message, category, destination) => { destType: 'active_campaign', feature: 'transformation', endpointPath: `/api/3/fields`, + requestMethod: 'GET', + module: 'router', }); promises.push(resp); } @@ -351,6 +357,8 @@ const customListProcessor = async (message, category, destination, contactId) => destType: 'active_campaign', feature: 'transformation', endpointPath: mergeListWithContactUrl, + requestMethod: 'POST', + module: 'router', }); promises.push(res); } @@ -409,6 +417,8 @@ const screenRequestHandler = async (message, category, destination) => { destType: 'active_campaign', feature: 'transformation', endpointPath: `/api/3/eventTrackingEvents`, + requestMethod: 'GET', + module: 'router', }); if (res.success === false) { errorHandler(res, 'Failed to retrieve events'); @@ -473,6 +483,8 @@ const trackRequestHandler = async (message, category, destination) => { destType: 'active_campaign', feature: 'transformation', endpointPath: `/api/3/eventTrackingEvents`, + requestMethod: 'GET', + module: 'router', }); if (res.success === false) { diff --git a/src/v0/destinations/adobe_analytics/networkHandler.js b/src/v0/destinations/adobe_analytics/networkHandler.js index 0ec1fad2869..8715721f853 100644 --- a/src/v0/destinations/adobe_analytics/networkHandler.js +++ b/src/v0/destinations/adobe_analytics/networkHandler.js @@ -15,7 +15,9 @@ function extractContent(xmlPayload, tagName) { return match ? match[1] : null; } -const responseHandler = (destinationResponse, dest) => { +const responseHandler = (responseParams) => { + const { destinationResponse, destType } = responseParams; + const message = `[${DESTINATION}] - Request Processed Successfully`; const { response, status } = destinationResponse; @@ -27,11 +29,11 @@ const responseHandler = (destinationResponse, dest) => { if (responseStatus === 'FAILURE') { if (reason) { throw new InstrumentationError( - `[${DESTINATION} Response Handler] Request failed for destination ${dest} : ${reason}`, + `[${DESTINATION} Response Handler] Request failed for destination ${destType} : ${reason}`, ); } else { throw new InstrumentationError( - `[${DESTINATION} Response Handler] Request failed for destination ${dest} with a general error`, + `[${DESTINATION} Response Handler] Request failed for destination ${destType} with a general error`, ); } } diff --git a/src/v0/destinations/adobe_analytics/transform.js b/src/v0/destinations/adobe_analytics/transform.js index b4281387249..5d3d6e7d00f 100644 --- a/src/v0/destinations/adobe_analytics/transform.js +++ b/src/v0/destinations/adobe_analytics/transform.js @@ -18,6 +18,7 @@ const { getIntegrationsObj, removeUndefinedAndNullValues, simpleProcessRouterDest, + validateEventAndLowerCaseConversion, } = require('../../util'); const { @@ -307,7 +308,7 @@ const processTrackEvent = (message, adobeEventName, destinationConfig, extras = destinationConfig; const { event: rawMessageEvent, properties } = message; const { overrideEventString, overrideProductString } = properties; - const event = rawMessageEvent.toLowerCase(); + const event = validateEventAndLowerCaseConversion(rawMessageEvent, true, true); const adobeEventArr = adobeEventName ? adobeEventName.split(',') : []; // adobeEventArr is an array of events which is defined as // ["eventName", "mapped Adobe Event=mapped merchproperty's value", "mapped Adobe Event=mapped merchproperty's value", . . .] diff --git a/src/v0/destinations/adobe_analytics/utils.js b/src/v0/destinations/adobe_analytics/utils.js index 97dc6e90bbd..ceba177ff14 100644 --- a/src/v0/destinations/adobe_analytics/utils.js +++ b/src/v0/destinations/adobe_analytics/utils.js @@ -93,7 +93,7 @@ function escapeToHTML(inputString) { '&': '&', '<': '<', '>': '>', - }[match]), + })[match], ); } diff --git a/src/v0/destinations/af/deleteUsers.js b/src/v0/destinations/af/deleteUsers.js index bb711292c00..ab515642aaa 100644 --- a/src/v0/destinations/af/deleteUsers.js +++ b/src/v0/destinations/af/deleteUsers.js @@ -39,6 +39,8 @@ const deleteUser = async (config, endpoint, body, identityType, identityValue) = destType: 'af', feature: 'deleteUsers', endpointPath: `appsflyer.com/api/gdpr/v1/opendsr_requests`, + requestMethod: 'POST', + module: 'deletion', }, ); const handledDelResponse = processAxiosResponse(response); @@ -48,6 +50,7 @@ const deleteUser = async (config, endpoint, body, identityType, identityValue) = handledDelResponse.status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(handledDelResponse.status), + [tags.TAG_NAMES.STATUS]: handledDelResponse.status, }, handledDelResponse, ); diff --git a/src/v0/destinations/af/transform.js b/src/v0/destinations/af/transform.js index 4d7ed7e635c..d6c41937a1e 100644 --- a/src/v0/destinations/af/transform.js +++ b/src/v0/destinations/af/transform.js @@ -113,9 +113,20 @@ function getEventValueForUnIdentifiedTrackEvent(message) { return { eventValue }; } -function getEventValueMapFromMappingJson(message, mappingJson, isMultiSupport) { +function getEventValueMapFromMappingJson( + message, + mappingJson, + isMultiSupport, + addPropertiesAtRoot, +) { let eventValue = {}; - set(eventValue, 'properties', message.properties); + + if (addPropertiesAtRoot) { + eventValue = message.properties; + } else { + set(eventValue, 'properties', message.properties); + } + const sourceKeys = Object.keys(mappingJson); sourceKeys.forEach((sourceKey) => { set(eventValue, mappingJson[sourceKey], get(message, sourceKey)); @@ -160,7 +171,7 @@ function processNonTrackEvents(message, eventName) { return payload; } -function processEventTypeTrack(message) { +function processEventTypeTrack(message, addPropertiesAtRoot) { let isMultiSupport = true; const evType = message.event && message.event.toLowerCase(); let category = ConfigCategory.DEFAULT; @@ -184,6 +195,7 @@ function processEventTypeTrack(message) { message, mappingConfig[category.name], isMultiSupport, + addPropertiesAtRoot, ); payload.eventName = message.event; payload.eventCurrency = message?.properties?.currency; @@ -196,7 +208,7 @@ function processSingleMessage(message, destination) { let payload; switch (messageType) { case EventType.TRACK: { - payload = processEventTypeTrack(message); + payload = processEventTypeTrack(message, destination.Config.addPropertiesAtRoot); break; } case EventType.SCREEN: { diff --git a/src/v0/destinations/am/config.js b/src/v0/destinations/am/config.js index 3e51a671371..78f8d43e948 100644 --- a/src/v0/destinations/am/config.js +++ b/src/v0/destinations/am/config.js @@ -136,5 +136,5 @@ module.exports = { batchEventsWithUserIdLengthLowerThanFive, IDENTIFY_AM, AMBatchSizeLimit, - AMBatchEventLimit + AMBatchEventLimit, }; diff --git a/src/v0/destinations/am/deleteUsers.js b/src/v0/destinations/am/deleteUsers.js index 6de9cf64a18..96c4f7b19c7 100644 --- a/src/v0/destinations/am/deleteUsers.js +++ b/src/v0/destinations/am/deleteUsers.js @@ -43,6 +43,8 @@ const userDeletionHandler = async (userAttributes, config) => { destType: 'am', feature: 'deleteUsers', endpointPath, + requestMethod: 'POST', + module: 'deletion', }); const handledDelResponse = processAxiosResponse(resp); if (!isHttpStatusSuccess(handledDelResponse.status)) { @@ -51,6 +53,7 @@ const userDeletionHandler = async (userAttributes, config) => { handledDelResponse.status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(handledDelResponse.status), + [tags.TAG_NAMES.STATUS]: handledDelResponse.status, }, handledDelResponse, ); diff --git a/src/v0/destinations/am/transform.js b/src/v0/destinations/am/transform.js index 911ec51be08..ce157e76743 100644 --- a/src/v0/destinations/am/transform.js +++ b/src/v0/destinations/am/transform.js @@ -22,13 +22,13 @@ const { getFieldValueFromMessage, getValueFromMessage, deleteObjectProperty, - getErrorRespEvents, removeUndefinedAndNullValues, isDefinedAndNotNull, isAppleFamily, isDefinedAndNotNullAndNotEmpty, simpleProcessRouterDest, isValidInteger, + handleRtTfSingleEventError, } = require('../../util'); const { BASE_URL, @@ -40,7 +40,6 @@ const { AMBatchSizeLimit, AMBatchEventLimit, } = require('./config'); -const tags = require('../../util/tags'); const AMUtils = require('./utils'); @@ -269,7 +268,7 @@ const updateConfigProperty = (message, payload, mappingJson, validatePayload, Co } }); }; -const identifyBuilder = (message, destination, rawPayload) => { +const userPropertiesHandler = (message, destination, rawPayload) => { // update payload user_properties from userProperties/traits/context.traits/nested traits of Rudder message // traits like address converted to top level user properties (think we can skip this extra processing as AM supports nesting upto 40 levels) let traits = getFieldValueFromMessage(message, 'traits'); @@ -336,6 +335,7 @@ const getDefaultResponseData = (message, rawPayload, evType, groupInfo) => { const groups = groupInfo && cloneDeep(groupInfo); return { groups, rawPayload }; }; + const getResponseData = (evType, destination, rawPayload, message, groupInfo) => { let groups; @@ -343,7 +343,7 @@ const getResponseData = (evType, destination, rawPayload, message, groupInfo) => case EventType.IDENTIFY: // event_type for identify event is $identify rawPayload.event_type = IDENTIFY_AM; - rawPayload = identifyBuilder(message, destination, rawPayload); + rawPayload = userPropertiesHandler(message, destination, rawPayload); break; case EventType.GROUP: // event_type for identify event is $identify @@ -358,8 +358,15 @@ const getResponseData = (evType, destination, rawPayload, message, groupInfo) => case EventType.ALIAS: break; default: + if (destination.Config.enableEnhancedUserOperations) { + // handle all other events like track, page, screen for user properties + rawPayload = userPropertiesHandler(message, destination, rawPayload); + } ({ groups, rawPayload } = getDefaultResponseData(message, rawPayload, evType, groupInfo)); } + if (destination.Config.enableEnhancedUserOperations) { + rawPayload = AMUtils.userPropertiesPostProcess(rawPayload); + } return { rawPayload, groups }; }; @@ -518,6 +525,9 @@ const responseBuilderSimple = ( ...campaign, }; + // we are updating the payload with skip_user_properties_sync + AMUtils.updateWithSkipAttribute(message, rawPayload); + const respData = getResponseData(evType, destination, rawPayload, message, groupInfo); const { groups, rawPayload: updatedRawPayload } = respData; @@ -615,16 +625,16 @@ const processSingleMessage = (message, destination) => { case EventType.PAGE: if (useUserDefinedPageEventName) { const getMessagePath = userProvidedPageEventString - .substring( + ?.substring( userProvidedPageEventString.indexOf('{') + 2, userProvidedPageEventString.indexOf('}'), ) .trim(); evType = - userProvidedPageEventString.trim() === '' + userProvidedPageEventString?.trim() === '' ? name : userProvidedPageEventString - .trim() + ?.trim() .replaceAll(/{{([^{}]+)}}/g, get(message, getMessagePath)); } else { evType = `Viewed ${name || get(message, CATEGORY_KEY) || ''} Page`; @@ -702,6 +712,7 @@ const processSingleMessage = (message, destination) => { logger.debug('could not determine type'); throw new InstrumentationError('message type not supported'); } + AMUtils.validateEventType(evType); return responseBuilderSimple( groupInfo, payloadObjectName, @@ -904,16 +915,10 @@ const batch = (destEvents) => { // this case shold not happen and should be filtered already // by the first pass of single event transformation if (messageEvent && !userId && !deviceId) { - const errorResponse = getErrorRespEvents( - metadata, - 400, + const MissingUserIdDeviceIdError = new InstrumentationError( 'Both userId and deviceId cannot be undefined', - { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.DATA_VALIDATION, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.INSTRUMENTATION, - }, ); - respList.push(errorResponse); + respList.push(handleRtTfSingleEventError(ev, MissingUserIdDeviceIdError, {})); return; } /* check if not a JSON body or (userId length < 5 && batchEventsWithUserIdLengthLowerThanFive is false) or diff --git a/src/v0/destinations/am/util.test.js b/src/v0/destinations/am/util.test.js index faaa9170f04..498980d1823 100644 --- a/src/v0/destinations/am/util.test.js +++ b/src/v0/destinations/am/util.test.js @@ -1,4 +1,9 @@ -const { getUnsetObj } = require('./utils'); +const { + getUnsetObj, + validateEventType, + userPropertiesPostProcess, + updateWithSkipAttribute, +} = require('./utils'); describe('getUnsetObj', () => { it("should return undefined when 'message.integrations.Amplitude.fieldsToUnset' is not array", () => { @@ -64,3 +69,131 @@ describe('getUnsetObj', () => { expect(result).toBeUndefined(); }); }); + +describe('validateEventType', () => { + it('should validate event type when it is valid with only page name given', () => { + expect(() => { + validateEventType('Home Page'); + }).not.toThrow(); + }); + + it('should throw an error when event type is null', () => { + expect(() => { + validateEventType(null); + }).toThrow( + 'Event type is missing. Please send it under `event.type`. For page/screen events, send it under `event.name`', + ); + }); + + it('should throw an error when event type is undefined', () => { + expect(() => { + validateEventType(undefined); + }).toThrow( + 'Event type is missing. Please send it under `event.type`. For page/screen events, send it under `event.name`', + ); + }); + + // Function receives an empty string as event type + it('should throw an error when event type is an empty string', () => { + expect(() => { + validateEventType(''); + }).toThrow( + 'Event type is missing. Please send it under `event.type`. For page/screen events, send it under `event.name`', + ); + }); +}); + +describe('userPropertiesPostProcess', () => { + // The function correctly removes duplicate keys found in both operation keys and root level keys. + it('should remove duplicate keys from user_properties', () => { + // Arrange + const rawPayload = { + user_properties: { + $setOnce: { + key1: 'value1', + }, + $add: { + key2: 'value2', + }, + key3: 'value3', + key1: 'value4', + }, + }; + + // Act + const result = userPropertiesPostProcess(rawPayload); + + // Assert + expect(result.user_properties).toEqual({ + $setOnce: { + key1: 'value1', + }, + $add: { + key2: 'value2', + }, + $set: { + key3: 'value3', + }, + }); + }); + + // The function correctly moves root level properties to $set operation. + it('should move root level properties to $set operation when they dont belong to any other operation', () => { + // Arrange + const rawPayload = { + user_properties: { + $setOnce: { + key1: 'value1', + }, + $add: { + key2: 'value2', + }, + key3: 'value3', + }, + }; + + // Act + const result = userPropertiesPostProcess(rawPayload); + + // Assert + expect(result.user_properties).toEqual({ + $set: { + key3: 'value3', + }, + $setOnce: { + key1: 'value1', + }, + $add: { + key2: 'value2', + }, + }); + }); +}); + +describe('updateWithSkipAttribute', () => { + // when 'skipUserPropertiesSync ' is present in 'integrations.Amplitude', return the original payload. + it("should return the original payload when 'skipUserPropertiesSync' is present", () => { + const message = { integrations: { Amplitude: { skipUserPropertiesSync: true } } }; + const payload = { key: 'value' }; + const expectedPayload = { key: 'value', $skip_user_properties_sync: true }; + updateWithSkipAttribute(message, payload); + expect(expectedPayload).toEqual(payload); + }); + + // When 'skipUserPropertiesSync' is not present in 'integrations.Amplitude', return the original payload. + it("should return the original payload when 'skipUserPropertiesSync' is not present", () => { + const message = { integrations: { Amplitude: {} } }; + const payload = { key: 'value' }; + const expectedPayload = { key: 'value' }; + updateWithSkipAttribute(message, payload); + expect(payload).toEqual(expectedPayload); + }); + // When 'message' is null, return null. + it("should return null when 'message' is null", () => { + const message = null; + const payload = { key: 'value' }; + const expectedPayload = { key: 'value' }; + updateWithSkipAttribute(message, payload); + expect(payload).toEqual(expectedPayload); + }); +}); diff --git a/src/v0/destinations/am/utils.js b/src/v0/destinations/am/utils.js index 71fe0ab4590..8de899182bb 100644 --- a/src/v0/destinations/am/utils.js +++ b/src/v0/destinations/am/utils.js @@ -10,6 +10,8 @@ // populate these dest keys const get = require('get-value'); const uaParser = require('@amplitude/ua-parser-js'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); +const set = require('set-value'); const logger = require('../../../logger'); const { isDefinedAndNotNull } = require('../../util'); @@ -108,6 +110,80 @@ const getUnsetObj = (message) => { return unsetObject; }; + +const updateWithSkipAttribute = (message, payload) => { + const skipAttribute = get(message, 'integrations.Amplitude.skipUserPropertiesSync'); + if (skipAttribute) { + set(payload, '$skip_user_properties_sync', true); + } +}; + +/** + * Check for evType as in some cases, like when the page name is absent, + * either the template depends only on the event.name or there is no template provided by user + * @param {*} evType + */ +const validateEventType = (evType) => { + if (!isDefinedAndNotNull(evType) || (typeof evType === 'string' && evType.length === 0)) { + throw new InstrumentationError( + 'Event type is missing. Please send it under `event.type`. For page/screen events, send it under `event.name`', + ); + } +}; + +const userPropertiesPostProcess = (rawPayload) => { + const operationList = [ + '$setOnce', + '$add', + '$unset', + '$append', + '$prepend', + '$preInsert', + '$postInsert', + '$remove', + ]; + // eslint-disable-next-line @typescript-eslint/naming-convention + const { user_properties } = rawPayload; + const userPropertiesKeys = Object.keys(user_properties).filter( + (key) => !operationList.includes(key), + ); + const duplicatekeys = new Set(); + // eslint-disable-next-line no-restricted-syntax, guard-for-in + for (const key of userPropertiesKeys) { + // check if any of the keys are present in the user_properties $setOnce, $add, $unset, $append, $prepend, $preInsert, $postInsert, $remove keys as well as root level + + if ( + operationList.some( + (operation) => user_properties[operation] && user_properties[operation][key], + ) + ) { + duplicatekeys.add(key); + } + } + // eslint-disable-next-line no-restricted-syntax, guard-for-in + for (const key of duplicatekeys) { + delete user_properties[key]; + } + + // Moving root level properties that doesn't belong to any operation under $set + const setProps = {}; + // eslint-disable-next-line no-restricted-syntax + for (const [key, value] of Object.entries(user_properties)) { + if (!operationList.includes(key)) { + setProps[key] = value; + delete user_properties[key]; + } + } + + if (Object.keys(setProps).length > 0) { + user_properties.$set = setProps; + } + + // eslint-disable-next-line no-param-reassign + rawPayload.user_properties = user_properties; + return rawPayload; +}; + module.exports = { getOSName, getOSVersion, @@ -117,4 +193,7 @@ module.exports = { getBrand, getEventId, getUnsetObj, + validateEventType, + userPropertiesPostProcess, + updateWithSkipAttribute, }; diff --git a/src/v0/destinations/bqstream/transform.js b/src/v0/destinations/bqstream/transform.js index 598a97946d3..8ee96aecf15 100644 --- a/src/v0/destinations/bqstream/transform.js +++ b/src/v0/destinations/bqstream/transform.js @@ -5,7 +5,6 @@ const { EventType } = require('../../../constants'); const { defaultBatchRequestConfig, getSuccessRespEvents, - checkInvalidRtTfEvents, handleRtTfSingleEventError, groupEventsByType, } = require('../../util'); @@ -130,10 +129,6 @@ const processEachTypedEventList = ( }; const processRouterDest = (inputs) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs, DESTINATION); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } const finalResp = []; const batchedEvents = groupEventsByType(inputs); diff --git a/src/v0/destinations/branch/transform.js b/src/v0/destinations/branch/transform.js index 23dcd6c8db4..2626d8aa812 100644 --- a/src/v0/destinations/branch/transform.js +++ b/src/v0/destinations/branch/transform.js @@ -13,6 +13,7 @@ const { simpleProcessRouterDest, } = require('../../util'); const { JSON_MIME_TYPE } = require('../../util/constant'); +const { getMappedEventNameFromConfig } = require('./utils'); function responseBuilder(payload, message, destination, category) { const response = defaultRequestConfig(); @@ -213,24 +214,21 @@ function getCommonPayload(message, category, evName) { return rawPayload; } -// function getTrackPayload(message) { -// const rawPayload = {}; -// const { name, category } = getCategoryAndName(message.event); -// rawPayload.name = name; -// -// return commonPayload(message, rawPayload, category); -// } - function processMessage(message, destination) { let evName; let category; switch (message.type) { - case EventType.TRACK: + case EventType.TRACK: { if (!message.event) { throw new InstrumentationError('Event name is required'); } ({ evName, category } = getCategoryAndName(message.event)); + const eventNameFromConfig = getMappedEventNameFromConfig(message, destination); + if (eventNameFromConfig) { + evName = eventNameFromConfig; + } break; + } case EventType.IDENTIFY: ({ evName, category } = getCategoryAndName(message.userId)); break; diff --git a/src/v0/destinations/branch/utils.js b/src/v0/destinations/branch/utils.js new file mode 100644 index 00000000000..1415f0de391 --- /dev/null +++ b/src/v0/destinations/branch/utils.js @@ -0,0 +1,24 @@ +const { getHashFromArray } = require('../../util'); + +/** + * Retrieves the mapped event name from the given config. + * + * @param {object} message - The message object containing the event. + * @param {object} destination - The destination object containing the events mapping configuration. + * @returns {string} - The mapped event name, or undefined if not found. + */ +const getMappedEventNameFromConfig = (message, destination) => { + let eventName; + const { event } = message; + const { eventsMapping } = destination.Config; + + // if event is mapped on dashboard, use the mapped event name + if (Array.isArray(eventsMapping) && eventsMapping.length > 0) { + const keyMap = getHashFromArray(eventsMapping, 'from', 'to', false); + eventName = keyMap[event]; + } + + return eventName; +}; + +module.exports = { getMappedEventNameFromConfig }; diff --git a/src/v0/destinations/branch/utils.test.js b/src/v0/destinations/branch/utils.test.js new file mode 100644 index 00000000000..e7da007d898 --- /dev/null +++ b/src/v0/destinations/branch/utils.test.js @@ -0,0 +1,18 @@ +const { getMappedEventNameFromConfig } = require('./utils'); +describe('getMappedEventNameFromConfig', () => { + it('should return the mapped event name when it exists in the events mapping configuration', () => { + const message = { event: 'Order Completed' }; + const destination = { + Config: { eventsMapping: [{ from: 'Order Completed', to: 'PURCHASE' }] }, + }; + const result = getMappedEventNameFromConfig(message, destination); + expect(result).toBe('PURCHASE'); + }); + + it('should return undefined when the event mapping is not created', () => { + const message = { event: 'Order Completed' }; + const destination = { Config: {} }; + const result = getMappedEventNameFromConfig(message, destination); + expect(result).toBeUndefined(); + }); +}); diff --git a/src/v0/destinations/braze/braze.util.test.js b/src/v0/destinations/braze/braze.util.test.js index 9e82a235f11..7b6a93d3597 100644 --- a/src/v0/destinations/braze/braze.util.test.js +++ b/src/v0/destinations/braze/braze.util.test.js @@ -305,7 +305,14 @@ describe('dedup utility tests', () => { }, timeout: 10000, }, - { destType: 'braze', feature: 'transformation' }, + { + destType: 'braze', + feature: 'transformation', + endpointPath: '/users/export/ids', + feature: 'transformation', + module: 'router', + requestMethod: 'POST', + }, ); }); diff --git a/src/v0/destinations/braze/deleteUsers.js b/src/v0/destinations/braze/deleteUsers.js index b94d901138c..33c0f2ef7fa 100644 --- a/src/v0/destinations/braze/deleteUsers.js +++ b/src/v0/destinations/braze/deleteUsers.js @@ -22,7 +22,7 @@ const userDeletionHandler = async (userAttributes, config) => { // Endpoints different for different data centers. // DOC: https://www.braze.com/docs/user_guide/administrative/access_braze/braze_instances/ let endPoint; - const endpointPath = '/users/delete'; // TODO: to handle for destinations dynamically by extracting from endpoint + const endpointPath = '/users/delete'; const dataCenterArr = dataCenter.trim().split('-'); if (dataCenterArr[0].toLowerCase() === 'eu') { endPoint = 'https://rest.fra-01.braze.eu/users/delete'; @@ -46,6 +46,8 @@ const userDeletionHandler = async (userAttributes, config) => { destType: 'braze', feature: 'deleteUsers', endpointPath, + requestMethod: 'POST', + module: 'deletion', }); const handledDelResponse = processAxiosResponse(resp); if (!isHttpStatusSuccess(handledDelResponse.status) && handledDelResponse.status !== 404) { @@ -54,6 +56,7 @@ const userDeletionHandler = async (userAttributes, config) => { handledDelResponse.status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(handledDelResponse.status), + [tags.TAG_NAMES.STATUS]: handledDelResponse.status, }, handledDelResponse, ); diff --git a/src/v0/destinations/braze/networkHandler.js b/src/v0/destinations/braze/networkHandler.js index c6cf7222eaa..b1363419b31 100644 --- a/src/v0/destinations/braze/networkHandler.js +++ b/src/v0/destinations/braze/networkHandler.js @@ -11,7 +11,8 @@ const tags = require('../../util/tags'); const stats = require('../../../util/stats'); // eslint-disable-next-line @typescript-eslint/no-unused-vars -const responseHandler = (destinationResponse, _dest) => { +const responseHandler = (responseParams) => { + const { destinationResponse } = responseParams; const message = `Request for ${DESTINATION} Processed Successfully`; const { response, status } = destinationResponse; // if the response from destination is not a success case build an explicit error diff --git a/src/v0/destinations/braze/transform.js b/src/v0/destinations/braze/transform.js index 6549f5658fc..d45640272ed 100644 --- a/src/v0/destinations/braze/transform.js +++ b/src/v0/destinations/braze/transform.js @@ -223,6 +223,9 @@ async function processIdentify(message, destination) { { destType: 'braze', feature: 'transformation', + requestMethod: 'POST', + module: 'router', + endpointPath: '/users/identify', }, ); if (!isHttpStatusSuccess(brazeIdentifyResp.status)) { diff --git a/src/v0/destinations/braze/util.js b/src/v0/destinations/braze/util.js index 40b9a7eadab..5f1f1e62057 100644 --- a/src/v0/destinations/braze/util.js +++ b/src/v0/destinations/braze/util.js @@ -163,6 +163,9 @@ const BrazeDedupUtility = { { destType: 'braze', feature: 'transformation', + requestMethod: 'POST', + module: 'router', + endpointPath: '/users/export/ids', }, ); stats.counter('braze_lookup_failure_count', 1, { diff --git a/src/v0/destinations/campaign_manager/networkHandler.js b/src/v0/destinations/campaign_manager/networkHandler.js index a1fa24835c1..df13b72adc0 100644 --- a/src/v0/destinations/campaign_manager/networkHandler.js +++ b/src/v0/destinations/campaign_manager/networkHandler.js @@ -44,7 +44,8 @@ function checkIfFailuresAreRetryable(response) { } } -const responseHandler = (destinationResponse) => { +const responseHandler = (responseParams) => { + const { destinationResponse } = responseParams; const message = `[CAMPAIGN_MANAGER Response Handler] - Request Processed Successfully`; const { response, status } = destinationResponse; diff --git a/src/v0/destinations/campaign_manager/transform.js b/src/v0/destinations/campaign_manager/transform.js index 3b480dbac23..14bc6d2c19f 100644 --- a/src/v0/destinations/campaign_manager/transform.js +++ b/src/v0/destinations/campaign_manager/transform.js @@ -9,7 +9,6 @@ const { removeUndefinedAndNullValues, getSuccessRespEvents, isDefinedAndNotNull, - checkInvalidRtTfEvents, handleRtTfSingleEventError, getAccessToken, } = require('../../util'); @@ -245,11 +244,6 @@ const batchEvents = (eventChunksArray) => { }; const processRouterDest = async (inputs, reqMetadata) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } - const batchErrorRespList = []; const eventChunksArray = []; const { destination } = inputs[0]; diff --git a/src/v0/destinations/canny/util.js b/src/v0/destinations/canny/util.js index f514a01e5c5..1d03eed4b9b 100644 --- a/src/v0/destinations/canny/util.js +++ b/src/v0/destinations/canny/util.js @@ -46,6 +46,8 @@ const retrieveUserId = async (apiKey, message) => { destType: 'canny', feature: 'transformation', endpointPath: `/v1/users/retrieve`, + requestMethod: 'POST', + module: 'processor', }, ); logger.debug(response); diff --git a/src/v0/destinations/clevertap/data/CleverTapIdentify.json b/src/v0/destinations/clevertap/data/CleverTapIdentify.json index 577e13c3399..cdc4b28d938 100644 --- a/src/v0/destinations/clevertap/data/CleverTapIdentify.json +++ b/src/v0/destinations/clevertap/data/CleverTapIdentify.json @@ -1,7 +1,7 @@ [ { "destKey": "Email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "required": false, "sourceFromGenericMap": true }, diff --git a/src/v0/destinations/clevertap/deleteUsers.js b/src/v0/destinations/clevertap/deleteUsers.js index 3c07a63d93c..52119bf0f19 100644 --- a/src/v0/destinations/clevertap/deleteUsers.js +++ b/src/v0/destinations/clevertap/deleteUsers.js @@ -53,6 +53,8 @@ const userDeletionHandler = async (userAttributes, config) => { destType: 'clevertap', feature: 'deleteUsers', endpointPath, + requestMethod: 'POST', + module: 'deletion', }, ); const handledDelResponse = processAxiosResponse(deletionResponse); @@ -62,6 +64,7 @@ const userDeletionHandler = async (userAttributes, config) => { handledDelResponse.status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(handledDelResponse.status), + [tags.TAG_NAMES.STATUS]: handledDelResponse.status, }, handledDelResponse, ); diff --git a/src/v0/destinations/clevertap/networkHandler.js b/src/v0/destinations/clevertap/networkHandler.js index e17afb57d19..02b523f3fc2 100644 --- a/src/v0/destinations/clevertap/networkHandler.js +++ b/src/v0/destinations/clevertap/networkHandler.js @@ -7,7 +7,8 @@ const { } = require('../../../adapters/utils/networkUtils'); const tags = require('../../util/tags'); -const responseHandler = (destinationResponse) => { +const responseHandler = (responseParams) => { + const { destinationResponse } = responseParams; const message = 'Request Processed Successfully'; const { response, status } = destinationResponse; diff --git a/src/v0/destinations/clevertap/transform.js b/src/v0/destinations/clevertap/transform.js index efcd101668a..51ed5c851e3 100644 --- a/src/v0/destinations/clevertap/transform.js +++ b/src/v0/destinations/clevertap/transform.js @@ -22,7 +22,6 @@ const { handleRtTfSingleEventError, batchMultiplexedEvents, getSuccessRespEvents, - checkInvalidRtTfEvents, } = require('../../util'); const { generateClevertapBatchedPayload } = require('./utils'); @@ -83,16 +82,21 @@ const responseWrapper = (payload, destination) => { } * } - * This function stringify the payload attributes if it's an array or objects. + * This function stringify the payload attributes if it's an array or objects. The keys that are not stringified are present in the `stringifyExcludeList` array. * @param {*} payload * @returns * return the final payload after converting to the relevant data-types. */ const convertObjectAndArrayToString = (payload, event) => { const finalPayload = {}; + const stringifyExcludeList = ['category-unsubscribe', 'category-resubscribe']; if (payload) { Object.keys(payload).forEach((key) => { - if (payload[key] && (Array.isArray(payload[key]) || typeof payload[key] === 'object')) { + if ( + payload[key] && + (Array.isArray(payload[key]) || typeof payload[key] === 'object') && + !stringifyExcludeList.includes(key) + ) { finalPayload[key] = JSON.stringify(payload[key]); } else { finalPayload[key] = payload[key]; @@ -384,13 +388,6 @@ const processEvent = (message, destination) => { const process = (event) => processEvent(event.message, event.destination); const processRouterDest = (inputs, reqMetadata) => { - // const respList = await simpleProcessRouterDest(inputs, process, reqMetadata); - // return respList; - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } - const eventsChunk = []; const errorRespList = []; // const { destination } = inputs[0]; diff --git a/src/v0/destinations/clickup/util.js b/src/v0/destinations/clickup/util.js index 148fe1bd073..74e961906cf 100644 --- a/src/v0/destinations/clickup/util.js +++ b/src/v0/destinations/clickup/util.js @@ -217,6 +217,9 @@ const retrieveCustomFields = async (listId, apiToken) => { const customFieldsResponse = await httpGET(endpoint, requestOptions, { destType: 'clickup', feature: 'transformation', + endpointPath: '/list/listId/field', + requestMethod: 'GET', + module: 'router', }); const processedCustomFieldsResponse = processAxiosResponse(customFieldsResponse); diff --git a/src/v0/destinations/criteo_audience/networkHandler.js b/src/v0/destinations/criteo_audience/networkHandler.js index 18bd9a93a06..6032aabcdd3 100644 --- a/src/v0/destinations/criteo_audience/networkHandler.js +++ b/src/v0/destinations/criteo_audience/networkHandler.js @@ -67,7 +67,8 @@ const criteoAudienceRespHandler = (destResponse, stageMsg) => { ); }; -const responseHandler = (destinationResponse) => { +const responseHandler = (responseParams) => { + const { destinationResponse } = responseParams; const message = `Request Processed Successfully`; const { status } = destinationResponse; if (!isHttpStatusSuccess(status)) { diff --git a/src/v0/destinations/custify/deleteUsers.js b/src/v0/destinations/custify/deleteUsers.js index 147fcc602ca..690768a170a 100644 --- a/src/v0/destinations/custify/deleteUsers.js +++ b/src/v0/destinations/custify/deleteUsers.js @@ -17,36 +17,44 @@ const userDeletionHandler = async (userAttributes, config) => { } const { apiKey } = config; - const { userId } = userAttributes; if (!apiKey) { throw new ConfigurationError('api key for deletion not present', 400); } - if (!userId) { - throw new InstrumentationError('User id for deletion not present', 400); - } - const requestUrl = `https://api.custify.com/people?user_id=${userId}`; - const requestOptions = { - headers: { - Authorization: `Bearer ${apiKey}`, - }, - }; + await Promise.all( + userAttributes.map(async (userAttr) => { + const { userId } = userAttr; + if (!userId) { + throw new InstrumentationError('User id for deletion not present', 400); + } + // Reference: https://docs.custify.com/#tag/People/paths/~1people/delete + const requestUrl = `https://api.custify.com/people?user_id=${userId}`; + const requestOptions = { + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }; - const deletionResponse = await httpDELETE(requestUrl, requestOptions, { - destType: 'custify', - feature: 'deleteUsers', - }); - const processedDeletionRequest = processAxiosResponse(deletionResponse); - if (processedDeletionRequest.status !== 200 && processedDeletionRequest.status !== 404) { - throw new NetworkError( - JSON.stringify(processedDeletionRequest.response) || 'Error while deleting user', - processedDeletionRequest.status, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(processedDeletionRequest.status), - }, - deletionResponse, - ); - } + const deletionResponse = await httpDELETE(requestUrl, requestOptions, { + destType: 'custify', + feature: 'deleteUsers', + requestMethod: 'DELETE', + endpointPath: '/people', + module: 'deletion', + }); + const processedDeletionRequest = processAxiosResponse(deletionResponse); + if (processedDeletionRequest.status !== 200 && processedDeletionRequest.status !== 404) { + throw new NetworkError( + JSON.stringify(processedDeletionRequest.response) || 'Error while deleting user', + processedDeletionRequest.status, + { + [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(processedDeletionRequest.status), + }, + deletionResponse, + ); + } + }), + ); return { statusCode: 200, status: 'successful' }; }; diff --git a/src/v0/destinations/custify/util.js b/src/v0/destinations/custify/util.js index 8ecabccd2e2..b6f34465039 100644 --- a/src/v0/destinations/custify/util.js +++ b/src/v0/destinations/custify/util.js @@ -41,6 +41,8 @@ const createUpdateCompany = async (companyPayload, Config) => { destType: 'custify', feature: 'transformation', endpointPath: `/company`, + requestMethod: 'POST', + module: 'router', }, ); const processedCompanyResponse = processAxiosResponse(companyResponse); diff --git a/src/v0/destinations/customerio/transform.js b/src/v0/destinations/customerio/transform.js index be4486717c1..6f2e053001f 100644 --- a/src/v0/destinations/customerio/transform.js +++ b/src/v0/destinations/customerio/transform.js @@ -5,7 +5,6 @@ const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType, MappedToDestinationKey } = require('../../../constants'); const { - getErrorRespEvents, getSuccessRespEvents, defaultRequestConfig, addExternalIdToTraits, @@ -174,10 +173,6 @@ const batchEvents = (successRespList) => { }; const processRouterDest = (inputs, reqMetadata) => { - if (!Array.isArray(inputs) || inputs.length <= 0) { - const respEvents = getErrorRespEvents(null, 400, 'Invalid event array'); - return [respEvents]; - } let batchResponseList = []; const batchErrorRespList = []; const successRespList = []; diff --git a/src/v0/destinations/delighted/util.js b/src/v0/destinations/delighted/util.js index 2c92685fd77..c690bf5f5ca 100644 --- a/src/v0/destinations/delighted/util.js +++ b/src/v0/destinations/delighted/util.js @@ -61,7 +61,13 @@ const userValidity = async (channel, Config, userId) => { }, params: paramsdata, }, - { destType: 'delighted', feature: 'transformation' }, + { + destType: 'delighted', + feature: 'transformation', + requestMethod: 'GET', + endpointPath: '/people.json', + module: 'router', + }, ); if (response && response.data && response.status === 200 && Array.isArray(response.data)) { return response.data.length > 0; diff --git a/src/v0/destinations/drip/util.js b/src/v0/destinations/drip/util.js index a502cf0d202..b7015c9351c 100644 --- a/src/v0/destinations/drip/util.js +++ b/src/v0/destinations/drip/util.js @@ -31,7 +31,13 @@ const userExists = async (Config, id) => { 'Content-Type': JSON_MIME_TYPE, }, }, - { destType: 'drip', feature: 'transformation' }, + { + destType: 'drip', + feature: 'transformation', + requestMethod: 'GET', + endpointPath: '/subscribers/id', + module: 'router', + }, ); if (response && response.status) { return response.status === 200; @@ -70,7 +76,13 @@ const createUpdateUser = async (finalpayload, Config, basicAuth) => { 'Content-Type': JSON_MIME_TYPE, }, }, - { destType: 'drip', feature: 'transformation' }, + { + destType: 'drip', + feature: 'transformation', + requestMethod: 'POST', + endpointPath: '/subscribers', + module: 'router', + }, ); if (response) { return response.status === 200 || response.status === 201; diff --git a/src/v0/destinations/engage/deleteUsers.js b/src/v0/destinations/engage/deleteUsers.js index a3c3055c7d9..3616d2408d2 100644 --- a/src/v0/destinations/engage/deleteUsers.js +++ b/src/v0/destinations/engage/deleteUsers.js @@ -42,6 +42,9 @@ const userDeletionHandler = async (userAttributes, config) => { { destType: 'engage', feature: 'deleteUsers', + requestMethod: 'DELETE', + endpointPath: '/users/userId', + module: 'deletion', }, ); const handledDelResponse = processAxiosResponse(response); @@ -51,6 +54,7 @@ const userDeletionHandler = async (userAttributes, config) => { handledDelResponse.status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(handledDelResponse.status), + [tags.TAG_NAMES.STATUS]: handledDelResponse.status, }, handledDelResponse, ); diff --git a/src/v0/destinations/facebook_conversions/utils.js b/src/v0/destinations/facebook_conversions/utils.js index 26204ec61a3..c6e3993e33e 100644 --- a/src/v0/destinations/facebook_conversions/utils.js +++ b/src/v0/destinations/facebook_conversions/utils.js @@ -93,28 +93,26 @@ const populateCustomDataBasedOnCategory = (customData, message, category, catego ); const contentCategory = eventTypeCustomData.content_category; - let contentType; + let defaultContentType; if (contentIds.length > 0) { - contentType = 'product'; + defaultContentType = 'product'; } else if (contentCategory) { contentIds.push(contentCategory); contents.push({ id: contentCategory, quantity: 1, }); - contentType = 'product_group'; + defaultContentType = 'product_group'; } + const contentType = + message.properties?.content_type || + getContentType(message, defaultContentType, categoryToContent, DESTINATION.toLowerCase()); eventTypeCustomData = { ...eventTypeCustomData, content_ids: contentIds, contents, - content_type: getContentType( - message, - contentType, - categoryToContent, - DESTINATION.toLowerCase(), - ), + content_type: contentType, content_category: getContentCategory(contentCategory), }; break; @@ -125,18 +123,20 @@ const populateCustomDataBasedOnCategory = (customData, message, category, catego case 'payment info entered': case 'product added to wishlist': { const contentCategory = eventTypeCustomData.content_category; - const contentType = eventTypeCustomData.content_type; + const contentType = + message.properties?.content_type || + getContentType( + message, + eventTypeCustomData.content_type, + categoryToContent, + DESTINATION.toLowerCase(), + ); const { contentIds, contents } = populateContentsAndContentIDs([message.properties]); eventTypeCustomData = { ...eventTypeCustomData, content_ids: contentIds, contents, - content_type: getContentType( - message, - contentType, - categoryToContent, - DESTINATION.toLowerCase(), - ), + content_type: contentType, content_category: getContentCategory(contentCategory), }; validateProductSearchedData(eventTypeCustomData); @@ -151,18 +151,20 @@ const populateCustomDataBasedOnCategory = (customData, message, category, catego ); const contentCategory = eventTypeCustomData.content_category; - const contentType = eventTypeCustomData.content_type; + const contentType = + message.properties?.content_type || + getContentType( + message, + eventTypeCustomData.content_type, + categoryToContent, + DESTINATION.toLowerCase(), + ); eventTypeCustomData = { ...eventTypeCustomData, content_ids: contentIds, contents, - content_type: getContentType( - message, - contentType, - categoryToContent, - DESTINATION.toLowerCase(), - ), + content_type: contentType, content_category: getContentCategory(contentCategory), num_items: contentIds.length, }; diff --git a/src/v0/destinations/facebook_pixel/transform.test.js b/src/v0/destinations/facebook_pixel/transform.test.js index 25332d770c7..d3c5baa0702 100644 --- a/src/v0/destinations/facebook_pixel/transform.test.js +++ b/src/v0/destinations/facebook_pixel/transform.test.js @@ -24,6 +24,23 @@ const getTestMessage = () => { return message; }; +const getTestMessageWithoutProductIdAndCategory = () => { + let message = { + properties: { + currency: 'CAD', + quantity: 1, + price: 24.75, + value: 30, + name: 'my product 1', + testDimension: true, + testMetric: true, + position: 4.5, + query: 'HDMI Cable', + }, + }; + return message; +}; + const getTestCategoryToContent = () => { let categoryToContent = [ { @@ -52,6 +69,17 @@ describe('Unit test cases for facebook_pixel handle search', () => { expect(handleSearch(getTestMessage())).toEqual(expectedOutput); }); + it('should return content with content_ids and content fields as empty array', async () => { + const expectedOutput = { + content_ids: [], + content_category: '', + value: 30, + search_string: 'HDMI Cable', + contents: [], + }; + expect(handleSearch(getTestMessageWithoutProductIdAndCategory())).toEqual(expectedOutput); + }); + it("mapping 'product_id' with contentId", async () => { let message = getTestMessage(); message.properties.product_id = 'prd-123'; diff --git a/src/v0/destinations/facebook_pixel/utils.js b/src/v0/destinations/facebook_pixel/utils.js index 8a63a0b0fe2..cfa625ee3db 100644 --- a/src/v0/destinations/facebook_pixel/utils.js +++ b/src/v0/destinations/facebook_pixel/utils.js @@ -53,13 +53,9 @@ const getActionSource = (payload, channel) => { * Handles order completed and checkout started types of specific events */ const handleOrder = (message, categoryToContent) => { - const { products, revenue } = message.properties; - const value = formatRevenue(revenue); - - const contentType = getContentType(message, 'product', categoryToContent); - const contentIds = []; - const contents = []; const { + products, + revenue, category, quantity, price, @@ -67,6 +63,12 @@ const handleOrder = (message, categoryToContent) => { contentName, delivery_category: deliveryCategory, } = message.properties; + const value = formatRevenue(revenue); + let { content_type: contentType } = message.properties; + contentType = contentType || getContentType(message, 'product', categoryToContent); + const contentIds = []; + const contents = []; + if (products) { if (products.length > 0 && Array.isArray(products)) { products.forEach((singleProduct) => { @@ -109,10 +111,17 @@ const handleOrder = (message, categoryToContent) => { * Handles product list viewed */ const handleProductListViewed = (message, categoryToContent) => { - let contentType; + let defaultContentType; const contentIds = []; const contents = []; - const { products, category, quantity, value, contentName } = message.properties; + const { + products, + category, + quantity, + value, + contentName, + content_type: contentType, + } = message.properties; if (products && products.length > 0 && Array.isArray(products)) { products.forEach((product, index) => { if (isObject(product)) { @@ -132,7 +141,7 @@ const handleProductListViewed = (message, categoryToContent) => { } if (contentIds.length > 0) { - contentType = 'product'; + defaultContentType = 'product'; // for viewContent event content_ids and content arrays are not mandatory } else if (category) { contentIds.push(category); @@ -140,12 +149,12 @@ const handleProductListViewed = (message, categoryToContent) => { id: category, quantity: 1, }); - contentType = 'product_group'; + defaultContentType = 'product_group'; } return { content_ids: contentIds, - content_type: getContentType(message, contentType, categoryToContent), + content_type: contentType || getContentType(message, defaultContentType, categoryToContent), contents, content_category: getContentCategory(category), content_name: contentName, @@ -165,7 +174,8 @@ const handleProduct = (message, categoryToContent, valueFieldIdentifier) => { const useValue = valueFieldIdentifier === 'properties.value'; const contentId = message.properties?.product_id || message.properties?.sku || message.properties?.id; - const contentType = getContentType(message, 'product', categoryToContent); + const contentType = + message.properties?.content_type || getContentType(message, 'product', categoryToContent); const contentName = message.properties.product_name || message.properties.name || ''; const contentCategory = message.properties.category || ''; const currency = message.properties.currency || 'USD'; diff --git a/src/v0/destinations/facebook_pixel/utils.test.js b/src/v0/destinations/facebook_pixel/utils.test.js new file mode 100644 index 00000000000..f32d7d7024d --- /dev/null +++ b/src/v0/destinations/facebook_pixel/utils.test.js @@ -0,0 +1,154 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); +const { getActionSource, formatRevenue, getCategoryFromEvent } = require('./utils'); +const { CONFIG_CATEGORIES, OTHER_STANDARD_EVENTS } = require('./config'); + +describe('Test Facebook Pixel Utils', () => { + describe('getActionSource', () => { + // Returns 'other' if payload.action_source is not defined and channel is neither 'web' nor 'mobile' + it('should return "other" when payload.action_source is not defined and channel is neither "web" nor "mobile"', () => { + const payload = {}; + const channel = 'email'; + const result = getActionSource(payload, channel); + expect(result).toBe('other'); + }); + + // Returns payload.action_source if it is defined and is a valid value from ACTION_SOURCES_VALUES + it('should return payload.action_source when it is defined and is a valid value from ACTION_SOURCES_VALUES', () => { + const payload = { action_source: 'website' }; + const channel = 'email'; + const result = getActionSource(payload, channel); + expect(result).toBe('website'); + }); + + // Returns 'website' if channel is 'web' and payload.action_source is not defined + it('should return "website" when channel is "web" and payload.action_source is not defined', () => { + const payload = {}; + const channel = 'web'; + const result = getActionSource(payload, channel); + expect(result).toBe('website'); + }); + + // Throws an InstrumentationError if payload.action_source is defined but not a valid value from ACTION_SOURCES_VALUES + it('should throw an InstrumentationError when payload.action_source is defined but not a valid value from ACTION_SOURCES_VALUES', () => { + const payload = { action_source: 'invalid' }; + const channel = 'email'; + expect(() => { + getActionSource(payload, channel); + }).toThrow(InstrumentationError); + }); + }); + + describe('formatRevenue', () => { + // Returns a number with two decimal places when passed a valid revenue value. + it('should return a number with two decimal places when passed a valid revenue value', () => { + const revenue = '100.50'; + const formattedRevenue = formatRevenue(revenue); + expect(formattedRevenue).toBe(100.5); + }); + + // Returns 0 when passed a null revenue value. + it('should return 0 when passed a null revenue value', () => { + const revenue = null; + const formattedRevenue = formatRevenue(revenue); + expect(formattedRevenue).toBe(0); + }); + + // Returns 0 when passed an undefined revenue value. + it('should return 0 when passed an undefined revenue value', () => { + const revenue = undefined; + const formattedRevenue = formatRevenue(revenue); + expect(formattedRevenue).toBe(0); + }); + + // Throws an InstrumentationError when passed a non-numeric string revenue value. + it('should throw an InstrumentationError when passed a non-numeric string revenue value', () => { + const revenue = 'abc'; + expect(() => { + formatRevenue(revenue); + }).toThrow(InstrumentationError); + }); + + // Returns a number with two decimal places when passed a numeric string revenue value with more than two decimal places. + it('should return a number with two decimal places when passed a numeric string revenue value with more than two decimal places', () => { + const revenue = '100.555'; + const formattedRevenue = formatRevenue(revenue); + expect(formattedRevenue).toBe(100.56); + }); + + // Returns a number with two decimal places when passed a numeric value with more than two decimal places. + it('should return a number with two decimal places when passed a numeric value with more than two decimal places', () => { + const revenue = 100.555; + const formattedRevenue = formatRevenue(revenue); + expect(formattedRevenue).toBe(100.56); + }); + }); + + describe('getCategoryFromEvent', () => { + // The function correctly maps the eventName to its corresponding category. + it('should correctly map the eventName to its corresponding category', () => { + const eventName = CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.type; + const result = getCategoryFromEvent(eventName); + expect(result).toEqual(CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED); + }); + + // The function returns the correct category for a given eventName. + it('should return the correct category for a given eventName', () => { + const eventName = CONFIG_CATEGORIES.PRODUCT_VIEWED.type; + const result = getCategoryFromEvent(eventName); + expect(result).toEqual(CONFIG_CATEGORIES.PRODUCT_VIEWED); + }); + + // The function returns the default category if the eventName is not recognized. + it('should return the default category if the eventName is not recognized', () => { + const eventName = 'unknownEvent'; + const result = getCategoryFromEvent(eventName); + expect(result).toEqual(CONFIG_CATEGORIES.SIMPLE_TRACK); + }); + + // The function handles null or undefined eventName inputs. + it('should handle null or undefined eventName inputs', () => { + const eventName = null; + const result = getCategoryFromEvent(eventName); + expect(result).toEqual(CONFIG_CATEGORIES.SIMPLE_TRACK); + }); + + // The function handles empty string eventName inputs. + it('should handle empty string eventName inputs', () => { + const eventName = ''; + const result = getCategoryFromEvent(eventName); + expect(result).toEqual(CONFIG_CATEGORIES.SIMPLE_TRACK); + }); + + // The function handles eventName inputs that are not strings. + it('should handle eventName inputs that are not strings', () => { + const eventName = 123; + const result = getCategoryFromEvent(eventName); + expect(result).toEqual(CONFIG_CATEGORIES.SIMPLE_TRACK); + }); + + // The function handles multiple eventNames that map to the same category. + it('should correctly map multiple eventNames to the same category', () => { + const eventName1 = CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.type; + const eventName2 = CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.eventName; + const result1 = getCategoryFromEvent(eventName1); + const result2 = getCategoryFromEvent(eventName2); + expect(result1).toEqual(CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED); + expect(result2).toEqual(CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED); + }); + + // The function handles eventNames that are included in the OTHER_STANDARD_EVENTS list. + it('should correctly handle eventNames included in the OTHER_STANDARD_EVENTS list', () => { + const eventName = OTHER_STANDARD_EVENTS[0]; + const result = getCategoryFromEvent(eventName); + expect(result).toEqual(CONFIG_CATEGORIES.OTHER_STANDARD); + expect(result.eventName).toEqual(eventName); + }); + + // The function handles eventNames that are not recognized and not in the OTHER_STANDARD_EVENTS list. + it('should correctly handle unrecognized eventNames', () => { + const eventName = 'unrecognizedEvent'; + const result = getCategoryFromEvent(eventName); + expect(result).toEqual(CONFIG_CATEGORIES.SIMPLE_TRACK); + }); + }); +}); diff --git a/src/v0/destinations/fb/networkHandler.js b/src/v0/destinations/fb/networkHandler.js index 06235fab402..7ba5b88adc2 100644 --- a/src/v0/destinations/fb/networkHandler.js +++ b/src/v0/destinations/fb/networkHandler.js @@ -2,7 +2,8 @@ const { processAxiosResponse } = require('../../../adapters/utils/networkUtils') const { errorResponseHandler } = require('../facebook_pixel/networkHandler'); const { prepareProxyRequest, proxyRequest } = require('../../../adapters/network'); -const destResponseHandler = (destinationResponse) => { +const destResponseHandler = (responseParams) => { + const { destinationResponse } = responseParams; errorResponseHandler(destinationResponse); return { destinationResponse: destinationResponse.response, diff --git a/src/v0/destinations/freshmarketer/utils.js b/src/v0/destinations/freshmarketer/utils.js index 5e3ba6e67ec..c80711ff8d4 100644 --- a/src/v0/destinations/freshmarketer/utils.js +++ b/src/v0/destinations/freshmarketer/utils.js @@ -50,6 +50,8 @@ const createUpdateAccount = async (payload, Config) => { destType: 'freshmarketer', feature: 'transformation', endpointPath: `/crm/sales/api/sales_accounts/upsert`, + requestMethod: 'POST', + module: 'router', }); accountResponse = processAxiosResponse(accountResponse); if (accountResponse.status !== 200 && accountResponse.status !== 201) { @@ -95,6 +97,8 @@ const getUserAccountDetails = async (payload, userEmail, Config) => { destType: 'freshmarketer', feature: 'transformation', endpointPath: `crm/sales/api/contacts/upsert?include=sales_accounts`, + requestMethod: 'POST', + module: 'router', }); userSalesAccountResponse = processAxiosResponse(userSalesAccountResponse); if (userSalesAccountResponse.status !== 200 && userSalesAccountResponse.status !== 201) { @@ -145,6 +149,8 @@ const createOrUpdateListDetails = async (listName, Config) => { destType: 'freshmarketer', feature: 'transformation', endpointPath: `/crm/sales/api/lists`, + requestMethod: 'GET', + module: 'router', }); listResponse = processAxiosResponse(listResponse); if (listResponse.status !== 200) { @@ -165,6 +171,8 @@ const createOrUpdateListDetails = async (listName, Config) => { destType: 'freshmarketer', feature: 'transformation', endpointPath: `/crm/sales/api/lists`, + requestMethod: 'POST', + module: 'router', }); listResponse = processAxiosResponse(listResponse); if (listResponse.status !== 200) { @@ -240,6 +248,8 @@ const getContactsDetails = async (userEmail, Config) => { destType: 'freshmarketer', feature: 'transformation', endpointPath: `/crm/sales/api/contacts/upsert`, + requestMethod: 'POST', + module: 'router', }); userResponse = processAxiosResponse(userResponse); if (userResponse.status !== 200 && userResponse.status !== 201) { @@ -314,6 +324,8 @@ const UpdateContactWithLifeCycleStage = async (message, Config) => { destType: 'freshmarketer', feature: 'transformation', endpointPath: `/crm/sales/api/selector/lifecycle_stages`, + requestMethod: 'GET', + module: 'router', }); lifeCycleStagesResponse = processAxiosResponse(lifeCycleStagesResponse); if (lifeCycleStagesResponse.status !== 200) { @@ -400,6 +412,8 @@ const UpdateContactWithSalesActivity = async (payload, message, Config) => { destType: 'freshmarketer', feature: 'transformation', endpointPath: `/crm/sales/api/selector/sales_activity_types`, + requestMethod: 'GET', + module: 'router', }); salesActivityResponse = processAxiosResponse(salesActivityResponse); if (salesActivityResponse.status !== 200) { diff --git a/src/v0/destinations/freshsales/utils.js b/src/v0/destinations/freshsales/utils.js index 5008fedc2da..977bde0abb3 100644 --- a/src/v0/destinations/freshsales/utils.js +++ b/src/v0/destinations/freshsales/utils.js @@ -48,6 +48,8 @@ const createUpdateAccount = async (payload, Config) => { destType: 'freshsales', feature: 'transformation', endpointPath: `/crm/sales/api/sales_accounts/upsert`, + requestMethod: 'POST', + module: 'router', }); accountResponse = processAxiosResponse(accountResponse); if (accountResponse.status !== 200 && accountResponse.status !== 201) { @@ -92,6 +94,8 @@ const getUserAccountDetails = async (payload, userEmail, Config) => { destType: 'freshsales', feature: 'transformation', endpointPath: `/crm/sales/api/contacts/upsert?include=sales_accounts`, + requestMethod: 'POST', + module: 'router', }); userSalesAccountResponse = processAxiosResponse(userSalesAccountResponse); if (userSalesAccountResponse.status !== 200 && userSalesAccountResponse.status !== 201) { @@ -148,6 +152,8 @@ const getContactsDetails = async (userEmail, Config) => { destType: 'freshsales', feature: 'transformation', endpointPath: `/crm/sales/api/contacts/upsert`, + requestMethod: 'POST', + module: 'router', }); userResponse = processAxiosResponse(userResponse); if (userResponse.status !== 200 && userResponse.status !== 201) { @@ -239,6 +245,8 @@ const UpdateContactWithSalesActivity = async (payload, message, Config) => { destType: 'freshsales', feature: 'transformation', endpointPath: `/crm/sales/api/sales_activity_types`, + requestMethod: 'GET', + module: 'router', }); salesActivityResponse = processAxiosResponse(salesActivityResponse); if (salesActivityResponse.status !== 200) { @@ -319,6 +327,8 @@ const UpdateContactWithLifeCycleStage = async (message, Config) => { destType: 'freshsales', feature: 'transformation', endpointPath: `/crm/sales/api/lifecycle_stages`, + requestMethod: 'GET', + module: 'router', }); lifeCycleStagesResponse = processAxiosResponse(lifeCycleStagesResponse); if (lifeCycleStagesResponse.status !== 200) { diff --git a/src/v0/destinations/ga/deleteUsers.js b/src/v0/destinations/ga/deleteUsers.js index 06e674048a6..524e2c14b47 100644 --- a/src/v0/destinations/ga/deleteUsers.js +++ b/src/v0/destinations/ga/deleteUsers.js @@ -81,6 +81,8 @@ const userDeletionHandler = async (userAttributes, config, rudderDestInfo) => { destType: 'ga', feature: 'deleteUsers', endpointPath: '/userDeletion/userDeletionRequests:upsert', + requestMethod: 'POST', + module: 'deletion', }, ); // process the response to know about refreshing scenario diff --git a/src/v0/destinations/ga4/networkHandler.js b/src/v0/destinations/ga4/networkHandler.js index b62fcc8d3bd..da8ae2ea30c 100644 --- a/src/v0/destinations/ga4/networkHandler.js +++ b/src/v0/destinations/ga4/networkHandler.js @@ -8,7 +8,8 @@ const { isDefinedAndNotNull, isDefined, isHttpStatusSuccess } = require('../../u const tags = require('../../util/tags'); -const responseHandler = (destinationResponse, dest) => { +const responseHandler = (responseParams) => { + const { destinationResponse, destType } = responseParams; const message = `[GA4 Response Handler] - Request Processed Successfully`; let { status } = destinationResponse; const { response } = destinationResponse; @@ -29,10 +30,10 @@ const responseHandler = (destinationResponse, dest) => { // Build the error in case the validationMessages[] is non-empty const { description, validationCode, fieldPath } = response.validationMessages[0]; throw new NetworkError( - `Validation Server Response Handler:: Validation Error for ${dest} of field path :${fieldPath} | ${validationCode}-${description}`, - status, + `Validation Server Response Handler:: Validation Error for ${destType} of field path :${fieldPath} | ${validationCode}-${description}`, + 400, { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(400), }, response?.validationMessages[0]?.description, ); @@ -42,7 +43,7 @@ const responseHandler = (destinationResponse, dest) => { // if the response from destination is not a success case build an explicit error if (!isHttpStatusSuccess(status)) { throw new NetworkError( - `[GA4 Response Handler] Request failed for destination ${dest} with status: ${status}`, + `[GA4 Response Handler] Request failed for destination ${destType} with status: ${status}`, status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), diff --git a/src/v0/destinations/gainsight/util.js b/src/v0/destinations/gainsight/util.js index 39e666c1a58..4c7fd581934 100644 --- a/src/v0/destinations/gainsight/util.js +++ b/src/v0/destinations/gainsight/util.js @@ -22,7 +22,13 @@ const searchGroup = async (groupName, Config) => { 'Content-Type': JSON_MIME_TYPE, }, }, - { destType: 'gainsight', feature: 'transformation' }, + { + destType: 'gainsight', + feature: 'transformation', + requestMethod: 'POST', + endpointPath: '/data/objects/query/Company', + module: 'router', + }, ); } catch (error) { let errMessage = ''; @@ -56,7 +62,13 @@ const createGroup = async (payload, Config) => { 'Content-Type': JSON_MIME_TYPE, }, }, - { destType: 'gainsight', feature: 'transformation' }, + { + destType: 'gainsight', + feature: 'transformation', + requestMethod: 'POST', + endpointPath: '/data/objects/Company', + module: 'router', + }, ); } catch (error) { let errMessage = ''; @@ -93,7 +105,13 @@ const updateGroup = async (payload, Config) => { keys: 'Name', }, }, - { destType: 'gainsight', feature: 'transformation' }, + { + destType: 'gainsight', + feature: 'transformation', + requestMethod: 'PUT', + endpointPath: '/data/objects/Company', + module: 'router', + }, ); } catch (error) { let errMessage = ''; diff --git a/src/v0/destinations/gainsight_px/util.js b/src/v0/destinations/gainsight_px/util.js index 5109286b3f3..83d23566dd8 100644 --- a/src/v0/destinations/gainsight_px/util.js +++ b/src/v0/destinations/gainsight_px/util.js @@ -6,13 +6,13 @@ const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const { JSON_MIME_TYPE } = require('../../util/constant'); const handleErrorResponse = (error, customErrMessage, expectedErrStatus, defaultStatus = 400) => { + let destResp; let errMessage = ''; let errorStatus = defaultStatus; if (error.response && error.response.data) { - errMessage = error.response.data.externalapierror - ? JSON.stringify(error.response.data.externalapierror) - : JSON.stringify(error.response.data); + destResp = error.response?.data?.externalapierror ?? error.response?.data; + errMessage = JSON.stringify(destResp); errorStatus = error.response.status; @@ -26,7 +26,7 @@ const handleErrorResponse = (error, customErrMessage, expectedErrStatus, default { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(errorStatus), }, - error, + destResp, ); }; @@ -56,7 +56,13 @@ const objectExists = async (id, Config, objectType) => { 'Content-Type': JSON_MIME_TYPE, }, }, - { destType: 'gainsight_px', feature: 'transformation' }, + { + destType: 'gainsight_px', + feature: 'transformation', + requestMethod: 'GET', + endpointPath: '/accounts/accountId', + module: 'router', + }, ); if (response && response.status === 200) { return { success: true, err: null }; @@ -88,7 +94,13 @@ const createAccount = async (payload, Config) => { 'Content-Type': JSON_MIME_TYPE, }, }, - { destType: 'gainsight_px', feature: 'transformation' }, + { + destType: 'gainsight_px', + feature: 'transformation', + requestMethod: 'POST', + endpointPath: '/accounts', + module: 'router', + }, ); if (response && response.status === 201) { return { success: true, err: null }; @@ -121,7 +133,13 @@ const updateAccount = async (accountId, payload, Config) => { 'Content-Type': JSON_MIME_TYPE, }, }, - { destType: 'gainsight_px', feature: 'transformation' }, + { + destType: 'gainsight_px', + feature: 'transformation', + requestMethod: 'PUT', + endpointPath: '/accounts/accountId', + module: 'router', + }, ); if (response && response.status === 204) { return { success: true, err: null }; diff --git a/src/v0/destinations/google_adwords_enhanced_conversions/networkHandler.js b/src/v0/destinations/google_adwords_enhanced_conversions/networkHandler.js index 7266154a095..f7ac660f53f 100644 --- a/src/v0/destinations/google_adwords_enhanced_conversions/networkHandler.js +++ b/src/v0/destinations/google_adwords_enhanced_conversions/networkHandler.js @@ -1,6 +1,7 @@ const { get, set } = require('lodash'); const sha256 = require('sha256'); const { NetworkError, NetworkInstrumentationError } = require('@rudderstack/integrations-lib'); +const SqlString = require('sqlstring'); const { prepareProxyRequest, handleHttpRequest } = require('../../../adapters/network'); const { isHttpStatusSuccess, getAuthErrCategoryFromStCode } = require('../../util/index'); const { CONVERSION_ACTION_ID_CACHE_TTL } = require('./config'); @@ -29,8 +30,12 @@ const ERROR_MSG_PATH = 'response[0].error.message'; const getConversionActionId = async (method, headers, params) => { const conversionActionIdKey = sha256(params.event + params.customerId).toString(); return conversionActionIdCache.get(conversionActionIdKey, async () => { + const queryString = SqlString.format( + 'SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = ?', + [params.event], + ); const data = { - query: `SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = '${params.event}'`, + query: queryString, }; const requestBody = { url: `${BASE_ENDPOINT}/${params.customerId}/googleAds:searchStream`, @@ -45,6 +50,8 @@ const getConversionActionId = async (method, headers, params) => { destType: 'google_adwords_enhanced_conversions', feature: 'proxy', endpointPath: `/googleAds:searchStream`, + requestMethod: 'POST', + module: 'dataDelivery', }, ); if (!isHttpStatusSuccess(gaecConversionActionIdResponse.status)) { @@ -98,11 +105,14 @@ const ProxyRequest = async (request) => { destType: 'google_adwords_enhanced_conversions', feature: 'proxy', endpointPath: `/googleAds:uploadOfflineUserData`, + requestMethod: 'POST', + module: 'dataDelivery', }); return response; }; -const responseHandler = (destinationResponse) => { +const responseHandler = (responseParams) => { + const { destinationResponse } = responseParams; const message = 'Request Processed Successfully'; const { status } = destinationResponse; if (isHttpStatusSuccess(status)) { @@ -112,7 +122,7 @@ const responseHandler = (destinationResponse) => { // Ref - https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto if (partialFailureError && partialFailureError.code !== 0) { throw new NetworkError( - `[Google Ads Offline Conversions]:: partialFailureError - ${JSON.stringify( + `[Google Adwords Enhanced Conversions]:: partialFailureError - ${JSON.stringify( partialFailureError, )}`, 400, diff --git a/src/v0/destinations/google_adwords_offline_conversions/config.js b/src/v0/destinations/google_adwords_offline_conversions/config.js index a02732894fb..f065be946cd 100644 --- a/src/v0/destinations/google_adwords_offline_conversions/config.js +++ b/src/v0/destinations/google_adwords_offline_conversions/config.js @@ -1,6 +1,6 @@ const { getMappingConfig } = require('../../util'); -const API_VERSION = 'v14'; +const API_VERSION = 'v16'; const BASE_ENDPOINT = `https://googleads.googleapis.com/${API_VERSION}/customers/:customerId`; @@ -42,6 +42,11 @@ const CONVERSION_CUSTOM_VARIABLE_CACHE_TTL = process.env.CONVERSION_CUSTOM_VARIA const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); +const consentConfigMap = { + personalizationConsent: 'adPersonalization', + userDataConsent: 'adUserData', +}; + module.exports = { trackClickConversionsMapping: MAPPING_CONFIG[CONFIG_CATEGORIES.TRACK_CLICK_CONVERSIONS_CONFIG.name], @@ -58,4 +63,5 @@ module.exports = { MAPPING_CONFIG[CONFIG_CATEGORIES.TRACK_STORE_CONVERSION_CONFIG_ADD_CONVERSION.name], trackAddStoreAddressConversionsMapping: MAPPING_CONFIG[CONFIG_CATEGORIES.TRACK_STORE_ADDRESS_IDENTIFIER.name], + consentConfigMap, }; diff --git a/src/v0/destinations/google_adwords_offline_conversions/data/TrackAddStoreConversionsConfig.json b/src/v0/destinations/google_adwords_offline_conversions/data/TrackAddStoreConversionsConfig.json index aeecc3e01b8..9c88e59ddb3 100644 --- a/src/v0/destinations/google_adwords_offline_conversions/data/TrackAddStoreConversionsConfig.json +++ b/src/v0/destinations/google_adwords_offline_conversions/data/TrackAddStoreConversionsConfig.json @@ -1,10 +1,7 @@ [ { "destKey": "operations.create.transaction_attribute.store_attribute.store_code", - "sourceKeys": [ - "properties.store_code", - "properties.storeCode" - ], + "sourceKeys": ["properties.store_code", "properties.storeCode"], "required": false, "metadata": { "type": "toString" @@ -25,10 +22,7 @@ }, { "destKey": "operations.create.transaction_attribute.order_id", - "sourceKeys": [ - "properties.order_id", - "properties.orderId" - ], + "sourceKeys": ["properties.order_id", "properties.orderId"], "required": false, "metadata": { "type": "toString" @@ -52,4 +46,4 @@ ], "required": true } -] \ No newline at end of file +] diff --git a/src/v0/destinations/google_adwords_offline_conversions/networkHandler.js b/src/v0/destinations/google_adwords_offline_conversions/networkHandler.js index 6922cde8c8f..5541fd6e1e3 100644 --- a/src/v0/destinations/google_adwords_offline_conversions/networkHandler.js +++ b/src/v0/destinations/google_adwords_offline_conversions/networkHandler.js @@ -34,6 +34,8 @@ const createJob = async (endpoint, headers, payload) => { destType: 'google_adwords_offline_conversions', feature: 'proxy', endpointPath: `/create`, + requestMethod: 'POST', + module: 'dataDelivery', }, ); createJobResponse = processAxiosResponse(createJobResponse); @@ -59,6 +61,8 @@ const addConversionToJob = async (endpoint, headers, jobId, payload) => { destType: 'google_adwords_offline_conversions', feature: 'proxy', endpointPath: `/addOperations`, + requestMethod: 'POST', + module: 'dataDelivery', }, ); addConversionToJobResponse = processAxiosResponse(addConversionToJobResponse); @@ -83,6 +87,8 @@ const runTheJob = async (endpoint, headers, payload, jobId) => { destType: 'google_adwords_offline_conversions', feature: 'proxy', endpointPath: `/run`, + requestMethod: 'POST', + module: 'dataDelivery', }, ); return executeJobResponse; @@ -110,6 +116,8 @@ const getConversionCustomVariable = async (headers, params) => { destType: 'google_adwords_offline_conversions', feature: 'proxy', endpointPath: `/searchStream`, + requestMethod: 'POST', + module: 'dataDelivery', }); searchStreamResponse = processAxiosResponse(searchStreamResponse); if (!isHttpStatusSuccess(searchStreamResponse.status)) { @@ -247,11 +255,14 @@ const ProxyRequest = async (request) => { feature: 'proxy', destType: 'gogole_adwords_offline_conversions', endpointPath: `/proxy`, + requestMethod: 'POST', + module: 'dataDelivery', }); return response; }; -const responseHandler = (destinationResponse) => { +const responseHandler = (responseParams) => { + const { destinationResponse } = responseParams; const message = `[Google Ads Offline Conversions Response Handler] - Request processed successfully`; const { status } = destinationResponse; if (isHttpStatusSuccess(status)) { diff --git a/src/v0/destinations/google_adwords_offline_conversions/transform.js b/src/v0/destinations/google_adwords_offline_conversions/transform.js index 397895c6032..c3be0f7cabb 100644 --- a/src/v0/destinations/google_adwords_offline_conversions/transform.js +++ b/src/v0/destinations/google_adwords_offline_conversions/transform.js @@ -3,24 +3,21 @@ const { InstrumentationError, ConfigurationError } = require('@rudderstack/integ const { EventType } = require('../../../constants'); const { getHashFromArrayWithDuplicate, - constructPayload, removeHyphens, getHashFromArray, handleRtTfSingleEventError, defaultBatchRequestConfig, getSuccessRespEvents, - checkInvalidRtTfEvents, + combineBatchRequestsWithSameJobIds, } = require('../../util'); -const { - CALL_CONVERSION, - trackCallConversionsMapping, - STORE_CONVERSION_CONFIG, -} = require('./config'); +const { CALL_CONVERSION, STORE_CONVERSION_CONFIG } = require('./config'); const { validateDestinationConfig, getStoreConversionPayload, requestBuilder, getClickConversionPayloadAndEndpoint, + getConsentsDataFromIntegrationObj, + getCallConversionPayload, } = require('./utils'); const helper = require('./helper'); @@ -41,12 +38,15 @@ const getConversions = (message, metadata, { Config }, event, conversionType) => const { properties, timestamp, originalTimestamp } = message; const filteredCustomerId = removeHyphens(customerId); + const eventLevelConsentsData = getConsentsDataFromIntegrationObj(message); + if (conversionType === 'click') { // click conversion const convertedPayload = getClickConversionPayloadAndEndpoint( message, Config, filteredCustomerId, + eventLevelConsentsData, ); payload = convertedPayload.payload; endpoint = convertedPayload.endpoint; @@ -55,7 +55,7 @@ const getConversions = (message, metadata, { Config }, event, conversionType) => endpoint = STORE_CONVERSION_CONFIG.replace(':customerId', filteredCustomerId); } else { // call conversions - payload = constructPayload(message, trackCallConversionsMapping); + payload = getCallConversionPayload(message, Config, eventLevelConsentsData); endpoint = CALL_CONVERSION.replace(':customerId', filteredCustomerId); } @@ -119,7 +119,6 @@ const trackResponseBuilder = (message, metadata, destination) => { const process = async (event) => { const { message, metadata, destination } = event; - if (!message.type) { throw new InstrumentationError('Message type is not present. Aborting message.'); } @@ -185,11 +184,6 @@ const batchEvents = (storeSalesEvents) => { }; const processRouterDest = async (inputs, reqMetadata) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } - const storeSalesEvents = []; // list containing store sales events in batched format const clickCallEvents = []; // list containing click and call events in batched format const errorRespList = []; @@ -229,7 +223,7 @@ const processRouterDest = async (inputs, reqMetadata) => { .concat(storeSalesEventsBatchedResponseList) .concat(clickCallEvents) .concat(errorRespList); - return batchedResponseList; + return combineBatchRequestsWithSameJobIds(batchedResponseList); }; module.exports = { process, processRouterDest }; diff --git a/src/v0/destinations/google_adwords_offline_conversions/utils.js b/src/v0/destinations/google_adwords_offline_conversions/utils.js index 599a163c548..70b42e2157a 100644 --- a/src/v0/destinations/google_adwords_offline_conversions/utils.js +++ b/src/v0/destinations/google_adwords_offline_conversions/utils.js @@ -1,4 +1,5 @@ const sha256 = require('sha256'); +const SqlString = require('sqlstring'); const { get, set, cloneDeep } = require('lodash'); const { AbortedError, @@ -17,6 +18,7 @@ const { isDefinedAndNotNull, getAuthErrCategoryFromStCode, getAccessToken, + getIntegrationsObj, } = require('../../util'); const { SEARCH_STREAM, @@ -26,10 +28,13 @@ const { trackAddStoreAddressConversionsMapping, trackClickConversionsMapping, CLICK_CONVERSION, + trackCallConversionsMapping, + consentConfigMap, } = require('./config'); const { processAxiosResponse } = require('../../../adapters/utils/networkUtils'); const Cache = require('../../util/cache'); const helper = require('./helper'); +const { finaliseConsent } = require('../../util/googleUtils'); const conversionActionIdCache = new Cache(CONVERSION_ACTION_ID_CACHE_TTL); @@ -53,8 +58,12 @@ const validateDestinationConfig = ({ Config }) => { const getConversionActionId = async (headers, params) => { const conversionActionIdKey = sha256(params.event + params.customerId).toString(); return conversionActionIdCache.get(conversionActionIdKey, async () => { + const queryString = SqlString.format( + 'SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = ?', + [params.event], + ); const data = { - query: `SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = '${params.event}'`, + query: queryString, }; const endpoint = SEARCH_STREAM.replace(':customerId', params.customerId); const requestOptions = { @@ -64,6 +73,8 @@ const getConversionActionId = async (headers, params) => { destType: 'google_adwords_offline_conversions', feature: 'transformation', endpointPath: `/googleAds:searchStream`, + requestMethod: 'POST', + module: 'dataDelivery', }); searchStreamResponse = processAxiosResponse(searchStreamResponse); if (!isHttpStatusSuccess(searchStreamResponse.status)) { @@ -214,6 +225,17 @@ function getExisitingUserIdentifier(userIdentifierInfo, defaultUserIdentifier) { return result; } +const getCallConversionPayload = (message, Config, eventLevelConsentsData) => { + const payload = constructPayload(message, trackCallConversionsMapping); + // here conversions[0] should be present because there are some mandatory properties mapped in the mapping json. + payload.conversions[0].consent = finaliseConsent( + consentConfigMap, + eventLevelConsentsData, + Config, + ); + return payload; +}; + /** * This Function create the add conversion payload * and returns the payload @@ -270,6 +292,10 @@ const getAddConversionPayload = (message, Config) => { set(payload, 'operations.create.userIdentifiers[0]', {}); } } + // add consent support for store conversions. Note: No event level consent supported. + const consentObject = finaliseConsent(consentConfigMap, {}, Config); + // create property should be present because there are some mandatory properties mapped in the mapping json. + set(payload, 'operations.create.consent', consentObject); return payload; }; @@ -285,7 +311,12 @@ const getStoreConversionPayload = (message, Config, event) => { return payload; }; -const getClickConversionPayloadAndEndpoint = (message, Config, filteredCustomerId) => { +const getClickConversionPayloadAndEndpoint = ( + message, + Config, + filteredCustomerId, + eventLevelConsent, +) => { const email = getFieldValueFromMessage(message, 'emailOnly'); const phone = getFieldValueFromMessage(message, 'phone'); const { hashUserIdentifier, defaultUserIdentifier, UserIdentifierSource, conversionEnvironment } = @@ -357,9 +388,19 @@ const getClickConversionPayloadAndEndpoint = (message, Config, filteredCustomerI if (!properties.conversionEnvironment && conversionEnvironment !== 'none') { set(payload, 'conversions[0].conversionEnvironment', conversionEnvironment); } + + // add consent support for click conversions + const consentObject = finaliseConsent(consentConfigMap, eventLevelConsent, Config); + // here conversions[0] is expected to be present there are some mandatory properties mapped in the mapping json. + set(payload, 'conversions[0].consent', consentObject); return { payload, endpoint }; }; +const getConsentsDataFromIntegrationObj = (message) => { + const integrationObj = getIntegrationsObj(message, 'GOOGLE_ADWORDS_OFFLINE_CONVERSIONS') || {}; + return integrationObj?.consents || {}; +}; + module.exports = { validateDestinationConfig, generateItemListFromProducts, @@ -370,4 +411,6 @@ module.exports = { buildAndGetAddress, getClickConversionPayloadAndEndpoint, getExisitingUserIdentifier, + getConsentsDataFromIntegrationObj, + getCallConversionPayload, }; diff --git a/src/v0/destinations/google_adwords_offline_conversions/utils.test.js b/src/v0/destinations/google_adwords_offline_conversions/utils.test.js index 8deaa3ab0a5..2d1863413c9 100644 --- a/src/v0/destinations/google_adwords_offline_conversions/utils.test.js +++ b/src/v0/destinations/google_adwords_offline_conversions/utils.test.js @@ -2,6 +2,8 @@ const { getClickConversionPayloadAndEndpoint, buildAndGetAddress, getExisitingUserIdentifier, + getConsentsDataFromIntegrationObj, + getCallConversionPayload, } = require('./utils'); const getTestMessage = () => { @@ -161,12 +163,16 @@ describe('getExisitingUserIdentifier util tests', () => { describe('getClickConversionPayloadAndEndpoint util tests', () => { it('getClickConversionPayloadAndEndpoint flow check when default field identifier is present', () => { let expectedOutput = { - endpoint: 'https://googleads.googleapis.com/v14/customers/9625812972:uploadClickConversions', + endpoint: 'https://googleads.googleapis.com/v16/customers/9625812972:uploadClickConversions', payload: { conversions: [ { conversionDateTime: '2022-01-01 12:32:45-08:00', conversionEnvironment: 'WEB', + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, userIdentifiers: [ { hashedEmail: 'fa922cb41ff930664d4c9ced3c472ce7ecf29a0f8248b7018456e990177fff75', @@ -187,11 +193,15 @@ describe('getClickConversionPayloadAndEndpoint util tests', () => { delete fittingPayload.traits.email; delete fittingPayload.properties.email; let expectedOutput = { - endpoint: 'https://googleads.googleapis.com/v14/customers/9625812972:uploadClickConversions', + endpoint: 'https://googleads.googleapis.com/v16/customers/9625812972:uploadClickConversions', payload: { conversions: [ { conversionDateTime: '2022-01-01 12:32:45-08:00', + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, conversionEnvironment: 'WEB', userIdentifiers: [ { @@ -215,7 +225,7 @@ describe('getClickConversionPayloadAndEndpoint util tests', () => { delete fittingPayload.traits.phone; delete fittingPayload.properties.email; let expectedOutput = { - endpoint: 'https://googleads.googleapis.com/v14/customers/9625812972:uploadClickConversions', + endpoint: 'https://googleads.googleapis.com/v16/customers/9625812972:uploadClickConversions', payload: { conversions: [ { @@ -237,7 +247,7 @@ describe('getClickConversionPayloadAndEndpoint util tests', () => { ).toThrow('Either of email or phone is required for user identifier'); }); - it('getClickConversionPayloadAndEndpoint flow check when default field identifier is present and product list present', () => { + it('finaliseConsent', () => { let fittingPayload = { ...getTestMessage() }; fittingPayload.properties.products = [ { @@ -251,13 +261,17 @@ describe('getClickConversionPayloadAndEndpoint util tests', () => { }, ]; let expectedOutput = { - endpoint: 'https://googleads.googleapis.com/v14/customers/9625812972:uploadClickConversions', + endpoint: 'https://googleads.googleapis.com/v16/customers/9625812972:uploadClickConversions', payload: { conversions: [ { cartData: { items: [{ productId: 1234, quantity: 2, unitPrice: 10 }] }, conversionDateTime: '2022-01-01 12:32:45-08:00', conversionEnvironment: 'WEB', + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, userIdentifiers: [ { hashedEmail: 'fa922cb41ff930664d4c9ced3c472ce7ecf29a0f8248b7018456e990177fff75', @@ -273,3 +287,118 @@ describe('getClickConversionPayloadAndEndpoint util tests', () => { ); }); }); + +describe('getConsentsDataFromIntegrationObj', () => { + it('should return an empty object when conversionType is "store"', () => { + const message = {}; + const result = getConsentsDataFromIntegrationObj(message); + expect(result).toEqual({}); + }); + it('should return the consent object when conversion type is call', () => { + const message = { + integrations: { + GOOGLE_ADWORDS_OFFLINE_CONVERSIONS: { + consents: { + adUserData: 'GRANTED', + adPersonalization: 'DENIED', + }, + }, + }, + }; + const conversionType = 'call'; + const result = getConsentsDataFromIntegrationObj(message, conversionType); + expect(result).toEqual({ + adPersonalization: 'DENIED', + adUserData: 'GRANTED', + }); + }); +}); + +describe('getCallConversionPayload', () => { + it('should call conversion payload with consent object', () => { + const message = { + properties: { + callerId: '1234', + callStartDateTime: '2022-01-01 12:32:45-08:00', + conversionDateTime: '2022-01-01 12:32:45-08:00', + }, + }; + const result = getCallConversionPayload( + message, + { + userDataConsent: 'GRANTED', + personalizationConsent: 'DENIED', + }, + { + adUserData: 'GRANTED', + adPersonalization: 'GRANTED', + }, + ); + expect(result).toEqual({ + conversions: [ + { + callStartDateTime: '2022-01-01 12:32:45-08:00', + callerId: '1234', + consent: { + adPersonalization: 'GRANTED', + adUserData: 'GRANTED', + }, + conversionDateTime: '2022-01-01 12:32:45-08:00', + }, + ], + }); + }); + it('should call conversion payload with consent object', () => { + const message = { + properties: { + callerId: '1234', + callStartDateTime: '2022-01-01 12:32:45-08:00', + conversionDateTime: '2022-01-01 12:32:45-08:00', + }, + }; + const result = getCallConversionPayload( + message, + { + userDataConsent: 'GRANTED', + personalizationConsent: 'DENIED', + }, + {}, + ); + expect(result).toEqual({ + conversions: [ + { + callStartDateTime: '2022-01-01 12:32:45-08:00', + callerId: '1234', + consent: { + adPersonalization: 'DENIED', + adUserData: 'GRANTED', + }, + conversionDateTime: '2022-01-01 12:32:45-08:00', + }, + ], + }); + }); + it('should call conversion payload with consent object even if no consent input from UI as well as event level', () => { + const message = { + properties: { + callerId: '1234', + callStartDateTime: '2022-01-01 12:32:45-08:00', + conversionDateTime: '2022-01-01 12:32:45-08:00', + }, + }; + const result = getCallConversionPayload(message, {}, {}); + expect(result).toEqual({ + conversions: [ + { + callStartDateTime: '2022-01-01 12:32:45-08:00', + callerId: '1234', + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, + conversionDateTime: '2022-01-01 12:32:45-08:00', + }, + ], + }); + }); +}); diff --git a/src/v0/destinations/google_adwords_remarketing_lists/config.js b/src/v0/destinations/google_adwords_remarketing_lists/config.js index 5bf0d8a299c..0f08b3866dc 100644 --- a/src/v0/destinations/google_adwords_remarketing_lists/config.js +++ b/src/v0/destinations/google_adwords_remarketing_lists/config.js @@ -16,6 +16,11 @@ const TYPEOFLIST = Object.freeze({ mobileDeviceID: 'mobileId', }); +const consentConfigMap = { + personalizationConsent: 'adPersonalization', + userDataConsent: 'adUserData', +}; + module.exports = { BASE_ENDPOINT, TYPEOFLIST, @@ -23,4 +28,5 @@ module.exports = { hashAttributes, offlineDataJobsMapping: MAPPING_CONFIG[CONFIG_CATEGORIES.AUDIENCE_LIST.name], addressInfoMapping: MAPPING_CONFIG[CONFIG_CATEGORIES.ADDRESSINFO.name], + consentConfigMap, }; diff --git a/src/v0/destinations/google_adwords_remarketing_lists/networkHandler.js b/src/v0/destinations/google_adwords_remarketing_lists/networkHandler.js index bf703ccb1b1..3045c1713f5 100644 --- a/src/v0/destinations/google_adwords_remarketing_lists/networkHandler.js +++ b/src/v0/destinations/google_adwords_remarketing_lists/networkHandler.js @@ -41,6 +41,8 @@ const createJob = async (endpoint, headers, method, params) => { destType: 'google_adwords_remarketing_lists', feature: 'proxy', endpointPath: '/customers/create', + requestMethod: 'POST', + module: 'dataDelivery', }); return response; }; @@ -65,6 +67,8 @@ const addUserToJob = async (endpoint, headers, method, jobId, body) => { destType: 'google_adwords_remarketing_lists', feature: 'proxy', endpointPath: '/addOperations', + requestMethod: 'POST', + module: 'dataDelivery', }); return response; }; @@ -87,6 +91,8 @@ const runTheJob = async (endpoint, headers, method, jobId) => { destType: 'google_adwords_remarketing_lists', feature: 'proxy', endpointPath: '/run', + requestMethod: 'POST', + module: 'dataDelivery', }); return response; }; @@ -153,7 +159,8 @@ const gaAudienceRespHandler = (destResponse, stageMsg) => { ); }; -const responseHandler = (destinationResponse) => { +const responseHandler = (responseParams) => { + const { destinationResponse } = responseParams; const message = `Request Processed Successfully`; const { status, response } = destinationResponse; if (isHttpStatusSuccess(status)) { diff --git a/src/v0/destinations/google_adwords_remarketing_lists/transform.js b/src/v0/destinations/google_adwords_remarketing_lists/transform.js index 9526973fb8f..b0dfaa0c354 100644 --- a/src/v0/destinations/google_adwords_remarketing_lists/transform.js +++ b/src/v0/destinations/google_adwords_remarketing_lists/transform.js @@ -15,7 +15,7 @@ const { getAccessToken, } = require('../../util'); -const { populateConsentForGoogleDestinations } = require('../../util/googleUtils'); +const { populateConsentFromConfig } = require('../../util/googleUtils'); const { offlineDataJobsMapping, @@ -24,6 +24,7 @@ const { attributeMapping, hashAttributes, TYPEOFLIST, + consentConfigMap, } = require('./config'); const { JSON_MIME_TYPE } = require('../../util/constant'); const { MappedToDestinationKey } = require('../../../constants'); @@ -218,7 +219,7 @@ const processEvent = async (metadata, message, destination) => { } Object.values(createdPayload).forEach((data) => { - const consentObj = populateConsentForGoogleDestinations(message.properties); + const consentObj = populateConsentFromConfig(destination.Config, consentConfigMap); response.push(responseBuilder(metadata, data, destination, message, consentObj)); }); return response; diff --git a/src/v0/destinations/google_cloud_function/transform.js b/src/v0/destinations/google_cloud_function/transform.js index b218615b44d..5e870b95817 100644 --- a/src/v0/destinations/google_cloud_function/transform.js +++ b/src/v0/destinations/google_cloud_function/transform.js @@ -1,9 +1,5 @@ const lodash = require('lodash'); -const { - getSuccessRespEvents, - checkInvalidRtTfEvents, - handleRtTfSingleEventError, -} = require('../../util'); +const { getSuccessRespEvents, handleRtTfSingleEventError } = require('../../util'); const { generateBatchedPayload, validateDestinationConfig } = require('./util'); @@ -40,11 +36,6 @@ function batchEvents(successRespList, maxBatchSize = 10) { // Router transform with batching by default const processRouterDest = async (inputs, reqMetadata) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } - const successResponseList = []; const errorRespList = []; const { destination } = inputs[0]; diff --git a/src/v0/destinations/googlesheets/transform.js b/src/v0/destinations/googlesheets/transform.js index 6e27f6192c1..79dcf1bdf27 100644 --- a/src/v0/destinations/googlesheets/transform.js +++ b/src/v0/destinations/googlesheets/transform.js @@ -5,7 +5,6 @@ const { getValueFromMessage, getSuccessRespEvents, handleRtTfSingleEventError, - checkInvalidRtTfEvents, } = require('../../util'); const SOURCE_KEYS = ['properties', 'traits', 'context.traits']; @@ -111,10 +110,6 @@ const process = (event) => { const processRouterDest = async (inputs, reqMetadata) => { const successRespList = []; const errorRespList = []; - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } await Promise.all( inputs.map(async (input) => { try { diff --git a/src/v0/destinations/hs/config.js b/src/v0/destinations/hs/config.js index 3e91035facc..fb9790f0e5b 100644 --- a/src/v0/destinations/hs/config.js +++ b/src/v0/destinations/hs/config.js @@ -37,7 +37,7 @@ const IDENTIFY_CRM_UPDATE_CONTACT = `${BASE_ENDPOINT}/crm/v3/objects/contacts/:c const BATCH_IDENTIFY_CRM_CREATE_NEW_CONTACT = `${BASE_ENDPOINT}/crm/v3/objects/contacts/batch/create`; const BATCH_IDENTIFY_CRM_UPDATE_CONTACT = `${BASE_ENDPOINT}/crm/v3/objects/contacts/batch/update`; // Ref - https://developers.hubspot.com/docs/api/crm/contacts#endpoint?spec=GET-/crm/v3/objects/contacts -const MAX_BATCH_SIZE_CRM_CONTACT = 10; +const MAX_BATCH_SIZE_CRM_CONTACT = 100; // Track // Ref - https://developers.hubspot.com/docs/api/analytics/events @@ -64,6 +64,8 @@ const API_VERSION = { v3: 'newApi', }; +const MAX_CONTACTS_PER_REQUEST = 100; + const ConfigCategory = { COMMON: { name: 'HSCommonConfig', @@ -109,5 +111,6 @@ module.exports = { SEARCH_LIMIT_VALUE, RETL_SOURCE, RETL_CREATE_ASSOCIATION_OPERATION, + MAX_CONTACTS_PER_REQUEST, DESTINATION: 'HS', }; diff --git a/src/v0/destinations/hs/transform.js b/src/v0/destinations/hs/transform.js index c26e024a6c5..9eed244af4b 100644 --- a/src/v0/destinations/hs/transform.js +++ b/src/v0/destinations/hs/transform.js @@ -1,11 +1,7 @@ const get = require('get-value'); const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); -const { - checkInvalidRtTfEvents, - handleRtTfSingleEventError, - getDestinationExternalIDInfoForRetl, -} = require('../../util'); +const { handleRtTfSingleEventError, getDestinationExternalIDInfoForRetl } = require('../../util'); const { API_VERSION } = require('./config'); const { processLegacyIdentify, @@ -71,10 +67,6 @@ const process = async (event) => { // we are batching by default at routerTransform const processRouterDest = async (inputs, reqMetadata) => { let tempInputs = inputs; - const errorRespEvents = checkInvalidRtTfEvents(tempInputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } const successRespList = []; const errorRespList = []; diff --git a/src/v0/destinations/hs/util.js b/src/v0/destinations/hs/util.js index 5c8f4a908a8..359c93dc1a5 100644 --- a/src/v0/destinations/hs/util.js +++ b/src/v0/destinations/hs/util.js @@ -1,3 +1,5 @@ +/* eslint-disable no-await-in-loop */ +const lodash = require('lodash'); const get = require('get-value'); const { NetworkInstrumentationError, @@ -17,6 +19,7 @@ const { getHashFromArray, getDestinationExternalIDInfoForRetl, getValueFromMessage, + isNull, } = require('../../util'); const { CONTACT_PROPERTY_MAP_ENDPOINT, @@ -25,6 +28,7 @@ const { SEARCH_LIMIT_VALUE, hsCommonConfigJson, DESTINATION, + MAX_CONTACTS_PER_REQUEST, } = require('./config'); const tags = require('../../util/tags'); @@ -101,6 +105,8 @@ const getProperties = async (destination) => { destType: 'hs', feature: 'transformation', endpointPath: `/properties/v1/contacts/properties`, + requestMethod: 'GET', + module: 'router', }); hubspotPropertyMapResponse = processAxiosResponse(hubspotPropertyMapResponse); } else { @@ -113,6 +119,8 @@ const getProperties = async (destination) => { destType: 'hs', feature: 'transformation', endpointPath: `/properties/v1/contacts/properties?hapikey`, + requestMethod: 'GET', + module: 'router', }, ); hubspotPropertyMapResponse = processAxiosResponse(hubspotPropertyMapResponse); @@ -216,7 +224,9 @@ const getTransformedJSON = async (message, destination, propertyMap) => { // lowercase and replace ' ' & '.' with '_' const hsSupportedKey = formatKey(traitsKey); if (!rawPayload[traitsKey] && propertyMap[hsSupportedKey]) { - let propValue = traits[traitsKey]; + // HS accepts empty string to remove the property from contact + // https://community.hubspot.com/t5/APIs-Integrations/Clearing-values-of-custom-properties-in-Hubspot-contact-using/m-p/409156 + let propValue = isNull(traits[traitsKey]) ? '' : traits[traitsKey]; if (propertyMap[hsSupportedKey] === 'date') { propValue = getUTCMidnightTimeStampValue(propValue); } @@ -362,6 +372,8 @@ const searchContacts = async (message, destination) => { destType: 'hs', feature: 'transformation', endpointPath, + requestMethod: 'POST', + module: 'router', }, ); searchContactsResponse = processAxiosResponse(searchContactsResponse); @@ -372,6 +384,8 @@ const searchContacts = async (message, destination) => { destType: 'hs', feature: 'transformation', endpointPath, + requestMethod: 'POST', + module: 'router', }); searchContactsResponse = processAxiosResponse(searchContactsResponse); } @@ -464,42 +478,129 @@ const getEventAndPropertiesFromConfig = (message, destination, payload) => { }; /** - * DOC: https://developers.hubspot.com/docs/api/crm/search + * Validates object and identifier type is present in message + * @param {*} firstMessage + * @returns + */ +const getObjectAndIdentifierType = (firstMessage) => { + const { objectType, identifierType } = getDestinationExternalIDInfoForRetl( + firstMessage, + DESTINATION, + ); + if (!objectType || !identifierType) { + throw new InstrumentationError('rETL - external Id not found.'); + } + return { objectType, identifierType }; +}; + +/** + * Returns values for search api call * @param {*} inputs + * @returns + */ +const extractIDsForSearchAPI = (inputs) => { + const values = inputs.map((input) => { + const { message } = input; + const { destinationExternalId } = getDestinationExternalIDInfoForRetl(message, DESTINATION); + return destinationExternalId.toString().toLowerCase(); + }); + + return Array.from(new Set(values)); +}; + +/** + * Returns hubspot records + * Ref : https://developers.hubspot.com/docs/api/crm/search + * @param {*} data + * @param {*} requestOptions + * @param {*} objectType + * @param {*} identifierType * @param {*} destination + * @returns */ -const getExistingData = async (inputs, destination) => { +const performHubSpotSearch = async ( + reqdata, + reqOptions, + objectType, + identifierType, + destination, +) => { + let checkAfter = 1; + const searchResults = []; + const requestData = reqdata; const { Config } = destination; - let values = []; - let searchResponse; - let updateHubspotIds = []; - const firstMessage = inputs[0].message; - let objectType = null; - let identifierType = null; - - if (firstMessage) { - objectType = getDestinationExternalIDInfoForRetl(firstMessage, DESTINATION).objectType; - identifierType = getDestinationExternalIDInfoForRetl(firstMessage, DESTINATION).identifierType; - if (!objectType || !identifierType) { - throw new InstrumentationError('rETL - external Id not found.'); + + const endpoint = IDENTIFY_CRM_SEARCH_ALL_OBJECTS.replace(':objectType', objectType); + const endpointPath = `objects/:objectType/search`; + + const url = + Config.authorizationType === 'newPrivateAppApi' + ? endpoint + : `${endpoint}?hapikey=${Config.apiKey}`; + + const requestOptions = Config.authorizationType === 'newPrivateAppApi' ? reqOptions : {}; + + /* * + * This is needed for processing paginated response when searching hubspot. + * we can't avoid await in loop as response to the request contains the pagination details + * */ + + while (checkAfter) { + const searchResponse = await httpPOST(url, requestData, requestOptions, { + destType: 'hs', + feature: 'transformation', + endpointPath, + requestMethod: 'POST', + module: 'router', + }); + + const processedResponse = processAxiosResponse(searchResponse); + + if (processedResponse.status !== 200) { + throw new NetworkError( + `rETL - Error during searching object record. ${JSON.stringify( + processedResponse.response?.message, + )}`, + processedResponse.status, + { + [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(processedResponse.status), + }, + processedResponse, + ); + } + + const after = processedResponse.response?.paging?.next?.after || 0; + requestData.after = after; // assigning to the new value of after + checkAfter = after; // assigning to the new value if no after we assign it to 0 and no more calls will take place + + const results = processedResponse.response?.results; + if (results) { + searchResults.push( + ...results.map((result) => ({ + id: result.id, + property: result.properties[identifierType], + })), + ); } - } else { - throw new InstrumentationError('rETL - objectType or identifier type not found. '); } - inputs.map(async (input) => { - const { message } = input; - const { destinationExternalId } = getDestinationExternalIDInfoForRetl(message, DESTINATION); - values.push(destinationExternalId.toString().toLowerCase()); - }); - values = Array.from(new Set(values)); + return searchResults; +}; + +/** + * Returns requestData + * @param {*} identifierType + * @param {*} chunk + * @returns + */ +const getRequestData = (identifierType, chunk) => { const requestData = { filterGroups: [ { filters: [ { propertyName: identifierType, - values, + values: chunk, operator: 'IN', }, ], @@ -510,65 +611,45 @@ const getExistingData = async (inputs, destination) => { after: 0, }; + return requestData; +}; + +/** + * DOC: https://developers.hubspot.com/docs/api/crm/search + * @param {*} inputs + * @param {*} destination + */ +const getExistingContactsData = async (inputs, destination) => { + const { Config } = destination; + const updateHubspotIds = []; + const firstMessage = inputs[0].message; + + if (!firstMessage) { + throw new InstrumentationError('rETL - objectType or identifier type not found.'); + } + + const { objectType, identifierType } = getObjectAndIdentifierType(firstMessage); + + const values = extractIDsForSearchAPI(inputs); + const valuesChunk = lodash.chunk(values, MAX_CONTACTS_PER_REQUEST); const requestOptions = { headers: { 'Content-Type': JSON_MIME_TYPE, Authorization: `Bearer ${Config.accessToken}`, }, }; - let checkAfter = 1; // variable to keep checking if we have more results - - /* eslint-disable no-await-in-loop */ - - /* * - * This is needed for processing paginated response when searching hubspot. - * we can't avoid await in loop as response to the request contains the pagination details - * */ - - while (checkAfter) { - const endpoint = IDENTIFY_CRM_SEARCH_ALL_OBJECTS.replace(':objectType', objectType); - const endpointPath = `objects/:objectType/search`; - - const url = - Config.authorizationType === 'newPrivateAppApi' - ? endpoint - : `${endpoint}?hapikey=${Config.apiKey}`; - searchResponse = - Config.authorizationType === 'newPrivateAppApi' - ? await httpPOST(url, requestData, requestOptions, { - destType: 'hs', - feature: 'transformation', - endpointPath, - }) - : await httpPOST(url, requestData, { - destType: 'hs', - feature: 'transformation', - endpointPath, - }); - searchResponse = processAxiosResponse(searchResponse); - - if (searchResponse.status !== 200) { - throw new NetworkError( - `rETL - Error during searching object record. ${searchResponse.response?.message}`, - searchResponse.status, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(searchResponse.status), - }, - searchResponse, - ); - } - - const after = searchResponse.response?.paging?.next?.after || 0; - - requestData.after = after; // assigning to the new value of after - checkAfter = after; // assigning to the new value if no after we assign it to 0 and no more calls will take place - - const results = searchResponse.response?.results; - if (results) { - updateHubspotIds = results.map((result) => { - const propertyValue = result.properties[identifierType]; - return { id: result.id, property: propertyValue }; - }); + // eslint-disable-next-line no-restricted-syntax + for (const chunk of valuesChunk) { + const requestData = getRequestData(identifierType, chunk); + const searchResults = await performHubSpotSearch( + requestData, + requestOptions, + objectType, + identifierType, + destination, + ); + if (searchResults.length > 0) { + updateHubspotIds.push(...searchResults); } } return updateHubspotIds; @@ -601,7 +682,7 @@ const setHsSearchId = (input, id) => { const splitEventsForCreateUpdate = async (inputs, destination) => { // get all the id and properties of already existing objects needed for update. - const updateHubspotIds = await getExistingData(inputs, destination); + const updateHubspotIds = await getExistingContactsData(inputs, destination); const resultInput = inputs.map((input) => { const { message } = input; @@ -680,4 +761,7 @@ module.exports = { validatePayloadDataTypes, getUTCMidnightTimeStampValue, populateTraits, + getObjectAndIdentifierType, + extractIDsForSearchAPI, + getRequestData, }; diff --git a/src/v0/destinations/hs/util.test.js b/src/v0/destinations/hs/util.test.js index 737b2064014..30e89d3aee5 100644 --- a/src/v0/destinations/hs/util.test.js +++ b/src/v0/destinations/hs/util.test.js @@ -1,4 +1,9 @@ -const { validatePayloadDataTypes } = require('../../../../src/v0/destinations/hs/util'); +const { + getRequestData, + extractIDsForSearchAPI, + validatePayloadDataTypes, + getObjectAndIdentifierType, +} = require('./util'); const propertyMap = { firstName: 'string', @@ -40,3 +45,187 @@ describe('Validate payload data types utility function test cases', () => { } }); }); + +describe('getObjectAndIdentifierType utility test cases', () => { + it('should return an object with objectType and identifierType properties when given a valid input', () => { + const firstMessage = { + type: 'identify', + traits: { + to: { + id: 1, + }, + from: { + id: 940, + }, + }, + userId: '1', + context: { + externalId: [ + { + id: 1, + type: 'HS-association', + toObjectType: 'contacts', + fromObjectType: 'companies', + identifierType: 'id', + associationTypeId: 'engineer', + }, + ], + mappedToDestination: 'true', + }, + }; + const result = getObjectAndIdentifierType(firstMessage); + expect(result).toEqual({ objectType: 'association', identifierType: 'id' }); + }); + + it('should throw an error when objectType or identifierType is not present in input', () => { + const firstMessage = { + type: 'identify', + traits: { + to: { + id: 1, + }, + from: { + id: 940, + }, + }, + userId: '1', + context: { + externalId: [ + { + id: 1, + type: 'HS-', + toObjectType: 'contacts', + fromObjectType: 'companies', + associationTypeId: 'engineer', + }, + ], + mappedToDestination: 'true', + }, + }; + try { + getObjectAndIdentifierType(firstMessage); + } catch (err) { + expect(err.message).toBe('rETL - external Id not found.'); + } + }); +}); + +describe('extractUniqueValues utility test cases', () => { + it('Should return an array of unique values', () => { + const inputs = [ + { + message: { + context: { + externalId: [ + { + identifierType: 'email', + id: 'testhubspot2@email.com', + type: 'HS-lead', + }, + ], + mappedToDestination: true, + }, + }, + }, + { + message: { + context: { + externalId: [ + { + identifierType: 'email', + id: 'Testhubspot3@email.com', + type: 'HS-lead', + }, + ], + mappedToDestination: true, + }, + }, + }, + { + message: { + context: { + externalId: [ + { + identifierType: 'email', + id: 'testhubspot4@email.com', + type: 'HS-lead', + }, + ], + mappedToDestination: true, + }, + }, + }, + { + message: { + context: { + externalId: [ + { + identifierType: 'email', + id: 'testHUBSPOT5@email.com', + type: 'HS-lead', + }, + ], + mappedToDestination: true, + }, + }, + }, + { + message: { + context: { + externalId: [ + { + identifierType: 'email', + id: 'testhubspot2@email.com', + type: 'HS-lead', + }, + ], + mappedToDestination: true, + }, + }, + }, + ]; + + const result = extractIDsForSearchAPI(inputs); + + expect(result).toEqual([ + 'testhubspot2@email.com', + 'testhubspot3@email.com', + 'testhubspot4@email.com', + 'testhubspot5@email.com', + ]); + }); + + it('Should return an empty array when the input is empty', () => { + const inputs = []; + const result = extractIDsForSearchAPI(inputs); + expect(result).toEqual([]); + }); +}); + +describe('getRequestDataAndRequestOptions utility test cases', () => { + it('Should return an object with requestData and requestOptions', () => { + const identifierType = 'email'; + const chunk = 'test1@gmail.com'; + const accessToken = 'dummyAccessToken'; + + const expectedRequestData = { + filterGroups: [ + { + filters: [ + { + propertyName: identifierType, + values: chunk, + operator: 'IN', + }, + ], + }, + ], + properties: [identifierType], + limit: 100, + after: 0, + }; + + const requestData = getRequestData(identifierType, chunk, accessToken); + expect(requestData).toEqual(expectedRequestData); + }); +}); diff --git a/src/v0/destinations/intercom/data/INTERCOMGroupConfig.json b/src/v0/destinations/intercom/data/INTERCOMGroupConfig.json index 174f828a56c..6857c4e1045 100644 --- a/src/v0/destinations/intercom/data/INTERCOMGroupConfig.json +++ b/src/v0/destinations/intercom/data/INTERCOMGroupConfig.json @@ -12,12 +12,12 @@ }, { "destKey": "plan", - "sourceKeys": ["traits.plan","context.traits.plan"], + "sourceKeys": ["traits.plan", "context.traits.plan"], "required": false }, { "destKey": "size", - "sourceKeys": ["traits.size","context.traits.size"], + "sourceKeys": ["traits.size", "context.traits.size"], "metadata": { "type": "toNumber" }, @@ -31,12 +31,12 @@ }, { "destKey": "industry", - "sourceKeys": ["traits.industry","context.traits.industry"], + "sourceKeys": ["traits.industry", "context.traits.industry"], "required": false }, { "destKey": "monthly_spend", - "sourceKeys": ["traits.monthlySpend","context.traits.monthlySpend"], + "sourceKeys": ["traits.monthlySpend", "context.traits.monthlySpend"], "metadata": { "type": "toNumber" }, @@ -44,7 +44,7 @@ }, { "destKey": "remote_created_at", - "sourceKeys": ["traits.remoteCreatedAt","context.traits.remoteCreatedAt"], + "sourceKeys": ["traits.remoteCreatedAt", "context.traits.remoteCreatedAt"], "metadata": { "type": "toNumber" }, diff --git a/src/v0/destinations/intercom/deleteUsers.js b/src/v0/destinations/intercom/deleteUsers.js index 085e8424589..2c35f29e533 100644 --- a/src/v0/destinations/intercom/deleteUsers.js +++ b/src/v0/destinations/intercom/deleteUsers.js @@ -14,7 +14,7 @@ const userDeletionHandler = async (userAttributes, config) => { } const { apiKey } = config; if (!apiKey) { - throw new ConfigurationError('api key for deletion not present'); + throw new ConfigurationError('The access token is not available'); } const validUserIds = []; userAttributes.forEach((userAttribute) => { @@ -39,6 +39,8 @@ const userDeletionHandler = async (userAttributes, config) => { destType: 'intercom', feature: 'deleteUsers', endpointPath: '/user_delete_requests', + requestMethod: 'POST', + module: 'deletion', }); const handledDelResponse = processAxiosResponse(resp); if (!isHttpStatusSuccess(handledDelResponse.status) && handledDelResponse.status !== 404) { @@ -47,6 +49,7 @@ const userDeletionHandler = async (userAttributes, config) => { handledDelResponse.status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(handledDelResponse.status), + [tags.TAG_NAMES.STATUS]: handledDelResponse.status, }, handledDelResponse, ); diff --git a/src/v0/destinations/intercom/networkHandler.js b/src/v0/destinations/intercom/networkHandler.js index a4106257b38..8485dac52e9 100644 --- a/src/v0/destinations/intercom/networkHandler.js +++ b/src/v0/destinations/intercom/networkHandler.js @@ -13,8 +13,9 @@ const errorResponseHandler = (destinationResponse, dest) => { } }; -const destResponseHandler = (destinationResponse, dest) => { - errorResponseHandler(destinationResponse, dest); +const destResponseHandler = (responseParams) => { + const { destinationResponse, destType } = responseParams; + errorResponseHandler(destinationResponse, destType); return { destinationResponse: destinationResponse.response, message: 'Request Processed Successfully', diff --git a/src/v0/destinations/iterable/deleteUsers.js b/src/v0/destinations/iterable/deleteUsers.js index a179a8930f0..015a9de9a05 100644 --- a/src/v0/destinations/iterable/deleteUsers.js +++ b/src/v0/destinations/iterable/deleteUsers.js @@ -36,6 +36,9 @@ const userDeletionHandler = async (userAttributes, config) => { const resp = await httpDELETE(url, requestOptions, { destType: 'iterable', feature: 'deleteUsers', + endpointPath: '/users/byUserId/uId', + requestMethod: 'DELETE', + module: 'deletion', }); const handledDelResponse = processAxiosResponse(resp); if (!isHttpStatusSuccess(handledDelResponse.status) && handledDelResponse.status !== 404) { @@ -46,6 +49,7 @@ const userDeletionHandler = async (userAttributes, config) => { handledDelResponse.status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(handledDelResponse.status), + [tags.TAG_NAMES.STATUS]: handledDelResponse.status, }, handledDelResponse, ); diff --git a/src/v0/destinations/iterable/transform.js b/src/v0/destinations/iterable/transform.js index 64bdcfcfa46..207a8d11865 100644 --- a/src/v0/destinations/iterable/transform.js +++ b/src/v0/destinations/iterable/transform.js @@ -18,7 +18,6 @@ const { const { constructPayload, defaultRequestConfig, - checkInvalidRtTfEvents, defaultPostRequestConfig, handleRtTfSingleEventError, removeUndefinedAndNullValues, @@ -162,11 +161,6 @@ const process = (event) => { }; const processRouterDest = async (inputs, reqMetadata) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } - const batchedEvents = batchEvents(inputs); const response = await Promise.all( batchedEvents.map(async (listOfEvents) => { diff --git a/src/v0/destinations/kafka/transform.js b/src/v0/destinations/kafka/transform.js index b08c7174753..78f278575a5 100644 --- a/src/v0/destinations/kafka/transform.js +++ b/src/v0/destinations/kafka/transform.js @@ -6,7 +6,6 @@ const { getHashFromArray, removeUndefinedAndNullValues, getSuccessRespEvents, - getErrorRespEvents, } = require('../../util'); const filterConfigTopics = (message, destination) => { @@ -38,10 +37,6 @@ const filterConfigTopics = (message, destination) => { const batch = (destEvents) => { const respList = []; - if (!Array.isArray(destEvents) || destEvents.length <= 0) { - const respEvents = getErrorRespEvents(null, 400, 'Invalid event array'); - return [respEvents]; - } // Grouping the events by topic const groupedEvents = groupBy(destEvents, (event) => event.message.topic); diff --git a/src/v0/destinations/klaviyo/data/KlaviyoIdentify.json b/src/v0/destinations/klaviyo/data/KlaviyoIdentify.json index e128f2666c8..b358919bc1e 100644 --- a/src/v0/destinations/klaviyo/data/KlaviyoIdentify.json +++ b/src/v0/destinations/klaviyo/data/KlaviyoIdentify.json @@ -57,7 +57,12 @@ "traits.address.region", "context.traits.region", "context.traits.address.region", - "properties.region" + "properties.region", + "traits.state", + "traits.address.state", + "context.traits.address.state", + "context.traits.state", + "properties.state" ], "required": false }, @@ -77,14 +82,19 @@ "sourceKeys": [ "traits.zip", "traits.postalcode", + "traits.postalCode", "traits.address.zip", "traits.address.postalcode", + "traits.address.postalCode", "context.traits.zip", "context.traits.postalcode", + "context.traits.postalCode", "context.traits.address.zip", "context.traits.address.postalcode", + "context.traits.address.postalCode", "properties.zip", - "properties.postalcode" + "properties.postalcode", + "properties.postalCode" ], "required": false }, @@ -97,5 +107,16 @@ "destKey": "location.timezone", "sourceKeys": ["traits.timezone", "context.traits.timezone", "properties.timezone"], "required": false + }, + { + "destKey": "location.address1", + "sourceKeys": [ + "traits.street", + "traits.address.street", + "context.traits.street", + "context.traits.address.street", + "properties.street" + ], + "required": false } ] diff --git a/src/v0/destinations/klaviyo/data/KlaviyoProfile.json b/src/v0/destinations/klaviyo/data/KlaviyoProfile.json index e2a8d86085b..329ecd978f5 100644 --- a/src/v0/destinations/klaviyo/data/KlaviyoProfile.json +++ b/src/v0/destinations/klaviyo/data/KlaviyoProfile.json @@ -41,7 +41,12 @@ "traits.address.region", "context.traits.region", "context.traits.address.region", - "properties.region" + "properties.region", + "traits.state", + "traits.address.state", + "context.traits.address.state", + "context.traits.state", + "properties.state" ], "required": false }, @@ -61,14 +66,19 @@ "sourceKeys": [ "traits.zip", "traits.postalcode", + "traits.postalCode", "traits.address.zip", "traits.address.postalcode", + "traits.address.postalCode", "context.traits.zip", "context.traits.postalcode", + "context.traits.postalCode", "context.traits.address.zip", "context.traits.address.postalcode", + "context.traits.address.postalCode", "properties.zip", - "properties.postalcode" + "properties.postalcode", + "properties.postalCode" ], "required": false }, @@ -81,5 +91,16 @@ "destKey": "$image", "sourceKeys": ["traits.image", "context.traits.image", "properties.image"], "required": false + }, + { + "destKey": "$address1", + "sourceKeys": [ + "traits.street", + "traits.address.street", + "context.traits.street", + "context.traits.address.street", + "properties.street" + ], + "required": false } ] diff --git a/src/v0/destinations/klaviyo/transform.js b/src/v0/destinations/klaviyo/transform.js index 3c2f8137f27..a0fe3e81a70 100644 --- a/src/v0/destinations/klaviyo/transform.js +++ b/src/v0/destinations/klaviyo/transform.js @@ -32,7 +32,6 @@ const { addExternalIdToTraits, adduserIdFromExternalId, getSuccessRespEvents, - checkInvalidRtTfEvents, handleRtTfSingleEventError, flattenJson, isNewStatusCodesAccepted, @@ -320,10 +319,6 @@ const getEventChunks = (event, subscribeRespList, nonSubscribeRespList) => { }; const processRouterDest = async (inputs, reqMetadata) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } let batchResponseList = []; const batchErrorRespList = []; const subscribeRespList = []; diff --git a/src/v0/destinations/klaviyo/util.js b/src/v0/destinations/klaviyo/util.js index 60b334f3a2f..df2dbb47121 100644 --- a/src/v0/destinations/klaviyo/util.js +++ b/src/v0/destinations/klaviyo/util.js @@ -45,6 +45,8 @@ const getIdFromNewOrExistingProfile = async (endpoint, payload, requestOptions) destType: 'klaviyo', feature: 'transformation', endpointPath, + requestMethod: 'POST', + module: 'router', }, ); diff --git a/src/v0/destinations/kustomer/util.js b/src/v0/destinations/kustomer/util.js index 571a03f1399..530983bb26b 100644 --- a/src/v0/destinations/kustomer/util.js +++ b/src/v0/destinations/kustomer/util.js @@ -139,7 +139,13 @@ const fetchKustomer = async (url, destination) => { Authorization: `Bearer ${destination.Config.apiKey}`, }, }, - { destType: 'kustomer', feature: 'transformation' }, + { + destType: 'kustomer', + feature: 'transformation', + endpointPath: '/customers/email', + requestMethod: 'GET', + module: 'processor', + }, ); } catch (err) { if (err.response) { diff --git a/src/v0/destinations/lambda/transform.js b/src/v0/destinations/lambda/transform.js index 1570a69ec31..efc68b89d6f 100644 --- a/src/v0/destinations/lambda/transform.js +++ b/src/v0/destinations/lambda/transform.js @@ -1,5 +1,6 @@ const _ = require('lodash'); -const { getErrorRespEvents, getSuccessRespEvents } = require('../../util'); +const { getErrorRespEvents } = require('@rudderstack/integrations-lib'); +const { getSuccessRespEvents } = require('../../util'); const { ConfigurationError } = require('@rudderstack/integrations-lib'); const DEFAULT_INVOCATION_TYPE = 'Event'; // asynchronous invocation diff --git a/src/v0/destinations/mailchimp/transform.js b/src/v0/destinations/mailchimp/transform.js index 894f70672a5..87f547c1248 100644 --- a/src/v0/destinations/mailchimp/transform.js +++ b/src/v0/destinations/mailchimp/transform.js @@ -3,7 +3,6 @@ const { InstrumentationError, ConfigurationError } = require('@rudderstack/integ const { defaultPutRequestConfig, handleRtTfSingleEventError, - checkInvalidRtTfEvents, constructPayload, defaultPostRequestConfig, isDefinedAndNotNull, @@ -162,10 +161,6 @@ const getEventChunks = (event, identifyRespList, trackRespList) => { }; const processRouterDest = async (inputs, reqMetadata) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } let batchResponseList = []; const batchErrorRespList = []; const identifyRespList = []; diff --git a/src/v0/destinations/mailchimp/utils.js b/src/v0/destinations/mailchimp/utils.js index e1e2e9883b7..1f4fc03ee5b 100644 --- a/src/v0/destinations/mailchimp/utils.js +++ b/src/v0/destinations/mailchimp/utils.js @@ -163,7 +163,13 @@ const checkIfMailExists = async (apiKey, datacenterId, audienceId, email) => { Authorization: `Basic ${basicAuth}`, }, }, - { destType: 'mailchimp', feature: 'transformation' }, + { + destType: 'mailchimp', + feature: 'transformation', + endpointPath: '/lists/audienceId/members/email', + requestMethod: 'GET', + module: 'router', + }, ); if (response?.data?.contact_id) { userStatus.exists = true; @@ -194,7 +200,13 @@ const checkIfDoubleOptIn = async (apiKey, datacenterId, audienceId) => { Authorization: `Basic ${basicAuth}`, }, }, - { destType: 'mailchimp', feature: 'transformation' }, + { + destType: 'mailchimp', + feature: 'transformation', + endpointPath: '/lists/audienceId', + requestMethod: 'GET', + module: 'router', + }, ); } catch (error) { const status = error.status || 400; diff --git a/src/v0/destinations/mailjet/transform.js b/src/v0/destinations/mailjet/transform.js index 9156bf45e95..78b4f766d1d 100644 --- a/src/v0/destinations/mailjet/transform.js +++ b/src/v0/destinations/mailjet/transform.js @@ -1,7 +1,6 @@ const lodash = require('lodash'); const { TransformationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { - getErrorRespEvents, getSuccessRespEvents, defaultRequestConfig, defaultPostRequestConfig, @@ -121,10 +120,6 @@ const batchEvents = (successRespList) => { }; const processRouterDest = (inputs, reqMetadata) => { - if (!Array.isArray(inputs) || inputs.length <= 0) { - const respEvents = getErrorRespEvents(null, 400, 'Invalid event array'); - return [respEvents]; - } let batchResponseList = []; const batchErrorRespList = []; const successRespList = []; diff --git a/src/v0/destinations/mailmodo/transform.js b/src/v0/destinations/mailmodo/transform.js index 756522939da..a61ca8a73d0 100644 --- a/src/v0/destinations/mailmodo/transform.js +++ b/src/v0/destinations/mailmodo/transform.js @@ -10,7 +10,6 @@ const { defaultPostRequestConfig, defaultBatchRequestConfig, removeUndefinedAndNullValues, - getErrorRespEvents, getSuccessRespEvents, handleRtTfSingleEventError, } = require('../../util'); @@ -191,11 +190,6 @@ function getEventChunks(event, identifyEventChunks, eventResponseList) { } const processRouterDest = (inputs, reqMetadata) => { - if (!Array.isArray(inputs) || inputs.length <= 0) { - const respEvents = getErrorRespEvents(null, 400, 'Invalid event array'); - return [respEvents]; - } - const identifyEventChunks = []; // list containing identify events in batched format const eventResponseList = []; // list containing other events in batched format const errorRespList = []; diff --git a/src/v0/destinations/marketo/networkHandler.js b/src/v0/destinations/marketo/networkHandler.js index 7abcc65c02a..ac555accfe2 100644 --- a/src/v0/destinations/marketo/networkHandler.js +++ b/src/v0/destinations/marketo/networkHandler.js @@ -3,9 +3,10 @@ const { marketoResponseHandler } = require('./util'); const { proxyRequest, prepareProxyRequest } = require('../../../adapters/network'); const { processAxiosResponse } = require('../../../adapters/utils/networkUtils'); -const responseHandler = (destinationResponse, destType) => { +const responseHandler = (responseParams) => { + const { destinationResponse, destType, rudderJobMetadata } = responseParams; const message = 'Request Processed Successfully'; - const { status, rudderJobMetadata } = destinationResponse; + const { status } = destinationResponse; const authCache = v0Utils.getDestAuthCacheInstance(destType); // check for marketo application level failures marketoResponseHandler( diff --git a/src/v0/destinations/marketo/transform.js b/src/v0/destinations/marketo/transform.js index 5000ef506b3..b811596f95a 100644 --- a/src/v0/destinations/marketo/transform.js +++ b/src/v0/destinations/marketo/transform.js @@ -7,6 +7,7 @@ const { InstrumentationError, ConfigurationError, UnauthorizedError, + getErrorRespEvents, } = require('@rudderstack/integrations-lib'); const stats = require('../../../util/stats'); const { EventType, MappedToDestinationKey } = require('../../../constants'); @@ -28,10 +29,8 @@ const { getFieldValueFromMessage, getDestinationExternalID, getSuccessRespEvents, - getErrorRespEvents, isDefinedAndNotNull, generateErrorObject, - checkInvalidRtTfEvents, handleRtTfSingleEventError, } = require('../../util'); const Cache = require('../../util/cache'); @@ -456,10 +455,6 @@ const process = async (event) => { const processRouterDest = async (inputs, reqMetadata) => { // Token needs to be generated for marketo which will be done on input level. // If destination information is not present Error should be thrown - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } let token; try { token = await getAuthToken(formatConfig(inputs[0].destination)); diff --git a/src/v0/destinations/marketo/util.js b/src/v0/destinations/marketo/util.js index 54ff70708a7..b3a24fb4110 100644 --- a/src/v0/destinations/marketo/util.js +++ b/src/v0/destinations/marketo/util.js @@ -248,6 +248,8 @@ const sendGetRequest = async (url, options) => { destType: 'marketo', feature: 'transformation', endpointPath: `/v1/leads`, + requestMethod: 'GET', + module: 'router', }); const processedResponse = processAxiosResponse(clientResponse); return processedResponse; @@ -264,6 +266,8 @@ const sendPostRequest = async (url, data, options) => { destType: 'marketo', feature: 'transformation', endpointPath: `/v1/leads`, + requestMethod: 'POST', + module: 'router', }); const processedResponse = processAxiosResponse(clientResponse); return processedResponse; diff --git a/src/v0/destinations/marketo_bulk_upload/config.js b/src/v0/destinations/marketo_bulk_upload/config.js index 487e11fe240..e3268711fe1 100644 --- a/src/v0/destinations/marketo_bulk_upload/config.js +++ b/src/v0/destinations/marketo_bulk_upload/config.js @@ -18,6 +18,24 @@ const FETCH_FAILURE_JOB_STATUS_ERR_MSG = 'Could not fetch failure job status'; const FETCH_WARNING_JOB_STATUS_ERR_MSG = 'Could not fetch warning job status'; const ACCESS_TOKEN_FETCH_ERR_MSG = 'Error during fetching access token'; +const SCHEMA_DATA_TYPE_MAP = { + string: 'string', + number: 'number', + boolean: 'boolean', + undefined: 'undefined', + float: 'number', + text: 'string', + currency: 'string', + integer: 'number', + reference: 'string', + datetime: 'string', + date: 'string', + email: 'string', + phone: 'string', + url: 'string', + object: 'object', +}; + module.exports = { ABORTABLE_CODES, RETRYABLE_CODES, @@ -33,4 +51,5 @@ module.exports = { FETCH_FAILURE_JOB_STATUS_ERR_MSG, FETCH_WARNING_JOB_STATUS_ERR_MSG, ACCESS_TOKEN_FETCH_ERR_MSG, + SCHEMA_DATA_TYPE_MAP, }; diff --git a/src/v0/destinations/marketo_bulk_upload/fetchJobStatus.js b/src/v0/destinations/marketo_bulk_upload/fetchJobStatus.js index e6f56620003..db3b13eeb84 100644 --- a/src/v0/destinations/marketo_bulk_upload/fetchJobStatus.js +++ b/src/v0/destinations/marketo_bulk_upload/fetchJobStatus.js @@ -33,6 +33,9 @@ const getJobsStatus = async (event, type, accessToken) => { const { processedResponse: resp } = await handleHttpRequest('get', url, requestOptions, { destType: 'marketo_bulk_upload', feature: 'transformation', + endpointPath: '/leads/batch/', + requestMethod: 'GET', + module: 'router', }); const endTime = Date.now(); const requestTime = endTime - startTime; diff --git a/src/v0/destinations/marketo_bulk_upload/fileUpload.js b/src/v0/destinations/marketo_bulk_upload/fileUpload.js index 9c42fdc98d0..b49a265fd53 100644 --- a/src/v0/destinations/marketo_bulk_upload/fileUpload.js +++ b/src/v0/destinations/marketo_bulk_upload/fileUpload.js @@ -198,6 +198,9 @@ const getImportID = async (input, config, accessToken, csvHeader) => { { destType: 'marketo_bulk_upload', feature: 'transformation', + endpointPath: '/leads.json', + requestMethod: 'POST', + module: 'router', }, ); const endTime = Date.now(); diff --git a/src/v0/destinations/marketo_bulk_upload/marketo_bulk_upload.util.test.js b/src/v0/destinations/marketo_bulk_upload/marketo_bulk_upload.util.test.js index 769fa4006d2..aa4b3aacc4f 100644 --- a/src/v0/destinations/marketo_bulk_upload/marketo_bulk_upload.util.test.js +++ b/src/v0/destinations/marketo_bulk_upload/marketo_bulk_upload.util.test.js @@ -3,6 +3,7 @@ const { handlePollResponse, handleFileUploadResponse, getAccessToken, + checkEventStatusViaSchemaMatching, } = require('./util'); const { @@ -295,6 +296,10 @@ describe('getAccessToken', () => { expect(handleHttpRequest).toHaveBeenCalledWith('get', url, { destType: 'marketo_bulk_upload', feature: 'transformation', + endpointPath: '/identity/oauth/token', + feature: 'transformation', + module: 'router', + requestMethod: 'GET', }); }); @@ -353,3 +358,187 @@ describe('getAccessToken', () => { await expect(getAccessToken(config)).rejects.toThrow(TransformationError); }); }); + +describe('checkEventStatusViaSchemaMatching', () => { + // The function correctly identifies fields with expected data types. + it('if event data types match with expected data types we send no field as mismatch', () => { + const event = { + input: [ + { + message: { + email: 'value1', + id: 123, + isLead: true, + }, + metadata: { + job_id: 'job1', + }, + }, + ], + }; + const fieldSchemaMapping = { + email: 'string', + id: 'integer', + isLead: 'boolean', + }; + + const result = checkEventStatusViaSchemaMatching(event, fieldSchemaMapping); + + expect(result).toEqual({}); + }); + + // The function correctly identifies fields with unexpected data types. + it('if event data types do not match with expected data types we send that field as mismatch', () => { + const event = { + input: [ + { + message: { + email: 123, + city: '123', + islead: true, + }, + metadata: { + job_id: 'job1', + }, + }, + ], + }; + const fieldSchemaMapping = { + email: 'string', + city: 'number', + islead: 'boolean', + }; + + const result = checkEventStatusViaSchemaMatching(event, fieldSchemaMapping); + + expect(result).toEqual({ + job1: 'invalid email', + }); + }); + + // The function correctly handles events with multiple fields. + it('For array of events the mismatch object fills up with each event errors', () => { + const event = { + input: [ + { + message: { + id: 'value1', + testCustomFieldScore: 123, + isLead: true, + }, + metadata: { + job_id: 'job1', + }, + }, + { + message: { + email: 'value2', + id: 456, + testCustomFieldScore: false, + }, + metadata: { + job_id: 'job2', + }, + }, + ], + }; + const fieldSchemaMapping = { + email: 'email', + id: 'integer', + testCustomFieldScore: 'integer', + isLead: 'boolean', + }; + + const result = checkEventStatusViaSchemaMatching(event, fieldSchemaMapping); + + expect(result).toEqual({ + job1: 'invalid id', + job2: 'invalid testCustomFieldScore', + }); + }); + + // The function correctly handles events with missing fields. + it('it is not mandatory to send all the fields present in schema', () => { + const event = { + input: [ + { + message: { + email: 'value1', + isLead: true, + }, + metadata: { + job_id: 'job1', + }, + }, + ], + }; + const fieldSchemaMapping = { + email: 'string', + id: 'number', + isLead: 'boolean', + }; + + const result = checkEventStatusViaSchemaMatching(event, fieldSchemaMapping); + + expect(result).toEqual({}); + }); + + // The function correctly handles events with additional fields. But this will not happen in our use case + it('for any field beyond schema fields will be mapped as invalid', () => { + const event = { + input: [ + { + message: { + email: 'value1', + id: 124, + isLead: true, + abc: 'value2', + }, + metadata: { + job_id: 'job1', + }, + }, + ], + }; + const fieldSchemaMapping = { + email: 'string', + id: 'number', + isLead: 'boolean', + }; + + const result = checkEventStatusViaSchemaMatching(event, fieldSchemaMapping); + + expect(result).toEqual({ + job1: 'invalid abc', + }); + }); + + // The function correctly handles events with null values. + it('should correctly handle events with null values', () => { + const event = { + input: [ + { + message: { + email: 'value1', + id: null, + isLead: true, + }, + metadata: { + job_id: 'job1', + }, + }, + ], + }; + const fieldSchemaMapping = { + email: 'string', + id: 'number', + isLead: 'boolean', + }; + + const result = checkEventStatusViaSchemaMatching(event, fieldSchemaMapping); + + expect(result).toEqual({ + job1: 'invalid id', + }); + }); +}); diff --git a/src/v0/destinations/marketo_bulk_upload/poll.js b/src/v0/destinations/marketo_bulk_upload/poll.js index db7a6347744..f53347d6e52 100644 --- a/src/v0/destinations/marketo_bulk_upload/poll.js +++ b/src/v0/destinations/marketo_bulk_upload/poll.js @@ -26,6 +26,9 @@ const getPollStatus = async (event) => { { destType: 'marketo_bulk_upload', feature: 'transformation', + endpointPath: '/leads/batch/importId.json', + requestMethod: 'GET', + module: 'router', }, ); if (!isHttpStatusSuccess(pollStatus.status)) { diff --git a/src/v0/destinations/marketo_bulk_upload/transform.js b/src/v0/destinations/marketo_bulk_upload/transform.js index 5431e67d38a..1943d817cde 100644 --- a/src/v0/destinations/marketo_bulk_upload/transform.js +++ b/src/v0/destinations/marketo_bulk_upload/transform.js @@ -1,4 +1,4 @@ -const { InstrumentationError } = require('@rudderstack/integrations-lib'); +const { InstrumentationError, isDefined } = require('@rudderstack/integrations-lib'); const { getHashFromArray, getFieldValueFromMessage, @@ -34,7 +34,7 @@ function responseBuilderSimple(message, destination) { // columnNames with trait's values from rudder payload Object.keys(fieldHashmap).forEach((key) => { const val = traits[fieldHashmap[key]]; - if (val) { + if (isDefined(val)) { payload[key] = val; } }); diff --git a/src/v0/destinations/marketo_bulk_upload/util.js b/src/v0/destinations/marketo_bulk_upload/util.js index 8b46212b876..4c99ba7483f 100644 --- a/src/v0/destinations/marketo_bulk_upload/util.js +++ b/src/v0/destinations/marketo_bulk_upload/util.js @@ -18,6 +18,7 @@ const { POLL_STATUS_ERR_MSG, FILE_UPLOAD_ERR_MSG, ACCESS_TOKEN_FETCH_ERR_MSG, + SCHEMA_DATA_TYPE_MAP, } = require('./config'); const logger = require('../../../logger'); @@ -127,6 +128,9 @@ const getAccessToken = async (config) => { const { processedResponse: accessTokenResponse } = await handleHttpRequest('get', url, { destType: 'marketo_bulk_upload', feature: 'transformation', + endpointPath: '/identity/oauth/token', + requestMethod: 'GET', + module: 'router', }); // sample response : {response: '[ENOTFOUND] :: DNS lookup failed', status: 400} @@ -351,6 +355,9 @@ const getFieldSchemaMap = async (accessToken, munchkinId) => { { destType: 'marketo_bulk_upload', feature: 'transformation', + endpointPath: '/leads/describe2.json', + requestMethod: 'GET', + module: 'router', }, ); @@ -401,14 +408,9 @@ const checkEventStatusViaSchemaMatching = (event, fieldMap) => { const { job_id } = metadata; Object.entries(message).forEach(([paramName, paramValue]) => { - let expectedDataType = fieldMap[paramName]; + const expectedDataType = SCHEMA_DATA_TYPE_MAP[fieldMap[paramName]]; const actualDataType = typeof paramValue; - // If expectedDataType is not one of the primitive data types, treat it as a string - if (!['string', 'number', 'boolean', 'undefined'].includes(expectedDataType)) { - expectedDataType = 'string'; - } - if (!mismatchedFields[job_id] && actualDataType !== expectedDataType) { mismatchedFields[job_id] = `invalid ${paramName}`; } diff --git a/src/v0/destinations/marketo_static_list/networkHandler.js b/src/v0/destinations/marketo_static_list/networkHandler.js index 30b053b9d3e..086378cf6ac 100644 --- a/src/v0/destinations/marketo_static_list/networkHandler.js +++ b/src/v0/destinations/marketo_static_list/networkHandler.js @@ -4,9 +4,10 @@ const v0Utils = require('../../util'); const { processAxiosResponse } = require('../../../adapters/utils/networkUtils'); const { DESTINATION } = require('./config'); -const responseHandler = (destinationResponse, destType) => { +const responseHandler = (responseParams) => { + const { destinationResponse, destType, rudderJobMetadata } = responseParams; const message = 'Request Processed Successfully'; - const { status, rudderJobMetadata } = destinationResponse; + const { status } = destinationResponse; const authCache = v0Utils.getDestAuthCacheInstance(destType); // check for marketo application level failures marketoResponseHandler( diff --git a/src/v0/destinations/marketo_static_list/transform.js b/src/v0/destinations/marketo_static_list/transform.js index 294e34f91bc..92c137c614d 100644 --- a/src/v0/destinations/marketo_static_list/transform.js +++ b/src/v0/destinations/marketo_static_list/transform.js @@ -1,6 +1,10 @@ const lodash = require('lodash'); const cloneDeep = require('lodash/cloneDeep'); -const { InstrumentationError, UnauthorizedError } = require('@rudderstack/integrations-lib'); +const { + InstrumentationError, + UnauthorizedError, + getErrorRespEvents, +} = require('@rudderstack/integrations-lib'); const { defaultPostRequestConfig, defaultDeleteRequestConfig, @@ -9,11 +13,7 @@ const { } = require('../../util'); const { AUTH_CACHE_TTL, JSON_MIME_TYPE } = require('../../util/constant'); const { getIds, validateMessageType } = require('./util'); -const { - getDestinationExternalID, - defaultRequestConfig, - getErrorRespEvents, -} = require('../../util'); +const { getDestinationExternalID, defaultRequestConfig } = require('../../util'); const { formatConfig, MAX_LEAD_IDS_SIZE } = require('./config'); const Cache = require('../../util/cache'); const { getAuthToken } = require('../marketo/transform'); diff --git a/src/v0/destinations/marketo_static_list/transformV2.js b/src/v0/destinations/marketo_static_list/transformV2.js index 912d548d098..73d4bec8f81 100644 --- a/src/v0/destinations/marketo_static_list/transformV2.js +++ b/src/v0/destinations/marketo_static_list/transformV2.js @@ -1,5 +1,9 @@ const lodash = require('lodash'); -const { InstrumentationError, UnauthorizedError } = require('@rudderstack/integrations-lib'); +const { + InstrumentationError, + UnauthorizedError, + getErrorRespEvents, +} = require('@rudderstack/integrations-lib'); const { defaultPostRequestConfig, defaultDeleteRequestConfig, @@ -7,7 +11,6 @@ const { getSuccessRespEvents, isDefinedAndNotNull, generateErrorObject, - getErrorRespEvents, } = require('../../util'); const { JSON_MIME_TYPE } = require('../../util/constant'); const { MAX_LEAD_IDS_SIZE } = require('./config'); diff --git a/src/v0/destinations/mautic/utils.js b/src/v0/destinations/mautic/utils.js index d8ad8dbffcd..7a1827e769a 100644 --- a/src/v0/destinations/mautic/utils.js +++ b/src/v0/destinations/mautic/utils.js @@ -183,6 +183,9 @@ const searchContactIds = async (message, Config, baseUrl) => { { destType: 'mautic', feature: 'transformation', + endpointPath: '/contacts', + requestMethod: 'GET', + module: 'router', }, ); searchContactsResponse = processAxiosResponse(searchContactsResponse); diff --git a/src/v0/destinations/monday/util.js b/src/v0/destinations/monday/util.js index 736f0133fde..872fad42a75 100644 --- a/src/v0/destinations/monday/util.js +++ b/src/v0/destinations/monday/util.js @@ -195,6 +195,8 @@ const getBoardDetails = async (url, boardID, apiToken) => { destType: 'monday', feature: 'transformation', endpointPath: '/v2', + requestMethod: 'POST', + module: 'router', }, ); const boardDetailsResponse = processAxiosResponse(clientResponse); diff --git a/src/v0/destinations/mp/deleteUsers.js b/src/v0/destinations/mp/deleteUsers.js index f01475ef2b8..e1240c609d6 100644 --- a/src/v0/destinations/mp/deleteUsers.js +++ b/src/v0/destinations/mp/deleteUsers.js @@ -49,6 +49,8 @@ const deleteProfile = async (userAttributes, config) => { destType: 'mp', feature: 'deleteUsers', endpointPath, + requestMethod: 'POST', + module: 'deletion', }, ); if (!isHttpStatusSuccess(handledDelResponse.status)) { @@ -57,6 +59,7 @@ const deleteProfile = async (userAttributes, config) => { handledDelResponse.status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(handledDelResponse.status), + [tags.TAG_NAMES.STATUS]: handledDelResponse.status, }, handledDelResponse, ); @@ -104,6 +107,8 @@ const createDeletionTask = async (userAttributes, config) => { destType: 'mp', feature: 'deleteUsers', endpointPath, + requestMethod: 'POST', + module: 'deletion', }, ); if (!isHttpStatusSuccess(handledDelResponse.status)) { diff --git a/src/v0/destinations/mp/transform.js b/src/v0/destinations/mp/transform.js index ef18b3d0d17..43e3c4b3768 100644 --- a/src/v0/destinations/mp/transform.js +++ b/src/v0/destinations/mp/transform.js @@ -14,10 +14,10 @@ const { removeUndefinedValues, toUnixTimestampInMS, getFieldValueFromMessage, - checkInvalidRtTfEvents, handleRtTfSingleEventError, groupEventsByType, parseConfigArray, + combineBatchRequestsWithSameJobIds, } = require('../../util'); const { ConfigCategory, @@ -32,10 +32,11 @@ const { createIdentifyResponse, isImportAuthCredentialsAvailable, buildUtmParams, - combineBatchRequestsWithSameJobIds, groupEventsByEndpoint, batchEvents, trimTraits, + generatePageOrScreenCustomEventName, + recordBatchSizeMetrics, } = require('./util'); const { CommonUtils } = require('../../../util/common'); @@ -48,11 +49,11 @@ const setImportCredentials = (destConfig) => { const params = { strict: destConfig.strictMode ? 1 : 0 }; const { serviceAccountUserName, serviceAccountSecret, projectId, token } = destConfig; let credentials; - if (serviceAccountUserName && serviceAccountSecret && projectId) { + if (token) { + credentials = `${token}:`; + } else if (serviceAccountUserName && serviceAccountSecret && projectId) { credentials = `${serviceAccountUserName}:${serviceAccountSecret}`; params.projectId = projectId; - } else { - credentials = `${token}:`; } const headers = { 'Content-Type': 'application/json', @@ -285,17 +286,25 @@ const processIdentifyEvents = async (message, type, destination) => { }; const processPageOrScreenEvents = (message, type, destination) => { + const { + token, + identityMergeApi, + useUserDefinedPageEventName, + userDefinedPageEventTemplate, + useUserDefinedScreenEventName, + userDefinedScreenEventTemplate, + } = destination.Config; const mappedProperties = constructPayload(message, mPEventPropertiesConfigJson); let properties = { ...get(message, 'context.traits'), ...message.properties, ...mappedProperties, - token: destination.Config.token, + token, distinct_id: message.userId || message.anonymousId, time: toUnixTimestampInMS(message.timestamp || message.originalTimestamp), ...buildUtmParams(message.context?.campaign), }; - if (destination.Config?.identityMergeApi === 'simplified') { + if (identityMergeApi === 'simplified') { properties = { ...properties, distinct_id: message.userId || `$device:${message.anonymousId}`, @@ -314,7 +323,18 @@ const processPageOrScreenEvents = (message, type, destination) => { properties.$browser = browser.name; properties.$browser_version = browser.version; } - const eventName = type === 'page' ? 'Loaded a Page' : 'Loaded a Screen'; + + let eventName; + if (type === 'page') { + eventName = useUserDefinedPageEventName + ? generatePageOrScreenCustomEventName(message, userDefinedPageEventTemplate) + : 'Loaded a Page'; + } else { + eventName = useUserDefinedScreenEventName + ? generatePageOrScreenCustomEventName(message, userDefinedScreenEventTemplate) + : 'Loaded a Screen'; + } + const payload = { event: eventName, properties, @@ -447,10 +467,11 @@ const process = (event) => processSingleMessage(event.message, event.destination // Ref: https://help.mixpanel.com/hc/en-us/articles/115004613766-Default-Properties-Collected-by-Mixpanel // Ref: https://help.mixpanel.com/hc/en-us/articles/115004561786-Track-UTM-Tags const processRouterDest = async (inputs, reqMetadata) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } + const batchSize = { + engage: 0, + groups: 0, + import: 0, + }; const groupedEvents = groupEventsByType(inputs); const response = await Promise.all( @@ -488,12 +509,19 @@ const processRouterDest = async (inputs, reqMetadata) => { const importRespList = batchEvents(importEvents, IMPORT_MAX_BATCH_SIZE, reqMetadata); const batchSuccessRespList = [...engageRespList, ...groupsRespList, ...importRespList]; + batchSize.engage += engageRespList.length; + batchSize.groups += groupsRespList.length; + batchSize.import += importRespList.length; + return [...batchSuccessRespList, ...batchErrorRespList]; }), ); // Flatten the response array containing batched events from multiple groups const allBatchedEvents = lodash.flatMap(response); + + const { destination } = allBatchedEvents[0]; + recordBatchSizeMetrics(batchSize, destination.ID); return combineBatchRequestsWithSameJobIds(allBatchedEvents); }; diff --git a/src/v0/destinations/mp/util.js b/src/v0/destinations/mp/util.js index 802438184c6..398a0452d5b 100644 --- a/src/v0/destinations/mp/util.js +++ b/src/v0/destinations/mp/util.js @@ -1,7 +1,7 @@ const lodash = require('lodash'); const set = require('set-value'); const get = require('get-value'); -const { InstrumentationError } = require('@rudderstack/integrations-lib'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { isDefined, constructPayload, @@ -16,6 +16,7 @@ const { IsGzipSupported, isObject, isDefinedAndNotNullAndNotEmpty, + isDefinedAndNotNull, } = require('../../util'); const { ConfigCategory, @@ -24,6 +25,7 @@ const { mappingConfig, } = require('./config'); const { CommonUtils } = require('../../../util/common'); +const stats = require('../../../util/stats'); const mPIdentifyConfigJson = mappingConfig[ConfigCategory.IDENTIFY.name]; const mPProfileAndroidConfigJson = mappingConfig[ConfigCategory.PROFILE_ANDROID.name]; @@ -139,44 +141,6 @@ const isImportAuthCredentialsAvailable = (destination) => destination.Config.serviceAccountUserName && destination.Config.projectId); -/** - * Finds an existing batch based on metadata JobIds from the provided batch and metadataMap. - * @param {*} batch - * @param {*} metadataMap The map containing metadata items indexed by JobIds. - * @returns - */ -const findExistingBatch = (batch, metadataMap) => { - let existingBatch = null; - - // eslint-disable-next-line no-restricted-syntax - for (const metadataItem of batch.metadata) { - if (metadataMap.has(metadataItem.jobId)) { - existingBatch = metadataMap.get(metadataItem.jobId); - break; - } - } - - return existingBatch; -}; - -/** - * Removes duplicate metadata within each merged batch object. - * @param {*} mergedBatches An array of merged batch objects. - */ -const removeDuplicateMetadata = (mergedBatches) => { - mergedBatches.forEach((batch) => { - const metadataSet = new Set(); - // eslint-disable-next-line no-param-reassign - batch.metadata = batch.metadata.filter((metadataItem) => { - if (!metadataSet.has(metadataItem.jobId)) { - metadataSet.add(metadataItem.jobId); - return true; - } - return false; - }); - }); -}; - /** * Builds UTM parameters from a campaign object. * @@ -271,58 +235,6 @@ const batchEvents = (successRespList, maxBatchSize, reqMetadata) => { }); }; -/** - * Combines batched requests with the same JobIds. - * @param {*} inputBatches The array of batched request objects. - * @returns The combined batched requests with merged JobIds. - * - */ -const combineBatchRequestsWithSameJobIds = (inputBatches) => { - const combineBatches = (batches) => { - const clonedBatches = [...batches]; - const mergedBatches = []; - const metadataMap = new Map(); - - clonedBatches.forEach((batch) => { - const existingBatch = findExistingBatch(batch, metadataMap); - - if (existingBatch) { - // Merge batchedRequests arrays - existingBatch.batchedRequest = [ - ...(Array.isArray(existingBatch.batchedRequest) - ? existingBatch.batchedRequest - : [existingBatch.batchedRequest]), - ...(Array.isArray(batch.batchedRequest) ? batch.batchedRequest : [batch.batchedRequest]), - ]; - - // Merge metadata - batch.metadata.forEach((metadataItem) => { - if (!metadataMap.has(metadataItem.jobId)) { - metadataMap.set(metadataItem.jobId, existingBatch); - } - existingBatch.metadata.push(metadataItem); - }); - } else { - mergedBatches.push(batch); - batch.metadata.forEach((metadataItem) => { - metadataMap.set(metadataItem.jobId, batch); - }); - } - }); - - // Remove duplicate metadata within each merged object - removeDuplicateMetadata(mergedBatches); - - return mergedBatches; - }; - // We need to run this twice because in first pass some batches might not get merged - // and in second pass they might get merged - // Example: [[{jobID:1}, {jobID:2}], [{jobID:3}], [{jobID:1}, {jobID:3}]] - // 1st pass: [[{jobID:1}, {jobID:2}, {jobID:3}], [{jobID:3}]] - // 2nd pass: [[{jobID:1}, {jobID:2}, {jobID:3}]] - return combineBatches(combineBatches(inputBatches)); -}; - /** * Trims the traits and contextTraits objects based on the setOnceProperties array and returns an object containing the modified traits, contextTraits, and setOnce properties. * @@ -389,6 +301,68 @@ function trimTraits(traits, contextTraits, setOnceProperties) { }; } +/** + * Generates a custom event name for a page or screen. + * + * @param {Object} message - The message object + * @param {string} userDefinedEventTemplate - The user-defined event template to be used for generating the event name. + * @throws {ConfigurationError} If the event template is missing. + * @returns {string} The generated custom event name. + * @example + * const userDefinedEventTemplate = "Viewed {{ category }} {{ name }} Page"; + * const message = {name: 'Home', properties: {category: 'Index'}}; + * output: "Viewed Index Home Page" + */ +const generatePageOrScreenCustomEventName = (message, userDefinedEventTemplate) => { + if (!userDefinedEventTemplate) { + throw new ConfigurationError( + 'Event name template is not configured. Please provide a valid value for the `Page/Screen Event Name Template` in the destination dashboard.', + ); + } + + let eventName = userDefinedEventTemplate; + + if (isDefinedAndNotNull(message.properties?.category)) { + // Replace {{ category }} with actual values + eventName = eventName.replace(/{{\s*category\s*}}/g, message.properties.category); + } else { + // find {{ category }} surrounded by whitespace characters and replace it with a single whitespace character + eventName = eventName.replace(/\s{{\s*category\s*}}\s/g, ' '); + } + + if (isDefinedAndNotNull(message.name)) { + // Replace {{ name }} with actual values + eventName = eventName.replace(/{{\s*name\s*}}/g, message.name); + } else { + // find {{ name }} surrounded by whitespace characters and replace it with a single whitespace character + eventName = eventName.replace(/\s{{\s*name\s*}}\s/g, ' '); + } + + return eventName; +}; + +/** + * Records the batch size metrics for different endpoints. + * + * @param {Object} batchSize - The object containing the batch size for different endpoints. + * @param {number} batchSize.engage - The batch size for engage endpoint. + * @param {number} batchSize.groups - The batch size for group endpoint. + * @param {number} batchSize.import - The batch size for import endpoint. + * @param {string} destinationId - The ID of the destination. + * @returns {void} + */ +const recordBatchSizeMetrics = (batchSize, destinationId) => { + stats.gauge('mixpanel_batch_engage_pack_size', batchSize.engage, { + destination_id: destinationId, + }); + stats.gauge('mixpanel_batch_group_pack_size', batchSize.groups, { + destination_id: destinationId, + }); + stats.gauge('mixpanel_batch_import_pack_size', batchSize.import, { + destination_id: destinationId, + }); +}; + module.exports = { createIdentifyResponse, isImportAuthCredentialsAvailable, @@ -396,6 +370,7 @@ module.exports = { groupEventsByEndpoint, generateBatchedPayloadForArray, batchEvents, - combineBatchRequestsWithSameJobIds, trimTraits, + generatePageOrScreenCustomEventName, + recordBatchSizeMetrics, }; diff --git a/src/v0/destinations/mp/util.test.js b/src/v0/destinations/mp/util.test.js index 530208736a7..3666081f593 100644 --- a/src/v0/destinations/mp/util.test.js +++ b/src/v0/destinations/mp/util.test.js @@ -1,669 +1,491 @@ const { - combineBatchRequestsWithSameJobIds, groupEventsByEndpoint, batchEvents, generateBatchedPayloadForArray, buildUtmParams, trimTraits, + generatePageOrScreenCustomEventName, } = require('./util'); const { FEATURE_GZIP_SUPPORT } = require('../../util/constant'); - -const destinationMock = { - Config: { - token: 'test_api_token', - prefixProperties: true, - useNativeSDK: false, - useOldMapping: true, - }, - DestinationDefinition: { - DisplayName: 'Mixpanel', - ID: 'test_destination_definition_id', - Name: 'MP', - }, - Enabled: true, - ID: 'test_id', - Name: 'Mixpanel', - Transformations: [], -}; +const { ConfigurationError } = require('@rudderstack/integrations-lib'); const maxBatchSizeMock = 2; -describe('Mixpanel utils test', () => { - describe('Unit test cases for groupEventsByEndpoint', () => { - it('should return an object with empty arrays for all properties when the events array is empty', () => { - const events = []; - const result = groupEventsByEndpoint(events); - expect(result).toEqual({ - engageEvents: [], - groupsEvents: [], - importEvents: [], - batchErrorRespList: [], - }); +describe('Unit test cases for groupEventsByEndpoint', () => { + it('should return an object with empty arrays for all properties when the events array is empty', () => { + const events = []; + const result = groupEventsByEndpoint(events); + expect(result).toEqual({ + engageEvents: [], + groupsEvents: [], + importEvents: [], + batchErrorRespList: [], }); + }); - it('should return an object with all properties containing their respective events when the events array contains events of all types', () => { - const events = [ - { - message: { - endpoint: '/engage', - body: { - JSON_ARRAY: { - batch: '[{prop:1}]', - }, + it('should return an object with all properties containing their respective events when the events array contains events of all types', () => { + const events = [ + { + message: { + endpoint: '/engage', + body: { + JSON_ARRAY: { + batch: '[{prop:1}]', }, - userId: 'user1', }, + userId: 'user1', }, - { - message: { - endpoint: '/engage', - body: { - JSON_ARRAY: { - batch: '[{prop:2}]', - }, + }, + { + message: { + endpoint: '/engage', + body: { + JSON_ARRAY: { + batch: '[{prop:2}]', }, - userId: 'user2', }, + userId: 'user2', }, - { - message: { - endpoint: '/groups', - body: { - JSON_ARRAY: { - batch: '[{prop:3}]', - }, + }, + { + message: { + endpoint: '/groups', + body: { + JSON_ARRAY: { + batch: '[{prop:3}]', }, - userId: 'user1', }, + userId: 'user1', }, - { - message: { - endpoint: '/import', - body: { - JSON_ARRAY: { - batch: '[{prop:4}]', - }, + }, + { + message: { + endpoint: '/track', + body: { + JSON_ARRAY: { + batch: '[{prop:4}]', }, - userId: 'user1', }, + userId: 'user1', }, - { - message: { - endpoint: '/import', - body: { - JSON_ARRAY: { - batch: '[{prop:5}]', - }, + }, + { + message: { + endpoint: '/import', + body: { + JSON_ARRAY: { + batch: '[{prop:5}]', }, - userId: 'user2', }, + userId: 'user2', }, - { error: 'Message type abc not supported' }, - ]; - const result = groupEventsByEndpoint(events); - expect(result).toEqual({ - engageEvents: [ - { - message: { - endpoint: '/engage', - body: { - JSON_ARRAY: { - batch: '[{prop:1}]', - }, - }, - userId: 'user1', - }, - }, - { - message: { - endpoint: '/engage', - body: { - JSON_ARRAY: { - batch: '[{prop:2}]', - }, - }, - userId: 'user2', - }, - }, - ], - groupsEvents: [ - { - message: { - endpoint: '/groups', - body: { - JSON_ARRAY: { - batch: '[{prop:3}]', - }, - }, - userId: 'user1', - }, - }, - ], - importEvents: [ - { - message: { - endpoint: '/import', - body: { - JSON_ARRAY: { - batch: '[{prop:4}]', - }, - }, - userId: 'user1', - }, - }, - { - message: { - endpoint: '/import', - body: { - JSON_ARRAY: { - batch: '[{prop:5}]', - }, - }, - userId: 'user2', - }, - }, - ], - batchErrorRespList: [{ error: 'Message type abc not supported' }], - }); - }); - }); - - describe('Unit test cases for batchEvents', () => { - it('should return an array of batched events with correct payload and metadata', () => { - const successRespList = [ + }, + { error: 'Message type abc not supported' }, + ]; + const result = groupEventsByEndpoint(events); + expect(result).toEqual({ + engageEvents: [ { message: { endpoint: '/engage', body: { JSON_ARRAY: { - batch: '[{"prop":1}]', + batch: '[{prop:1}]', }, }, - headers: {}, - params: {}, userId: 'user1', }, - metadata: { jobId: 3 }, }, { message: { endpoint: '/engage', body: { JSON_ARRAY: { - batch: '[{"prop":2}]', + batch: '[{prop:2}]', }, }, - headers: {}, - params: {}, userId: 'user2', }, - metadata: { jobId: 4 }, }, + ], + groupsEvents: [ { message: { - endpoint: '/engage', + endpoint: '/groups', body: { JSON_ARRAY: { - batch: '[{"prop":3}]', + batch: '[{prop:3}]', }, }, - headers: {}, - params: {}, - userId: 'user2', - }, - metadata: { jobId: 6 }, - }, - ]; - - const result = batchEvents(successRespList, maxBatchSizeMock); - - expect(result).toEqual([ - { - batched: true, - batchedRequest: { - body: { FORM: {}, JSON: {}, JSON_ARRAY: { batch: '[{"prop":1},{"prop":2}]' }, XML: {} }, - endpoint: '/engage', - files: {}, - headers: {}, - method: 'POST', - params: {}, - type: 'REST', - version: '1', + userId: 'user1', }, - destination: undefined, - metadata: [{ jobId: 3 }, { jobId: 4 }], - statusCode: 200, }, + ], + importEvents: [ { - batched: true, - batchedRequest: { - body: { FORM: {}, JSON: {}, JSON_ARRAY: { batch: '[{"prop":3}]' }, XML: {} }, - endpoint: '/engage', - files: {}, - headers: {}, - method: 'POST', - params: {}, - type: 'REST', - version: '1', + message: { + endpoint: '/import', + body: { + JSON_ARRAY: { + batch: '[{prop:5}]', + }, + }, + userId: 'user2', }, - destination: undefined, - metadata: [{ jobId: 6 }], - statusCode: 200, }, - ]); - }); - - it('should return an empty array when successRespList is empty', () => { - const successRespList = []; - const result = batchEvents(successRespList, maxBatchSizeMock); - expect(result).toEqual([]); + ], + batchErrorRespList: [{ error: 'Message type abc not supported' }], }); }); +}); - describe('Unit test cases for combineBatchRequestsWithSameJobIds', () => { - it('Combine batch request with same jobIds', async () => { - const input = [ - { - batchedRequest: { - endpoint: 'https://api.mixpanel.com/import/', - }, - metadata: [ - { - jobId: 1, - }, - { - jobId: 4, +describe('Unit test cases for batchEvents', () => { + it('should return an array of batched events with correct payload and metadata', () => { + const successRespList = [ + { + message: { + endpoint: '/engage', + body: { + JSON_ARRAY: { + batch: '[{"prop":1}]', }, - ], - batched: true, - statusCode: 200, - destination: destinationMock, - }, - { - batchedRequest: { - endpoint: 'https://api.mixpanel.com/import/', }, - metadata: [ - { - jobId: 3, - }, - ], - batched: true, - statusCode: 200, - destination: destinationMock, + headers: {}, + params: {}, + userId: 'user1', }, - { - batchedRequest: { - endpoint: 'https://api.mixpanel.com/engage/', - }, - metadata: [ - { - jobId: 1, + metadata: { jobId: 3 }, + }, + { + message: { + endpoint: '/engage', + body: { + JSON_ARRAY: { + batch: '[{"prop":2}]', }, - { - jobId: 3, - }, - ], - batched: true, - statusCode: 200, - destination: destinationMock, - }, - { - batchedRequest: { - endpoint: 'https://api.mixpanel.com/import/', }, - metadata: [ - { - jobId: 6, - }, - ], - batched: true, - statusCode: 200, - destination: destinationMock, - }, - ]; - - const expectedOutput = [ - { - batchedRequest: [ - { - endpoint: 'https://api.mixpanel.com/import/', - }, - { - endpoint: 'https://api.mixpanel.com/engage/', - }, - { - endpoint: 'https://api.mixpanel.com/import/', - }, - ], - metadata: [ - { - jobId: 1, - }, - { - jobId: 4, - }, - { - jobId: 3, - }, - ], - batched: true, - statusCode: 200, - destination: destinationMock, + headers: {}, + params: {}, + userId: 'user2', }, - { - batchedRequest: { - endpoint: 'https://api.mixpanel.com/import/', - }, - metadata: [ - { - jobId: 6, + metadata: { jobId: 4 }, + }, + { + message: { + endpoint: '/engage', + body: { + JSON_ARRAY: { + batch: '[{"prop":3}]', }, - ], - batched: true, - statusCode: 200, - destination: destinationMock, - }, - ]; - expect(combineBatchRequestsWithSameJobIds(input)).toEqual(expectedOutput); - }); - - it('Each batchRequest contains unique jobIds (no event multiplexing)', async () => { - const input = [ - { - batchedRequest: { - endpoint: 'https://api.mixpanel.com/import/', }, - metadata: [ - { - jobId: 1, - }, - { - jobId: 4, - }, - ], - batched: true, - statusCode: 200, - destination: destinationMock, + headers: {}, + params: {}, + userId: 'user2', }, - { - batchedRequest: { - endpoint: 'https://api.mixpanel.com/engage/', - }, - metadata: [ - { - jobId: 2, - }, - ], - batched: true, - statusCode: 200, - destination: destinationMock, + metadata: { jobId: 6 }, + }, + ]; + + const result = batchEvents(successRespList, maxBatchSizeMock); + + expect(result).toEqual([ + { + batched: true, + batchedRequest: { + body: { FORM: {}, JSON: {}, JSON_ARRAY: { batch: '[{"prop":1},{"prop":2}]' }, XML: {} }, + endpoint: '/engage', + files: {}, + headers: {}, + method: 'POST', + params: {}, + type: 'REST', + version: '1', }, - { - batchedRequest: { - endpoint: 'https://api.mixpanel.com/engage/', - }, - metadata: [ - { - jobId: 5, - }, - ], - batched: true, - statusCode: 200, - destination: destinationMock, + destination: undefined, + metadata: [{ jobId: 3 }, { jobId: 4 }], + statusCode: 200, + }, + { + batched: true, + batchedRequest: { + body: { FORM: {}, JSON: {}, JSON_ARRAY: { batch: '[{"prop":3}]' }, XML: {} }, + endpoint: '/engage', + files: {}, + headers: {}, + method: 'POST', + params: {}, + type: 'REST', + version: '1', }, - ]; - - const expectedOutput = [ - { - batchedRequest: { - endpoint: 'https://api.mixpanel.com/import/', - }, + destination: undefined, + metadata: [{ jobId: 6 }], + statusCode: 200, + }, + ]); + }); - metadata: [ - { - jobId: 1, - }, - { - jobId: 4, - }, - ], - batched: true, - statusCode: 200, - destination: destinationMock, - }, - { - batchedRequest: { - endpoint: 'https://api.mixpanel.com/engage/', - }, - metadata: [ - { - jobId: 2, - }, - ], - batched: true, - statusCode: 200, - destination: destinationMock, - }, - { - batchedRequest: { - endpoint: 'https://api.mixpanel.com/engage/', - }, - metadata: [ - { - jobId: 5, - }, - ], - batched: true, - statusCode: 200, - destination: destinationMock, - }, - ]; - expect(combineBatchRequestsWithSameJobIds(input)).toEqual(expectedOutput); - }); + it('should return an empty array when successRespList is empty', () => { + const successRespList = []; + const result = batchEvents(successRespList, maxBatchSizeMock); + expect(result).toEqual([]); }); +}); - describe('Unit test cases for generateBatchedPayloadForArray', () => { - it('should generate a batched payload with GZIP payload for /import endpoint when given an array of events', () => { - const events = [ - { - body: { JSON_ARRAY: { batch: '[{"event": "event1"}]' } }, - endpoint: '/import', - headers: { 'Content-Type': 'application/json' }, - params: {}, - }, - { - body: { JSON_ARRAY: { batch: '[{"event": "event2"}]' } }, - endpoint: '/import', - headers: { 'Content-Type': 'application/json' }, - params: {}, - }, - ]; - const expectedBatchedRequest = { - body: { - FORM: {}, - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - GZIP: { - payload: '[{"event":"event1"},{"event":"event2"}]', - }, - }, +describe('Unit test cases for generateBatchedPayloadForArray', () => { + it('should generate a batched payload with GZIP payload for /import endpoint when given an array of events', () => { + const events = [ + { + body: { JSON_ARRAY: { batch: '[{"event": "event1"}]' } }, endpoint: '/import', - files: {}, headers: { 'Content-Type': 'application/json' }, - method: 'POST', params: {}, - type: 'REST', - version: '1', - }; - - const result = generateBatchedPayloadForArray(events, { - features: { [FEATURE_GZIP_SUPPORT]: true }, - }); - - expect(result).toEqual(expectedBatchedRequest); + }, + { + body: { JSON_ARRAY: { batch: '[{"event": "event2"}]' } }, + endpoint: '/import', + headers: { 'Content-Type': 'application/json' }, + params: {}, + }, + ]; + const expectedBatchedRequest = { + body: { + FORM: {}, + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + GZIP: { + payload: '[{"event":"event1"},{"event":"event2"}]', + }, + }, + endpoint: '/import', + files: {}, + headers: { 'Content-Type': 'application/json' }, + method: 'POST', + params: {}, + type: 'REST', + version: '1', + }; + + const result = generateBatchedPayloadForArray(events, { + features: { [FEATURE_GZIP_SUPPORT]: true }, }); - it('should generate a batched payload with JSON_ARRAY body when given an array of events', () => { - const events = [ - { - body: { JSON_ARRAY: { batch: '[{"event": "event1"}]' } }, - endpoint: '/endpoint', - headers: { 'Content-Type': 'application/json' }, - params: {}, - }, - { - body: { JSON_ARRAY: { batch: '[{"event": "event2"}]' } }, - endpoint: '/endpoint', - headers: { 'Content-Type': 'application/json' }, - params: {}, - }, - ]; - const expectedBatchedRequest = { - body: { - FORM: {}, - JSON: {}, - JSON_ARRAY: { batch: '[{"event":"event1"},{"event":"event2"}]' }, - XML: {}, - }, + expect(result).toEqual(expectedBatchedRequest); + }); + + it('should generate a batched payload with JSON_ARRAY body when given an array of events', () => { + const events = [ + { + body: { JSON_ARRAY: { batch: '[{"event": "event1"}]' } }, endpoint: '/endpoint', - files: {}, headers: { 'Content-Type': 'application/json' }, - method: 'POST', params: {}, - type: 'REST', - version: '1', - }; - - const result = generateBatchedPayloadForArray(events, { - features: { [FEATURE_GZIP_SUPPORT]: true }, - }); - - expect(result).toEqual(expectedBatchedRequest); + }, + { + body: { JSON_ARRAY: { batch: '[{"event": "event2"}]' } }, + endpoint: '/endpoint', + headers: { 'Content-Type': 'application/json' }, + params: {}, + }, + ]; + const expectedBatchedRequest = { + body: { + FORM: {}, + JSON: {}, + JSON_ARRAY: { batch: '[{"event":"event1"},{"event":"event2"}]' }, + XML: {}, + }, + endpoint: '/endpoint', + files: {}, + headers: { 'Content-Type': 'application/json' }, + method: 'POST', + params: {}, + type: 'REST', + version: '1', + }; + + const result = generateBatchedPayloadForArray(events, { + features: { [FEATURE_GZIP_SUPPORT]: true }, }); + + expect(result).toEqual(expectedBatchedRequest); }); +}); - describe('Unit test cases for buildUtmParams', () => { - it('should return an empty object when campaign is undefined', () => { - const campaign = undefined; - const result = buildUtmParams(campaign); - expect(result).toEqual({}); - }); +describe('Unit test cases for buildUtmParams', () => { + it('should return an empty object when campaign is undefined', () => { + const campaign = undefined; + const result = buildUtmParams(campaign); + expect(result).toEqual({}); + }); - it('should return an empty object when campaign is an empty object', () => { - const campaign = {}; - const result = buildUtmParams(campaign); - expect(result).toEqual({}); - }); + it('should return an empty object when campaign is an empty object', () => { + const campaign = {}; + const result = buildUtmParams(campaign); + expect(result).toEqual({}); + }); - it('should return an empty object when campaign is not an object', () => { - const campaign = [{ name: 'test' }]; - const result = buildUtmParams(campaign); - expect(result).toEqual({}); - }); + it('should return an empty object when campaign is not an object', () => { + const campaign = [{ name: 'test' }]; + const result = buildUtmParams(campaign); + expect(result).toEqual({}); + }); - it('should handle campaign object with null/undefined values', () => { - const campaign = { name: null, source: 'rudder', medium: 'rudder', test: undefined }; - const result = buildUtmParams(campaign); - expect(result).toEqual({ - utm_campaign: null, - utm_source: 'rudder', - utm_medium: 'rudder', - test: undefined, - }); + it('should handle campaign object with null/undefined values', () => { + const campaign = { name: null, source: 'rudder', medium: 'rudder', test: undefined }; + const result = buildUtmParams(campaign); + expect(result).toEqual({ + utm_campaign: null, + utm_source: 'rudder', + utm_medium: 'rudder', + test: undefined, }); }); - describe('Unit test cases for trimTraits', () => { - // Given a valid traits object and contextTraits object, and a valid setOnceProperties array, the function should return an object containing traits, contextTraits, and setOnce properties. - it('should return an object containing traits, contextTraits, and setOnce properties when given valid inputs', () => { - const traits = { name: 'John', age: 30 }; - const contextTraits = { email: 'john@example.com' }; - const setOnceProperties = ['name', 'email']; - - const result = trimTraits(traits, contextTraits, setOnceProperties); - - expect(result).toEqual({ - traits: { - age: 30, - }, - contextTraits: {}, - setOnce: { $name: 'John', $email: 'john@example.com' }, - }); +}); +describe('Unit test cases for trimTraits', () => { + // Given a valid traits object and contextTraits object, and a valid setOnceProperties array, the function should return an object containing traits, contextTraits, and setOnce properties. + it('should return an object containing traits, contextTraits, and setOnce properties when given valid inputs', () => { + const traits = { name: 'John', age: 30 }; + const contextTraits = { email: 'john@example.com' }; + const setOnceProperties = ['name', 'email']; + + const result = trimTraits(traits, contextTraits, setOnceProperties); + + expect(result).toEqual({ + traits: { + age: 30, + }, + contextTraits: {}, + setOnce: { $name: 'John', $email: 'john@example.com' }, }); + }); - // Given an empty traits object and contextTraits object, and a valid setOnceProperties array, the function should return an object containing empty traits and contextTraits, and an empty setOnce property. - it('should return an object containing empty traits and contextTraits, and an empty setOnce property when given empty traits and contextTraits objects', () => { - const traits = {}; - const contextTraits = {}; - const setOnceProperties = ['name', 'email']; + // Given an empty traits object and contextTraits object, and a valid setOnceProperties array, the function should return an object containing empty traits and contextTraits, and an empty setOnce property. + it('should return an object containing empty traits and contextTraits, and an empty setOnce property when given empty traits and contextTraits objects', () => { + const traits = {}; + const contextTraits = {}; + const setOnceProperties = ['name', 'email']; - const result = trimTraits(traits, contextTraits, setOnceProperties); + const result = trimTraits(traits, contextTraits, setOnceProperties); - expect(result).toEqual({ - traits: {}, - contextTraits: {}, - setOnce: {}, - }); + expect(result).toEqual({ + traits: {}, + contextTraits: {}, + setOnce: {}, }); + }); - // Given an empty setOnceProperties array, the function should return an object containing the original traits and contextTraits objects, and an empty setOnce property. - it('should return an object containing the original traits and contextTraits objects, and an empty setOnce property when given an empty setOnceProperties array', () => { - const traits = { name: 'John', age: 30 }; - const contextTraits = { email: 'john@example.com' }; - const setOnceProperties = []; + // Given an empty setOnceProperties array, the function should return an object containing the original traits and contextTraits objects, and an empty setOnce property. + it('should return an object containing the original traits and contextTraits objects, and an empty setOnce property when given an empty setOnceProperties array', () => { + const traits = { name: 'John', age: 30 }; + const contextTraits = { email: 'john@example.com' }; + const setOnceProperties = []; - const result = trimTraits(traits, contextTraits, setOnceProperties); + const result = trimTraits(traits, contextTraits, setOnceProperties); - expect(result).toEqual({ - traits: { name: 'John', age: 30 }, - contextTraits: { email: 'john@example.com' }, - setOnce: {}, - }); + expect(result).toEqual({ + traits: { name: 'John', age: 30 }, + contextTraits: { email: 'john@example.com' }, + setOnce: {}, }); + }); - // Given a setOnceProperties array containing properties that do not exist in either traits or contextTraits objects, the function should not add the property to the setOnce property. - it('should not add properties to the setOnce property when given setOnceProperties array with non-existent properties', () => { - const traits = { name: 'John', age: 30 }; - const contextTraits = { email: 'john@example.com' }; - const setOnceProperties = ['name', 'email', 'address']; + // Given a setOnceProperties array containing properties that do not exist in either traits or contextTraits objects, the function should not add the property to the setOnce property. + it('should not add properties to the setOnce property when given setOnceProperties array with non-existent properties', () => { + const traits = { name: 'John', age: 30 }; + const contextTraits = { email: 'john@example.com' }; + const setOnceProperties = ['name', 'email', 'address']; - const result = trimTraits(traits, contextTraits, setOnceProperties); + const result = trimTraits(traits, contextTraits, setOnceProperties); - expect(result).toEqual({ - traits: { age: 30 }, - contextTraits: {}, - setOnce: { $name: 'John', $email: 'john@example.com' }, - }); + expect(result).toEqual({ + traits: { age: 30 }, + contextTraits: {}, + setOnce: { $name: 'John', $email: 'john@example.com' }, }); + }); - // Given a setOnceProperties array containing properties with nested paths that do not exist in either traits or contextTraits objects, the function should not add the property to the setOnce property. - it('should not add properties to the setOnce property when given setOnceProperties array with non-existent nested properties', () => { - const traits = { name: 'John', age: 30, address: 'kolkata' }; - const contextTraits = { email: 'john@example.com' }; - const setOnceProperties = ['name', 'email', 'address.city']; + // Given a setOnceProperties array containing properties with nested paths that do not exist in either traits or contextTraits objects, the function should not add the property to the setOnce property. + it('should not add properties to the setOnce property when given setOnceProperties array with non-existent nested properties', () => { + const traits = { name: 'John', age: 30, address: 'kolkata' }; + const contextTraits = { email: 'john@example.com' }; + const setOnceProperties = ['name', 'email', 'address.city']; - const result = trimTraits(traits, contextTraits, setOnceProperties); + const result = trimTraits(traits, contextTraits, setOnceProperties); - expect(result).toEqual({ - traits: { age: 30, address: 'kolkata' }, - contextTraits: {}, - setOnce: { $name: 'John', $email: 'john@example.com' }, - }); + expect(result).toEqual({ + traits: { age: 30, address: 'kolkata' }, + contextTraits: {}, + setOnce: { $name: 'John', $email: 'john@example.com' }, }); + }); - it('should add properties to the setOnce property when given setOnceProperties array with existent nested properties', () => { - const traits = { name: 'John', age: 30, address: { city: 'kolkata' }, isAdult: false }; - const contextTraits = { email: 'john@example.com' }; - const setOnceProperties = ['name', 'email', 'address.city']; + it('should add properties to the setOnce property when given setOnceProperties array with existent nested properties', () => { + const traits = { name: 'John', age: 30, address: { city: 'kolkata' }, isAdult: false }; + const contextTraits = { email: 'john@example.com' }; + const setOnceProperties = ['name', 'email', 'address.city']; - const result = trimTraits(traits, contextTraits, setOnceProperties); + const result = trimTraits(traits, contextTraits, setOnceProperties); - expect(result).toEqual({ - traits: { age: 30, address: {}, isAdult: false }, - contextTraits: {}, - setOnce: { $name: 'John', $email: 'john@example.com', $city: 'kolkata' }, - }); + expect(result).toEqual({ + traits: { age: 30, address: {}, isAdult: false }, + contextTraits: {}, + setOnce: { $name: 'John', $email: 'john@example.com', $city: 'kolkata' }, }); }); }); + +describe('generatePageOrScreenCustomEventName', () => { + it('should throw a ConfigurationError when userDefinedEventTemplate is not provided', () => { + const message = { name: 'Home' }; + const userDefinedEventTemplate = undefined; + expect(() => { + generatePageOrScreenCustomEventName(message, userDefinedEventTemplate); + }).toThrow(ConfigurationError); + }); + + it('should generate a custom event name when userDefinedEventTemplate contains event template and message object is provided', () => { + let message = { name: 'Doc', properties: { category: 'Integration' } }; + const userDefinedEventTemplate = 'Viewed {{ category }} {{ name }} page'; + let expected = 'Viewed Integration Doc page'; + let result = generatePageOrScreenCustomEventName(message, userDefinedEventTemplate); + expect(result).toBe(expected); + + message = { name: true, properties: { category: 0 } }; + expected = 'Viewed 0 true page'; + result = generatePageOrScreenCustomEventName(message, userDefinedEventTemplate); + expect(result).toBe(expected); + }); + + it('should generate a custom event name when userDefinedEventTemplate contains event template and category or name is missing in message object', () => { + const message = { name: 'Doc', properties: { category: undefined } }; + const userDefinedEventTemplate = 'Viewed {{ category }} {{ name }} page someKeyword'; + const expected = 'Viewed Doc page someKeyword'; + const result = generatePageOrScreenCustomEventName(message, userDefinedEventTemplate); + expect(result).toBe(expected); + }); + + it('should generate a custom event name when userDefinedEventTemplate contains only category or name placeholder and message object is provided', () => { + const message = { name: 'Doc', properties: { category: 'Integration' } }; + const userDefinedEventTemplate = 'Viewed {{ name }} page'; + const expected = 'Viewed Doc page'; + const result = generatePageOrScreenCustomEventName(message, userDefinedEventTemplate); + expect(result).toBe(expected); + }); + + it('should return the userDefinedEventTemplate when it does not contain placeholder {{}}', () => { + const message = { name: 'Index' }; + const userDefinedEventTemplate = 'Viewed a Home page'; + const expected = 'Viewed a Home page'; + const result = generatePageOrScreenCustomEventName(message, userDefinedEventTemplate); + expect(result).toBe(expected); + }); + + it('should return a event name when message object is not provided/empty', () => { + const message = {}; + const userDefinedEventTemplate = 'Viewed {{ category }} {{ name }} page someKeyword'; + const expected = 'Viewed page someKeyword'; + const result = generatePageOrScreenCustomEventName(message, userDefinedEventTemplate); + expect(result).toBe(expected); + }); +}); diff --git a/src/v0/destinations/ometria/transform.js b/src/v0/destinations/ometria/transform.js index 55038e10b83..5eff77bd15d 100644 --- a/src/v0/destinations/ometria/transform.js +++ b/src/v0/destinations/ometria/transform.js @@ -14,7 +14,6 @@ const { getFieldValueFromMessage, getIntegrationsObj, getSuccessRespEvents, - checkInvalidRtTfEvents, handleRtTfSingleEventError, } = require('../../util/index'); const { @@ -250,10 +249,6 @@ const process = (event) => { }; const processRouterDest = async (inputs, reqMetadata) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } const inputChunks = returnArrayOfSubarrays(inputs, MAX_BATCH_SIZE); const successList = []; const errorList = []; diff --git a/src/v0/destinations/one_signal/transform.js b/src/v0/destinations/one_signal/transform.js index a072aef0e4f..b025660fa42 100644 --- a/src/v0/destinations/one_signal/transform.js +++ b/src/v0/destinations/one_signal/transform.js @@ -122,7 +122,7 @@ const trackResponseBuilder = (message, { Config }) => { if (!externalUserId) { throw new InstrumentationError('userId is required for track events/updating a device'); } - endpoint = `${endpoint}/${appId}/users/${externalUserId}`; + endpoint = `${endpoint}/${appId}/users/${encodeURIComponent(externalUserId)}`; const payload = {}; const tags = {}; /* Populating event as true in tags. @@ -163,7 +163,7 @@ const groupResponseBuilder = (message, { Config }) => { if (!externalUserId) { throw new InstrumentationError('userId is required for group events'); } - endpoint = `${endpoint}/${appId}/users/${externalUserId}`; + endpoint = `${endpoint}/${appId}/users/${encodeURIComponent(externalUserId)}`; const payload = {}; const tags = { groupId, diff --git a/src/v0/destinations/pardot/networkHandler.js b/src/v0/destinations/pardot/networkHandler.js index 12b4abbc530..60d2f7ee23d 100644 --- a/src/v0/destinations/pardot/networkHandler.js +++ b/src/v0/destinations/pardot/networkHandler.js @@ -46,6 +46,19 @@ const getStatus = (code) => { const pardotRespHandler = (destResponse, stageMsg) => { const { status, response } = destResponse; const respAttributes = response['@attributes']; + + // to handle errors like service unavilable, wrong url, no response + if (!respAttributes) { + throw new NetworkError( + `${JSON.stringify(response)} ${stageMsg}`, + status, + { + [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + }, + response, + ); + } + const { stat, err_code: errorCode } = respAttributes; if (isHttpStatusSuccess(status) && stat !== 'fail') { @@ -65,7 +78,8 @@ const pardotRespHandler = (destResponse, stageMsg) => { ); }; -const responseHandler = (destinationResponse) => { +const responseHandler = (responseParams) => { + const { destinationResponse } = responseParams; const message = 'Request Processed Successfully'; const { status } = destinationResponse; // else successfully return status, message and original destination response diff --git a/src/v0/destinations/pardot/transform.js b/src/v0/destinations/pardot/transform.js index b32b8967bd2..3dbe57ecc74 100644 --- a/src/v0/destinations/pardot/transform.js +++ b/src/v0/destinations/pardot/transform.js @@ -44,7 +44,6 @@ const { getFieldValueFromMessage, removeUndefinedValues, getSuccessRespEvents, - checkInvalidRtTfEvents, handleRtTfSingleEventError, getAccessToken, } = require('../../util'); @@ -150,11 +149,6 @@ const processEvent = (metadata, message, destination) => { const process = (event) => processEvent(event.metadata, event.message, event.destination); const processRouterDest = (events, reqMetadata) => { - const errorRespEvents = checkInvalidRtTfEvents(events); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } - const responseList = events.map((event) => { try { return getSuccessRespEvents(process(event), [event.metadata], event.destination); diff --git a/src/v0/destinations/pinterest_tag/transform.js b/src/v0/destinations/pinterest_tag/transform.js index ee7e2e5b192..f8ccfd48eab 100644 --- a/src/v0/destinations/pinterest_tag/transform.js +++ b/src/v0/destinations/pinterest_tag/transform.js @@ -5,7 +5,6 @@ const { defaultRequestConfig, defaultPostRequestConfig, getSuccessRespEvents, - getErrorRespEvents, constructPayload, defaultBatchRequestConfig, removeUndefinedAndNullValues, @@ -172,11 +171,6 @@ const batchEvents = (successRespList) => { }; const processRouterDest = (inputs, reqMetadata) => { - if (!Array.isArray(inputs) || inputs.length <= 0) { - const respEvents = getErrorRespEvents(null, 400, 'Invalid event array'); - return [respEvents]; - } - const successRespList = []; const batchErrorRespList = []; inputs.forEach((input) => { diff --git a/src/v0/destinations/profitwell/utils.js b/src/v0/destinations/profitwell/utils.js index acc4db20353..1b235617217 100644 --- a/src/v0/destinations/profitwell/utils.js +++ b/src/v0/destinations/profitwell/utils.js @@ -188,6 +188,9 @@ const getSubscriptionHistory = async (endpoint, options) => { const res = await httpGET(endpoint, requestOptions, { destType: 'profitwell', feature: 'transformation', + endpointPath: '/users/userId', + requestMethod: 'GET', + module: 'router', }); return res; }; diff --git a/src/v0/destinations/rakuten/networkHandler.js b/src/v0/destinations/rakuten/networkHandler.js new file mode 100644 index 00000000000..4c97a23e518 --- /dev/null +++ b/src/v0/destinations/rakuten/networkHandler.js @@ -0,0 +1,110 @@ +const { NetworkError } = require('@rudderstack/integrations-lib'); +const { httpSend } = require('../../../adapters/network'); +const { + processAxiosResponse, + getDynamicErrorType, +} = require('../../../adapters/utils/networkUtils'); +const { TAG_NAMES } = require('../../util/tags'); +const { HTTP_STATUS_CODES } = require('../../util/constant'); + +const DESTINATION = 'RAKUTEN'; +const prepareProxyRequest = (request) => request; +const proxyRequest = async (request, destType) => { + const { endpoint, data, method, params, headers } = prepareProxyRequest(request); + const requestOptions = { + url: endpoint, + data, + params, + headers, + method, + }; + const response = await httpSend(requestOptions, { + feature: 'proxy', + destType, + endpointPath: '/ep', + requestMethod: 'GET', + module: 'dataDelivery', + }); + return response; +}; +const extractContent = (xmlPayload, tagName) => { + const pattern = new RegExp(`<${tagName}>(.*?)`); + const match = xmlPayload.match(pattern); + return match ? match[1] : null; +}; + +const responseHandler = (responseParams) => { + const { destinationResponse } = responseParams; + const msg = `[${DESTINATION} Response Handler] - Request Processed Successfully`; + const { response, status } = destinationResponse; + if (status === 400) { + throw new NetworkError( + `Request failed with status: ${status} due to invalid Marketing Id`, + 400, + { + [TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + }, + destinationResponse, + ); + } + // Extract errors, good and bad between different tags + const badRecords = extractContent(response, 'bad'); + const errors = extractContent(response, 'error'); + + // For access denied for a mid rakuten sends status code 200 with response as Access denied + if (errors) { + throw new NetworkError( + `Request failed with status: ${status} due to ${errors}. Can you try to enable pixel tracking for this mid.`, + 400, + { + // status would be 200 but since no error type for this status code hence it will take it as aborted + [TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + }, + destinationResponse, + ); + } + if (parseInt(badRecords, 10)) { + throw new NetworkError( + `Request failed with status: ${status} with number of bad records ${badRecords}`, + 400, + { + // status would be 200 but since no error type for this status code hence it will take it as aborted + [TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + }, + destinationResponse, + ); + } + /* just puttting it here for 429 and 500's we dont have documentation for these two + neither we have any sample response but just in case if we recoeve non 2xx status + */ + if (status !== 200) { + throw new NetworkError( + `Request failed with status: ${status}`, + status, + { + [TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + }, + destinationResponse, + ); + } + // if no error or bad record is found and status is 200 the request is successfull + return { + status: HTTP_STATUS_CODES.OK, + message: msg, + destinationResponse, + }; +}; +// eslint-disable-next-line @typescript-eslint/naming-convention +class networkHandler { + constructor() { + this.responseHandler = responseHandler; + this.proxy = proxyRequest; + this.prepareProxy = prepareProxyRequest; + this.processAxiosResponse = processAxiosResponse; + } +} + +module.exports = { + networkHandler, + responseHandler, +}; diff --git a/src/v0/destinations/rakuten/networkHandler.test.js b/src/v0/destinations/rakuten/networkHandler.test.js new file mode 100644 index 00000000000..da74e05cb31 --- /dev/null +++ b/src/v0/destinations/rakuten/networkHandler.test.js @@ -0,0 +1,63 @@ +const { responseHandler } = require('./networkHandler'); +// Generated by CodiumAI + +describe('responseHandler', () => { + it('should return a success message with status code 200 when the request is successful and no bad records or errors are found', () => { + const destinationResponse = { + response: '', + status: 200, + }; + + const result = responseHandler({ destinationResponse }); + + expect(result.status).toBe(200); + expect(result.message).toBe('[RAKUTEN Response Handler] - Request Processed Successfully'); + expect(result.destinationResponse).toEqual(destinationResponse); + }); + + it('should throw a NetworkError with status code 400 and error message when the response status is 400 due to invalid Marketing Id', () => { + const destinationResponse = { + response: 'Invalid marketing id', + status: 400, + }; + expect(() => { + responseHandler({ destinationResponse }); + }).toThrow('Request failed with status: 400 due to invalid Marketing Id'); + }); + + it('should throw a NetworkError with status code 400 and error message when the response contains errors', () => { + const destinationResponse = { + response: 'Access denied', + status: 200, + }; + expect(() => { + responseHandler({ destinationResponse }); + }).toThrow( + 'Request failed with status: 200 due to Access denied. Can you try to enable pixel tracking for this mid.', + ); + }); + + it('should return a success message with status code 200 when the response status is 200 and no bad records or errors are found', () => { + const destinationResponse = { + response: '', + status: 200, + }; + + const result = responseHandler({ destinationResponse }); + + expect(result.status).toBe(200); + expect(result.message).toBe('[RAKUTEN Response Handler] - Request Processed Successfully'); + expect(result.destinationResponse).toEqual(destinationResponse); + }); + + it('should throw a NetworkError with status code 400 and error message when the response status is 200 and the response contains only bad records', () => { + const destinationResponse = { + response: '1', + status: 200, + }; + + expect(() => { + responseHandler({ destinationResponse }); + }).toThrow('Request failed with status: 200 with number of bad records 1'); + }); +}); diff --git a/src/v0/destinations/reddit/networkHandler.js b/src/v0/destinations/reddit/networkHandler.js index 836c0158592..55087b52ac4 100644 --- a/src/v0/destinations/reddit/networkHandler.js +++ b/src/v0/destinations/reddit/networkHandler.js @@ -18,7 +18,8 @@ const redditRespHandler = (destResponse) => { ); } }; -const responseHandler = (destinationResponse) => { +const responseHandler = (responseParams) => { + const { destinationResponse } = responseParams; const message = `Request Processed Successfully`; const { status } = destinationResponse; if (!isHttpStatusSuccess(status)) { diff --git a/src/v0/destinations/salesforce/networkHandler.js b/src/v0/destinations/salesforce/networkHandler.js index 918084cc899..ac312417756 100644 --- a/src/v0/destinations/salesforce/networkHandler.js +++ b/src/v0/destinations/salesforce/networkHandler.js @@ -3,13 +3,14 @@ const { processAxiosResponse } = require('../../../adapters/utils/networkUtils') const { LEGACY } = require('./config'); const { salesforceResponseHandler } = require('./utils'); -const responseHandler = (destinationResponse, destType) => { +const responseHandler = (responseParams) => { + const { destinationResponse, destType, rudderJobMetadata } = responseParams; const message = `Request for destination: ${destType} Processed Successfully`; salesforceResponseHandler( destinationResponse, 'during Salesforce Response Handling', - destinationResponse?.rudderJobMetadata?.destInfo?.authKey, + rudderJobMetadata?.destInfo?.authKey, LEGACY, ); diff --git a/src/v0/destinations/salesforce/transform.js b/src/v0/destinations/salesforce/transform.js index 5ada9dfaa07..b8f032c5bfe 100644 --- a/src/v0/destinations/salesforce/transform.js +++ b/src/v0/destinations/salesforce/transform.js @@ -3,6 +3,7 @@ const cloneDeep = require('lodash/cloneDeep'); const { InstrumentationError, NetworkInstrumentationError, + getErrorRespEvents, } = require('@rudderstack/integrations-lib'); const { EventType, MappedToDestinationKey } = require('../../../constants'); const { @@ -20,10 +21,8 @@ const { constructPayload, getFirstAndLastName, getSuccessRespEvents, - getErrorRespEvents, addExternalIdToTraits, getDestinationExternalIDObjectForRetl, - checkInvalidRtTfEvents, handleRtTfSingleEventError, generateErrorObject, isHttpStatusSuccess, @@ -120,6 +119,9 @@ async function getSaleforceIdForRecord( { destType: 'salesforce', feature: 'transformation', + endpointPath: '/parameterizedSearch', + requestMethod: 'GET', + module: 'router', }, ); if (!isHttpStatusSuccess(processedsfSearchResponse.status)) { @@ -233,6 +235,9 @@ async function getSalesforceIdFromPayload( { destType: 'salesforce', feature: 'transformation', + endpointPath: '/parameterizedSearch', + requestMethod: 'GET', + module: 'router', }, ); @@ -348,10 +353,6 @@ async function process(event) { } const processRouterDest = async (inputs, reqMetadata) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } let authInfo; try { authInfo = await collectAuthorizationInfo(inputs[0]); diff --git a/src/v0/destinations/salesforce/utils.js b/src/v0/destinations/salesforce/utils.js index 96735ecc174..85061ce2b2a 100644 --- a/src/v0/destinations/salesforce/utils.js +++ b/src/v0/destinations/salesforce/utils.js @@ -133,6 +133,9 @@ const getAccessToken = async (destination) => { { destType: 'salesforce', feature: 'transformation', + endpointPath: '/services/oauth2/token', + requestMethod: 'POST', + module: 'router', }, ); // If the request fails, throwing error. diff --git a/src/v0/destinations/salesforce_oauth/networkHandler.js b/src/v0/destinations/salesforce_oauth/networkHandler.js index 2bcace31c9a..b6cbed77f95 100644 --- a/src/v0/destinations/salesforce_oauth/networkHandler.js +++ b/src/v0/destinations/salesforce_oauth/networkHandler.js @@ -3,13 +3,14 @@ const { processAxiosResponse } = require('../../../adapters/utils/networkUtils') const { OAUTH } = require('../salesforce/config'); const { salesforceResponseHandler } = require('../salesforce/utils'); -const responseHandler = (destinationResponse, destType) => { +const responseHandler = (responseParams) => { + const { destinationResponse, destType, rudderJobMetadata } = responseParams; const message = `Request for destination: ${destType} Processed Successfully`; salesforceResponseHandler( destinationResponse, 'during Salesforce Response Handling', - destinationResponse?.rudderJobMetadata?.destInfo?.authKey, + rudderJobMetadata?.destInfo?.authKey, OAUTH, ); diff --git a/src/v0/destinations/sendgrid/deleteUsers.js b/src/v0/destinations/sendgrid/deleteUsers.js index 8410f41296f..ccd277d90d6 100644 --- a/src/v0/destinations/sendgrid/deleteUsers.js +++ b/src/v0/destinations/sendgrid/deleteUsers.js @@ -85,6 +85,9 @@ const userDeletionHandler = async (userAttributes, config) => { const deletionResponse = await httpDELETE(endpoint, requestOptions, { destType: 'sendgrid', feature: 'deleteUsers', + endpointPath: '/marketing/contacts', + requestMethod: 'DELETE', + module: 'deletion', }); const handledDelResponse = processAxiosResponse(deletionResponse); @@ -94,6 +97,7 @@ const userDeletionHandler = async (userAttributes, config) => { handledDelResponse.status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(handledDelResponse.status), + [tags.TAG_NAMES.STATUS]: handledDelResponse.status, }, handledDelResponse, ); diff --git a/src/v0/destinations/sendgrid/transform.js b/src/v0/destinations/sendgrid/transform.js index 5038fedf7b7..c32e34c4890 100644 --- a/src/v0/destinations/sendgrid/transform.js +++ b/src/v0/destinations/sendgrid/transform.js @@ -9,7 +9,6 @@ const { ErrorMessage, isEmptyObject, constructPayload, - getErrorRespEvents, extractCustomFields, getValueFromMessage, defaultRequestConfig, @@ -236,10 +235,6 @@ const batchEvents = (successRespList) => { }; const processRouterDest = async (inputs, reqMetadata) => { - if (!Array.isArray(inputs) || inputs.length <= 0) { - const respEvents = getErrorRespEvents(null, 400, 'Invalid event array'); - return [respEvents]; - } let batchResponseList = []; const batchErrorRespList = []; const successRespList = []; diff --git a/src/v0/destinations/sendgrid/util.js b/src/v0/destinations/sendgrid/util.js index 1df34bfe69d..7105c5cda5f 100644 --- a/src/v0/destinations/sendgrid/util.js +++ b/src/v0/destinations/sendgrid/util.js @@ -445,6 +445,9 @@ const fetchCustomFields = async (destination) => { const resonse = await httpGET(endpoint, requestOptions, { destType: 'sendgrid', feature: 'transformation', + endpointPath: '/marketing/field_definitions', + requestMethod: 'GET', + module: 'router', }); const processedResponse = processAxiosResponse(resonse); if (isHttpStatusSuccess(processedResponse.status)) { diff --git a/src/v0/destinations/sendinblue/util.js b/src/v0/destinations/sendinblue/util.js index 9ad37fc9b79..9fded8e493b 100644 --- a/src/v0/destinations/sendinblue/util.js +++ b/src/v0/destinations/sendinblue/util.js @@ -60,6 +60,9 @@ const checkIfContactExists = async (identifier, apiKey) => { const contactDetailsResponse = await httpGET(endpoint, requestOptions, { destType: 'sendinblue', feature: 'transformation', + endpointPath: '/contacts', + requestMethod: 'GET', + module: 'router', }); const processedContactDetailsResponse = processAxiosResponse(contactDetailsResponse); diff --git a/src/v0/destinations/sfmc/config.js b/src/v0/destinations/sfmc/config.js index f856c44d6b3..1b1f5c323ba 100644 --- a/src/v0/destinations/sfmc/config.js +++ b/src/v0/destinations/sfmc/config.js @@ -4,6 +4,7 @@ const ENDPOINTS = { GET_TOKEN: `auth.marketingcloudapis.com/v2/token`, CONTACTS: `rest.marketingcloudapis.com/contacts/v1/contacts`, INSERT_CONTACTS: `rest.marketingcloudapis.com/hub/v1/dataevents/key:`, + EVENT: 'rest.marketingcloudapis.com/interaction/v1/events', }; const CONFIG_CATEGORIES = { diff --git a/src/v0/destinations/sfmc/transform.js b/src/v0/destinations/sfmc/transform.js index 7623d751f1a..53925bc7ed5 100644 --- a/src/v0/destinations/sfmc/transform.js +++ b/src/v0/destinations/sfmc/transform.js @@ -1,3 +1,4 @@ +/* eslint-disable no-param-reassign */ /* eslint-disable no-nested-ternary */ const { NetworkError, @@ -44,7 +45,13 @@ const getToken = async (clientId, clientSecret, subdomain) => { { 'Content-Type': JSON_MIME_TYPE, }, - { destType: 'sfmc', feature: 'transformation' }, + { + destType: 'sfmc', + feature: 'transformation', + endpointPath: '/token', + requestMethod: 'POST', + module: 'router', + }, ); if (resp && resp.data) { return resp.data.access_token; @@ -182,6 +189,26 @@ const responseBuilderForInsertData = ( return response; }; +// DOC : https://developer.salesforce.com/docs/marketing/marketing-cloud/references/mc_rest_interaction/postEvent.html + +const responseBuilderForMessageEvent = (message, subDomain, authToken, hashMapEventDefinition) => { + const contactKey = message.properties.contactId; + delete message.properties.contactId; + const response = defaultRequestConfig(); + response.method = defaultPostRequestConfig.requestMethod; + response.endpoint = `https://${subDomain}.${ENDPOINTS.EVENT}`; + response.headers = { + 'Content-Type': JSON_MIME_TYPE, + Authorization: `Bearer ${authToken}`, + }; + response.body.JSON = { + ContactKey: contactKey, + EventDefinitionKey: hashMapEventDefinition[message.event.toLowerCase()], + Data: { ...message.properties }, + }; + return response; +}; + const responseBuilderSimple = async (message, category, destination) => { const { clientId, @@ -192,6 +219,7 @@ const responseBuilderSimple = async (message, category, destination) => { eventToExternalKey, eventToPrimaryKey, eventToUUID, + eventToDefinitionMapping, } = destination.Config; // map from an event name to an external key of a data extension. const hashMapExternalKey = getHashFromArray(eventToExternalKey, 'from', 'to'); @@ -201,6 +229,8 @@ const responseBuilderSimple = async (message, category, destination) => { const hashMapUUID = getHashFromArray(eventToUUID, 'event', 'uuid'); // token needed for authorization for subsequent calls const authToken = await getToken(clientId, clientSecret, subDomain); + // map from an event name to an event definition key. + const hashMapEventDefinition = getHashFromArray(eventToDefinitionMapping, 'from', 'to'); // if createOrUpdateContacts is true identify calls for create and update of contacts will not occur. if (category.type === 'identify' && !createOrUpdateContacts) { // first call to identify the contact @@ -234,10 +264,12 @@ const responseBuilderSimple = async (message, category, destination) => { if (typeof message.event !== 'string') { throw new ConfigurationError('Event name must be a string'); } + if (hashMapEventDefinition[message.event.toLowerCase()]) { + return responseBuilderForMessageEvent(message, subDomain, authToken, hashMapEventDefinition); + } if (!isDefinedAndNotNull(hashMapExternalKey[message.event.toLowerCase()])) { throw new ConfigurationError('Event not mapped for this track call'); } - return responseBuilderForInsertData( message, hashMapExternalKey[message.event.toLowerCase()], @@ -287,4 +319,9 @@ const processRouterDest = async (inputs, reqMetadata) => { return respList; }; -module.exports = { process, processRouterDest, responseBuilderSimple }; +module.exports = { + process, + processRouterDest, + responseBuilderSimple, + responseBuilderForMessageEvent, +}; diff --git a/src/v0/destinations/sfmc/transform.test.js b/src/v0/destinations/sfmc/transform.test.js index c49c49017c6..8d382ef6499 100644 --- a/src/v0/destinations/sfmc/transform.test.js +++ b/src/v0/destinations/sfmc/transform.test.js @@ -1,7 +1,7 @@ const { ConfigurationError } = require('@rudderstack/integrations-lib'); const axios = require('axios'); const MockAxiosAdapter = require('axios-mock-adapter'); -const { responseBuilderSimple } = require('./transform'); +const { responseBuilderSimple, responseBuilderForMessageEvent } = require('./transform'); beforeAll(() => { const mock = new MockAxiosAdapter(axios); mock @@ -122,4 +122,44 @@ describe('responseBuilderSimple', () => { expect(response).toHaveProperty('body.JSON'); expect(response).toHaveProperty('headers'); }); + + it('should build response object with correct details for message event', () => { + const message = { + userId: 'u123', + event: 'testEvent', + properties: { + contactId: '12345', + prop1: 'value1', + prop2: 'value2', + }, + }; + const subDomain = 'subdomain'; + const authToken = 'token'; + const hashMapEventDefinition = { + testevent: 'eventDefinitionKey', + }; + + const response = responseBuilderForMessageEvent( + message, + subDomain, + authToken, + hashMapEventDefinition, + ); + expect(response.method).toBe('POST'); + expect(response.endpoint).toBe( + 'https://subdomain.rest.marketingcloudapis.com/interaction/v1/events', + ); + expect(response.headers).toEqual({ + 'Content-Type': 'application/json', + Authorization: 'Bearer token', + }); + expect(response.body.JSON).toEqual({ + ContactKey: '12345', + EventDefinitionKey: 'eventDefinitionKey', + Data: { + prop1: 'value1', + prop2: 'value2', + }, + }); + }); }); diff --git a/src/v0/destinations/snapchat_conversion/transform.js b/src/v0/destinations/snapchat_conversion/transform.js index 37d321a468d..6fec6313a4a 100644 --- a/src/v0/destinations/snapchat_conversion/transform.js +++ b/src/v0/destinations/snapchat_conversion/transform.js @@ -12,7 +12,6 @@ const { getSuccessRespEvents, isAppleFamily, getValidDynamicFormConfig, - checkInvalidRtTfEvents, handleRtTfSingleEventError, batchMultiplexedEvents, } = require('../../util'); @@ -358,11 +357,6 @@ const process = (event) => { }; const processRouterDest = async (inputs, reqMetadata) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } - const eventsChunk = []; // temporary variable to divide payload into chunks const errorRespList = []; inputs.forEach((event) => { diff --git a/src/v0/destinations/snapchat_custom_audience/networkHandler.js b/src/v0/destinations/snapchat_custom_audience/networkHandler.js index db36f6f5180..6044216293a 100644 --- a/src/v0/destinations/snapchat_custom_audience/networkHandler.js +++ b/src/v0/destinations/snapchat_custom_audience/networkHandler.js @@ -43,6 +43,9 @@ const scAudienceProxyRequest = async (request) => { const response = await httpSend(requestOptions, { feature: 'proxy', destType: 'snapchat_custom_audience', + endpointPath: '/segments/segmentId/users', + requestMethod: requestOptions?.method, + module: 'dataDelivery', }); return response; }; @@ -80,7 +83,8 @@ const scaAudienceRespHandler = (destResponse, stageMsg) => { ); }; -const responseHandler = (destinationResponse) => { +const responseHandler = (responseParams) => { + const { destinationResponse } = responseParams; const message = `Request Processed Successfully`; const { status } = destinationResponse; if (isHttpStatusSuccess(status)) { diff --git a/src/v0/destinations/sprig/deleteUsers.js b/src/v0/destinations/sprig/deleteUsers.js index a886bbbafc0..01044adcd1c 100644 --- a/src/v0/destinations/sprig/deleteUsers.js +++ b/src/v0/destinations/sprig/deleteUsers.js @@ -49,7 +49,9 @@ const userDeletionHandler = async (userAttributes, config) => { { destType: 'sprig', feature: 'deleteUsers', - endpointPath: 'api.sprig.com/v2/purge/visitors', + endpointPath: '/purge/visitors', + requestMethod: 'POST', + module: 'deletion', }, ); const handledDelResponse = processAxiosResponse(deletionResponse); @@ -59,6 +61,7 @@ const userDeletionHandler = async (userAttributes, config) => { handledDelResponse.status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(handledDelResponse.status), + [tags.TAG_NAMES.STATUS]: handledDelResponse.status, }, handledDelResponse, ); diff --git a/src/v0/destinations/the_trade_desk/networkHandler.js b/src/v0/destinations/the_trade_desk/networkHandler.js index ca5ac68be87..aebbfc0785e 100644 --- a/src/v0/destinations/the_trade_desk/networkHandler.js +++ b/src/v0/destinations/the_trade_desk/networkHandler.js @@ -22,12 +22,12 @@ const proxyRequest = async (request) => { const ProxyHeaders = { ...headers, + 'Content-Type': JSON_MIME_TYPE, TtdSignature: getSignatureHeader(data, config.advertiserSecretKey), 'TtdSignature-dp': getSignatureHeader( data, process.env.THE_TRADE_DESK_DATA_PROVIDER_SECRET_KEY, ), - 'Content-Type': JSON_MIME_TYPE, }; const requestOptions = { @@ -37,18 +37,25 @@ const proxyRequest = async (request) => { headers: ProxyHeaders, method, }; - const response = await httpSend(requestOptions, { feature: 'proxy', destType: 'the_trade_desk' }); + const response = await httpSend(requestOptions, { + feature: 'proxy', + destType: 'the_trade_desk', + endpointPath: '/track/realtimeconversion', + requestMethod: 'POST', + module: 'dataDelivery', + }); return response; }; -const responseHandler = (destinationResponse) => { +const responseHandler = (responseParams) => { + const { destinationResponse } = responseParams; const message = 'Request Processed Successfully'; const { response, status } = destinationResponse; // if the response from destination is not a success case build an explicit error if (!isHttpStatusSuccess(status)) { throw new NetworkError( - `Request failed with status: ${status} due to ${response}`, + `Request failed with status: ${status} due to ${JSON.stringify(response)}`, status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), @@ -57,7 +64,7 @@ const responseHandler = (destinationResponse) => { ); } - // Trade desk returns 200 with an error in case of "Failed to parse TDID, DAID, UID2, IDL, EUID, or failed to decrypt UID2Token or EUIDToken" + // Trade desk first party data api returns 200 with an error in case of "Failed to parse TDID, DAID, UID2, IDL, EUID, or failed to decrypt UID2Token or EUIDToken" // https://partner.thetradedesk.com/v3/portal/data/doc/post-data-advertiser-external // {"FailedLines":[{"ErrorCode":"MissingUserId","Message":"Invalid DAID, item #1"}]} if ('FailedLines' in response && response.FailedLines.length > 0) { @@ -69,7 +76,7 @@ const responseHandler = (destinationResponse) => { } // else successfully return status, message and original destination response - // Trade desk returns 200 with empty object '{}' in response if all the events are processed successfully + // For first party api trade desk returns 200 with empty object '{}' in response if all the events are processed successfully return { status, message, diff --git a/src/v0/destinations/tiktok_ads/networkHandler.js b/src/v0/destinations/tiktok_ads/networkHandler.js index ae93b1ec15b..5d4b7fd4e06 100644 --- a/src/v0/destinations/tiktok_ads/networkHandler.js +++ b/src/v0/destinations/tiktok_ads/networkHandler.js @@ -8,7 +8,8 @@ const { DESTINATION } = require('./config'); const { TAG_NAMES } = require('../../util/tags'); const { HTTP_STATUS_CODES } = require('../../util/constant'); -const responseHandler = (destinationResponse) => { +const responseHandler = (responseParams) => { + const { destinationResponse } = responseParams; const msg = `[${DESTINATION} Response Handler] - Request Processed Successfully`; const { response: { code }, diff --git a/src/v0/destinations/tiktok_ads/transform.js b/src/v0/destinations/tiktok_ads/transform.js index bdf3a0defe3..17a37984c39 100644 --- a/src/v0/destinations/tiktok_ads/transform.js +++ b/src/v0/destinations/tiktok_ads/transform.js @@ -17,9 +17,9 @@ const { getDestinationExternalID, getFieldValueFromMessage, getHashFromArrayWithDuplicate, - checkInvalidRtTfEvents, handleRtTfSingleEventError, batchMultiplexedEvents, + validateEventName, } = require('../../util'); const { process: processV2, processRouterDest: processRouterDestV2 } = require('./transformV2'); const { getContents } = require('./util'); @@ -130,14 +130,9 @@ const getTrackResponse = (message, Config, event) => { const trackResponseBuilder = async (message, { Config }) => { const { eventsToStandard, sendCustomEvents } = Config; - - let event = message.event?.toLowerCase().trim(); - if (!event) { - throw new InstrumentationError('Event name is required'); - } - + validateEventName(message.event); + let event = message.event.toLowerCase().trim(); const standardEventsMap = getHashFromArrayWithDuplicate(eventsToStandard); - if (!sendCustomEvents && eventNameMapping[event] === undefined && !standardEventsMap[event]) { throw new InstrumentationError( `Event name (${event}) is not valid, must be mapped to one of standard events`, @@ -248,10 +243,6 @@ const processRouterDest = async (inputs, reqMetadata) => { if (Config?.version === 'v2') { return processRouterDestV2(inputs, reqMetadata); } - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } const trackResponseList = []; // list containing single track event in batched format const eventsChunk = []; // temporary variable to divide payload into chunks diff --git a/src/v0/destinations/tiktok_ads/transformV2.js b/src/v0/destinations/tiktok_ads/transformV2.js index 91078dfe656..3bd8699e3ad 100644 --- a/src/v0/destinations/tiktok_ads/transformV2.js +++ b/src/v0/destinations/tiktok_ads/transformV2.js @@ -13,8 +13,8 @@ const { isDefinedAndNotNullAndNotEmpty, getDestinationExternalID, getHashFromArrayWithDuplicate, - checkInvalidRtTfEvents, handleRtTfSingleEventError, + validateEventName, } = require('../../util'); const { getContents, hashUserField } = require('./util'); const config = require('./config'); @@ -40,7 +40,7 @@ const getTrackResponsePayload = (message, destConfig, event) => { } // if contents is not present but we have properties.products present which has fields with superset of contents fields - if (payload.properties && !payload.properties.contents && message.properties.products) { + if (!payload.properties?.contents && message.properties?.products) { // retreiving data from products only when contents is not present payload.properties.contents = getContents(message, false); } @@ -60,7 +60,7 @@ const getTrackResponsePayload = (message, destConfig, event) => { const trackResponseBuilder = async (message, { Config }) => { const { eventsToStandard, sendCustomEvents, accessToken, pixelCode } = Config; - + validateEventName(message.event); let event = message.event?.toLowerCase().trim(); if (!event) { throw new InstrumentationError('Event name is required'); @@ -690,10 +690,6 @@ const batchEvents = (eventsChunk) => { return events; }; const processRouterDest = async (inputs, reqMetadata) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } const trackResponseList = []; // list containing single track event in batched format const eventsChunk = []; // temporary variable to divide payload into chunks const errorRespList = []; diff --git a/src/v0/destinations/tiktok_ads_offline_events/config.js b/src/v0/destinations/tiktok_ads_offline_events/config.js index 5d5e80c7167..4bb3bda850e 100644 --- a/src/v0/destinations/tiktok_ads_offline_events/config.js +++ b/src/v0/destinations/tiktok_ads_offline_events/config.js @@ -19,12 +19,24 @@ const CONFIG_CATEGORIES = { const PARTNER_NAME = 'RudderStack'; const EVENT_NAME_MAPPING = { + addpaymentinfo: 'AddPaymentInfo', + addtocart: 'AddToCart', + addtowishlist: 'AddToWishlist', + 'checkout started': 'InitiateCheckout', 'checkout step completed': 'CompletePayment', + clickbutton: 'ClickButton', + completeregistration: 'CompleteRegistration', contact: 'Contact', + download: 'Download', + 'order completed': 'PlaceAnOrder', + 'payment info entered': 'AddPaymentInfo', + 'product added': 'AddToCart', + 'product added to wishlist': 'AddToWishlist', + search: 'Search', submitform: 'SubmitForm', subscribe: 'Subscribe', + viewcontent: 'ViewContent', }; - const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); module.exports = { diff --git a/src/v0/destinations/tiktok_ads_offline_events/transform.js b/src/v0/destinations/tiktok_ads_offline_events/transform.js index 945c31ea632..dbe9a06dd6e 100644 --- a/src/v0/destinations/tiktok_ads_offline_events/transform.js +++ b/src/v0/destinations/tiktok_ads_offline_events/transform.js @@ -9,7 +9,6 @@ const { removeUndefinedAndNullValues, isDefinedAndNotNullAndNotEmpty, getHashFromArrayWithDuplicate, - checkInvalidRtTfEvents, handleRtTfSingleEventError, getSuccessRespEvents, defaultBatchRequestConfig, @@ -199,11 +198,6 @@ const batchEvents = (eventChunksArray) => { }; const processRouterDest = async (inputs, reqMetadata) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } - const batchErrorRespList = []; const eventChunksArray = []; const { destination } = inputs[0]; diff --git a/src/v0/destinations/trengo/transform.js b/src/v0/destinations/trengo/transform.js index 06e5496a1eb..01c5cfeb254 100644 --- a/src/v0/destinations/trengo/transform.js +++ b/src/v0/destinations/trengo/transform.js @@ -90,7 +90,13 @@ const lookupContact = async (term, destination) => { Authorization: `Bearer ${destination.Config.apiToken}`, }, }, - { destType: 'trengo', feature: 'transformation' }, + { + destType: 'trengo', + feature: 'transformation', + endpointPath: '/contacts', + requestMethod: 'GET', + module: 'router', + }, ); } catch (err) { // check if exists err.response && err.response.status else 500 diff --git a/src/v0/destinations/twitter_ads/config.js b/src/v0/destinations/twitter_ads/config.js index 601675fc2ff..6b0db0622c8 100644 --- a/src/v0/destinations/twitter_ads/config.js +++ b/src/v0/destinations/twitter_ads/config.js @@ -14,5 +14,5 @@ const mappingConfig = getMappingConfig(ConfigCategories, __dirname); module.exports = { mappingConfig, ConfigCategories, - BASE_URL + BASE_URL, }; diff --git a/src/v0/destinations/twitter_ads/util.js b/src/v0/destinations/twitter_ads/util.js index 2f237b1dd86..ad59a812673 100644 --- a/src/v0/destinations/twitter_ads/util.js +++ b/src/v0/destinations/twitter_ads/util.js @@ -2,23 +2,20 @@ const crypto = require('crypto'); const oauth1a = require('oauth-1.0a'); function getAuthHeaderForRequest(request, oAuthObject) { - const oauth = oauth1a({ - consumer: { key: oAuthObject.consumerKey, secret: oAuthObject.consumerSecret }, - signature_method: 'HMAC-SHA1', - hash_function(base_string, k) { - return crypto - .createHmac('sha1', k) - .update(base_string) - .digest('base64') - }, - }) + const oauth = oauth1a({ + consumer: { key: oAuthObject.consumerKey, secret: oAuthObject.consumerSecret }, + signature_method: 'HMAC-SHA1', + hash_function(base_string, k) { + return crypto.createHmac('sha1', k).update(base_string).digest('base64'); + }, + }); - const authorization = oauth.authorize(request, { - key: oAuthObject.accessToken, - secret: oAuthObject.accessTokenSecret, - }); + const authorization = oauth.authorize(request, { + key: oAuthObject.accessToken, + secret: oAuthObject.accessTokenSecret, + }); - return oauth.toHeader(authorization); + return oauth.toHeader(authorization); } -module.exports = { getAuthHeaderForRequest }; \ No newline at end of file +module.exports = { getAuthHeaderForRequest }; diff --git a/src/v0/destinations/user/utils.js b/src/v0/destinations/user/utils.js index 52fba2167ea..f332d7a4a71 100644 --- a/src/v0/destinations/user/utils.js +++ b/src/v0/destinations/user/utils.js @@ -238,6 +238,8 @@ const createCompany = async (message, destination) => { destType: 'user', feature: 'transformation', endpointPath: `/companies/`, + requestMethod: 'POST', + module: 'router', }); const data = processAxiosResponse(response); return data.response; @@ -279,6 +281,8 @@ const updateCompany = async (message, destination, company) => { destType: 'user', feature: 'transformation', endpointPath: `/companies/`, + requestMethod: 'PUT', + module: 'router', }); const data = processAxiosResponse(response); return data.response; @@ -306,6 +310,8 @@ const getUserByUserKey = async (apiKey, userKey, appSubdomain) => { destType: 'user', feature: 'transformation', endpointPath: `/users/search`, + requestMethod: 'GET', + module: 'router', }); const processedUserResponse = processAxiosResponse(userResponse); if (processedUserResponse.status === 200) { @@ -340,6 +346,8 @@ const getUserByEmail = async (apiKey, email, appSubdomain) => { destType: 'user', feature: 'transformation', endpointPath: `/users/search/?email`, + requestMethod: 'GET', + module: 'router', }); const processedUserResponse = processAxiosResponse(userResponse); @@ -379,6 +387,8 @@ const getUserByPhoneNumber = async (apiKey, phoneNumber, appSubdomain) => { destType: 'user', feature: 'transformation', endpointPath: `/users/search/?phone_number`, + requestMethod: 'GET', + module: 'router', }); const processedUserResponse = processAxiosResponse(userResponse); @@ -424,6 +434,8 @@ const getUserByCustomId = async (message, destination) => { destType: 'user', feature: 'transformation', endpointPath: `/users-by-id/`, + requestMethod: 'GET', + module: 'router', }); const processedUserResponse = processAxiosResponse(userResponse); @@ -460,6 +472,8 @@ const getCompanyByCustomId = async (message, destination) => { destType: 'user', feature: 'transformation', endpointPath: `/companies-by-id/`, + requestMethod: 'GET', + module: 'router', }); const processedUserResponse = processAxiosResponse(response); if (processedUserResponse.status === 200) { diff --git a/src/v0/destinations/wootric/util.js b/src/v0/destinations/wootric/util.js index eb61a472cf2..c2505c635be 100644 --- a/src/v0/destinations/wootric/util.js +++ b/src/v0/destinations/wootric/util.js @@ -47,6 +47,8 @@ const getAccessToken = async (destination) => { destType: 'wootric', feature: 'transformation', endpointPath: `/oauth/token`, + requestMethod: 'POST', + module: 'router', }); const processedAuthResponse = processAxiosResponse(wootricAuthResponse); // If the request fails, throwing error. @@ -100,6 +102,8 @@ const retrieveUserDetails = async (endUserId, externalId, accessToken) => { destType: 'wootric', feature: 'transformation', endpointPath: `/v1/end_users/`, + requestMethod: 'GET', + module: 'router', }); const processedUserResponse = processAxiosResponse(userResponse); diff --git a/src/v0/destinations/yahoo_dsp/util.js b/src/v0/destinations/yahoo_dsp/util.js index d41716935fd..255f84d1c91 100644 --- a/src/v0/destinations/yahoo_dsp/util.js +++ b/src/v0/destinations/yahoo_dsp/util.js @@ -137,6 +137,9 @@ const getAccessToken = async (destination) => { const dspAuthorisationData = await httpSend(request, { destType: 'yahoo_dsp', feature: 'transformation', + endpointPath: '/identity/oauth2/access_token', + requestMethod: 'POST', + module: 'router', }); // If the request fails, throwing error. if (dspAuthorisationData.success === false) { diff --git a/src/v0/destinations/zendesk/transform.js b/src/v0/destinations/zendesk/transform.js index bf2bc01ed28..58620147845 100644 --- a/src/v0/destinations/zendesk/transform.js +++ b/src/v0/destinations/zendesk/transform.js @@ -36,7 +36,7 @@ const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); const CONTEXT_TRAITS_KEY_PATH = 'context.traits'; - +const endpointPath = '/users/search.json'; function responseBuilder(message, headers, payload, endpoint) { const response = defaultRequestConfig(); @@ -102,6 +102,9 @@ const payloadBuilderforUpdatingEmail = async (userId, headers, userEmail, baseEn const res = await httpGET(url, config, { destType: 'zendesk', feature: 'transformation', + endpointPath: 'users/userId/identities', + requestMethod: 'POST', + module: 'router', }); if (res?.response?.data?.count > 0) { const { identities } = res.response.data; @@ -147,6 +150,9 @@ async function createUserFields(url, config, newFields, fieldJson) { const response = await myAxios.post(url, fieldData, config, { destType: 'zendesk', feature: 'transformation', + endpointPath: '/users/userId/identities', + requestMethod: 'POST', + module: 'router', }); if (response.status !== 201) { logger.debug(`${NAME}:: Failed to create User Field : `, field); @@ -176,6 +182,8 @@ async function checkAndCreateUserFields( const response = await myAxios.get(url, config, { destType: 'zendesk', feature: 'transformation', + requestMethod: 'POST', + module: 'router', }); const fields = get(response.data, fieldJson); if (response.data && fields) { @@ -253,6 +261,9 @@ const getUserIdByExternalId = async (message, headers, baseEndpoint) => { const resp = await httpGET(url, config, { destType: 'zendesk', feature: 'transformation', + endpointPath, + requestMethod: 'GET', + module: 'router', }); if (resp?.response?.data?.count > 0) { @@ -283,6 +294,9 @@ async function getUserId(message, headers, baseEndpoint, type) { const resp = await myAxios.get(url, config, { destType: 'zendesk', feature: 'transformation', + endpointPath, + requestMethod: 'GET', + module: 'router', }); if (!resp || !resp.data || resp.data.count === 0) { logger.debug(`${NAME}:: User not found`); @@ -307,6 +321,9 @@ async function isUserAlreadyAssociated(userId, orgId, headers, baseEndpoint) { const response = await myAxios.get(url, config, { destType: 'zendesk', feature: 'transformation', + endpointPath: '/users/userId/organization_memberships.json', + requestMethod: 'GET', + module: 'router', }); if (response?.data?.organization_memberships?.[0]?.organization_id === orgId) { return true; @@ -339,6 +356,9 @@ async function createUser(message, headers, destinationConfig, baseEndpoint, typ const resp = await myAxios.post(url, payload, config, { destType: 'zendesk', feature: 'transformation', + endpointPath: '/users/create_or_update.json', + requestMethod: 'POST', + module: 'router', }); if (!resp.data || !resp.data.user || !resp.data.user.id) { @@ -420,6 +440,9 @@ async function createOrganization(message, category, headers, destinationConfig, const resp = await myAxios.post(url, payload, config, { destType: 'zendesk', feature: 'transformation', + endpointPath: '/organizations/create_or_update.json', + requestMethod: 'POST', + module: 'router', }); if (!resp.data || !resp.data.organization) { @@ -488,6 +511,9 @@ async function processIdentify(message, destinationConfig, headers, baseEndpoint const response = await myAxios.get(membershipUrl, config, { destType: 'zendesk', feature: 'transformation', + endpointPath: '/users/userId/organization_memberships.json', + requestMethod: 'GET', + module: 'router', }); if ( response.data && @@ -535,6 +561,9 @@ async function processTrack(message, destinationConfig, headers, baseEndpoint) { const userResponse = await myAxios.get(url, config, { destType: 'zendesk', feature: 'transformation', + endpointPath, + requestMethod: 'GET', + module: 'router', }); if (!get(userResponse, 'data.users.0.id') || userResponse.data.count === 0) { const { zendeskUserId, email } = await createUser( diff --git a/src/v0/sources/auth0/transform.js b/src/v0/sources/auth0/transform.js index d2721780d82..4b78621418e 100644 --- a/src/v0/sources/auth0/transform.js +++ b/src/v0/sources/auth0/transform.js @@ -1,5 +1,6 @@ const path = require('path'); const fs = require('fs'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { removeUndefinedAndNullValues } = require('../../util'); const { getGroupId } = require('./util'); // import mapping json using JSON.parse to preserve object key order @@ -73,7 +74,11 @@ function process(events) { if (!Array.isArray(events)) { eventList = events.logs || [events]; } - return processEvents(eventList); + const responses = processEvents(eventList); + if (responses.length === 0) { + throw new InstrumentationError('UserId is not present'); + } + return responses; } exports.process = process; diff --git a/src/v0/sources/formsort/transform.js b/src/v0/sources/formsort/transform.js index 18d7b8fc0eb..dd37482bc49 100644 --- a/src/v0/sources/formsort/transform.js +++ b/src/v0/sources/formsort/transform.js @@ -1,18 +1,16 @@ -const path = require("path"); -const fs = require("fs"); -const { generateUUID, isDefinedAndNotNull } = require("../../util"); -const Message = require("../message"); +const path = require('path'); +const fs = require('fs'); +const { generateUUID, isDefinedAndNotNull } = require('../../util'); +const Message = require('../message'); // import mapping json using JSON.parse to preserve object key order -const mapping = JSON.parse( - fs.readFileSync(path.resolve(__dirname, "./mapping.json"), "utf-8") -); +const mapping = JSON.parse(fs.readFileSync(path.resolve(__dirname, './mapping.json'), 'utf-8')); function process(event) { const message = new Message(`Formsort`); // we are setting event type as track always - message.setEventType("track"); + message.setEventType('track'); message.setPropertiesV2(event, mapping); @@ -23,9 +21,9 @@ function process(event) { // setting event Name if (event.finalized) { - message.setEventName("FlowFinalized"); + message.setEventName('FlowFinalized'); } else { - message.setEventName("FlowLoaded"); + message.setEventName('FlowLoaded'); } return message; diff --git a/src/v0/sources/formsort/transform.test.js b/src/v0/sources/formsort/transform.test.js index 9b0d814d6af..e3d686fcefb 100644 --- a/src/v0/sources/formsort/transform.test.js +++ b/src/v0/sources/formsort/transform.test.js @@ -1,52 +1,51 @@ const { process } = require('./transform'); it(`Transform.js Tests`, () => { - const data = { - input: { - "answers": { - "yes": true, - "enter_email": "test@user.com", - "enter_name": "2022-11-17", - "yes_or_no": false - }, - "responder_uuid": "66a8e5bb-67e1-47ec-b55f-a26fd4be2dc7", - "flow_label": "new-flow-2022-11-25", - "variant_label": "main", - "variant_uuid": "0828efa7-7215-4e7d-a7ab-6c1079010cea", - "finalized": false, - "created_at": "2022-11-25T14:41:22+00:00" + const data = { + input: { + answers: { + yes: true, + enter_email: 'test@user.com', + enter_name: '2022-11-17', + yes_or_no: false, + }, + responder_uuid: '66a8e5bb-67e1-47ec-b55f-a26fd4be2dc7', + flow_label: 'new-flow-2022-11-25', + variant_label: 'main', + variant_uuid: '0828efa7-7215-4e7d-a7ab-6c1079010cea', + finalized: false, + created_at: '2022-11-25T14:41:22+00:00', + }, + output: { + context: { + library: { + name: 'unknown', + version: 'unknown', }, - output: { - "context": { - "library": { - "name": "unknown", - "version": "unknown" - }, - "integration": { - "name": "Formsort" - }, - "page": { - "title": "new-flow-2022-11-25" - }, - "variantLabel": "main", - "variantUuid": "0828efa7-7215-4e7d-a7ab-6c1079010cea" - }, - "integrations": { - "Formsort": false - }, - "type": "track", - "userId": "66a8e5bb-67e1-47ec-b55f-a26fd4be2dc7", - "originalTimestamp": "2022-11-25T14:41:22+00:00", - "properties": { - "yes": true, - "enter_email": "test@user.com", - "enter_name": "2022-11-17", - "yes_or_no": false - }, - "event": "FlowLoaded" - } - }; - const output = process(data.input); - expect(output).toEqual(data.output); - -}); \ No newline at end of file + integration: { + name: 'Formsort', + }, + page: { + title: 'new-flow-2022-11-25', + }, + variantLabel: 'main', + variantUuid: '0828efa7-7215-4e7d-a7ab-6c1079010cea', + }, + integrations: { + Formsort: false, + }, + type: 'track', + userId: '66a8e5bb-67e1-47ec-b55f-a26fd4be2dc7', + originalTimestamp: '2022-11-25T14:41:22+00:00', + properties: { + yes: true, + enter_email: 'test@user.com', + enter_name: '2022-11-17', + yes_or_no: false, + }, + event: 'FlowLoaded', + }, + }; + const output = process(data.input); + expect(output).toEqual(data.output); +}); diff --git a/src/v0/sources/shopify/shopify.util.test.js b/src/v0/sources/shopify/shopify.util.test.js index 9c570dde41b..d058db36b5c 100644 --- a/src/v0/sources/shopify/shopify.util.test.js +++ b/src/v0/sources/shopify/shopify.util.test.js @@ -1,5 +1,4 @@ -const { getShopifyTopic, -} = require('./util'); +const { getShopifyTopic } = require('./util'); jest.mock('ioredis', () => require('../../../../test/__mocks__/redis')); describe('Shopify Utils Test', () => { describe('Fetching Shopify Topic Test Cases', () => { @@ -58,5 +57,4 @@ describe('Shopify Utils Test', () => { } }); }); - }); diff --git a/src/v0/sources/shopify/shopify_redis.util.test.js b/src/v0/sources/shopify/shopify_redis.util.test.js index db596e1dfb1..fb998379328 100644 --- a/src/v0/sources/shopify/shopify_redis.util.test.js +++ b/src/v0/sources/shopify/shopify_redis.util.test.js @@ -1,5 +1,9 @@ const { getAnonymousIdAndSessionId, checkAndUpdateCartItems } = require('./util'); jest.mock('ioredis', () => require('../../../../test/__mocks__/redis')); +const metricMetadata = { + writeKey: 'dummyKey', + source: 'src', +}; describe('Shopify Utils Test', () => { describe('Check for valid cart update event test cases', () => { it('Event containing token and nothing is retreived from redis and less than req. time difference between created_at and uadated_at', async () => { @@ -14,7 +18,7 @@ describe('Shopify Utils Test', () => { created_at: '2023-02-10T12:05:04.402Z', }; const expectedOutput = false; - const output = await checkAndUpdateCartItems(input); + const output = await checkAndUpdateCartItems(input, null, metricMetadata); expect(output).toEqual(expectedOutput); }); it('Event containing token and nothing is retreived from redis', async () => { @@ -28,7 +32,7 @@ describe('Shopify Utils Test', () => { ], }; const expectedOutput = true; - const output = await checkAndUpdateCartItems(input); + const output = await checkAndUpdateCartItems(input, null, metricMetadata); expect(output).toEqual(expectedOutput); }); @@ -44,7 +48,7 @@ describe('Shopify Utils Test', () => { }; const expectedOutput = true; - const output = await checkAndUpdateCartItems(input); + const output = await checkAndUpdateCartItems(input, null, metricMetadata); expect(output).toEqual(expectedOutput); }); @@ -60,7 +64,7 @@ describe('Shopify Utils Test', () => { }; const expectedOutput = false; - const output = await checkAndUpdateCartItems(input); + const output = await checkAndUpdateCartItems(input, null, metricMetadata); expect(output).toEqual(expectedOutput); }); @@ -76,7 +80,7 @@ describe('Shopify Utils Test', () => { }; const expectedOutput = true; - const output = await checkAndUpdateCartItems(input); + const output = await checkAndUpdateCartItems(input, null, metricMetadata); expect(output).toEqual(expectedOutput); }); }); diff --git a/src/v0/sources/shopify/transform.js b/src/v0/sources/shopify/transform.js index 013580d7a3c..93e3ed0c72b 100644 --- a/src/v0/sources/shopify/transform.js +++ b/src/v0/sources/shopify/transform.js @@ -143,7 +143,7 @@ const processEvent = async (inputEvent, metricMetadata) => { break; case 'carts_update': if (useRedisDatabase) { - redisData = await getDataFromRedis(event.id || event.token); + redisData = await getDataFromRedis(event.id || event.token, metricMetadata); const isValidEvent = await checkAndUpdateCartItems(inputEvent, redisData, metricMetadata); if (!isValidEvent) { return NO_OPERATION_SUCCESS; @@ -154,8 +154,9 @@ const processEvent = async (inputEvent, metricMetadata) => { default: if (!SUPPORTED_TRACK_EVENTS.includes(shopifyTopic)) { stats.increment('invalid_shopify_event', { - event: shopifyTopic, - ...metricMetadata, + writeKey: metricMetadata.writeKey, + source: metricMetadata.source, + shopifyTopic: metricMetadata.shopifyTopic, }); return NO_OPERATION_SUCCESS; } @@ -215,7 +216,8 @@ const processIdentifierEvent = async (event, metricMetadata) => { stats.increment('shopify_redis_calls', { type: 'set', field: 'itemsHash', - ...metricMetadata, + source: metricMetadata.source, + writeKey: metricMetadata.writeKey, }); /* cart_token: { anonymousId: 'anon_id1', @@ -236,14 +238,16 @@ const processIdentifierEvent = async (event, metricMetadata) => { stats.increment('shopify_redis_calls', { type: 'set', field, - ...metricMetadata, + source: metricMetadata.source, + writeKey: metricMetadata.writeKey, }); await RedisDB.setVal(`${event.cartToken}`, value); } catch (e) { logger.debug(`{{SHOPIFY::}} cartToken map set call Failed due redis error ${e}`); stats.increment('shopify_redis_failures', { type: 'set', - ...metricMetadata, + source: metricMetadata.source, + writeKey: metricMetadata.writeKey, }); } } diff --git a/src/v0/sources/shopify/util.js b/src/v0/sources/shopify/util.js index 6f31ade4a70..c4bbb61b9cc 100644 --- a/src/v0/sources/shopify/util.js +++ b/src/v0/sources/shopify/util.js @@ -29,7 +29,8 @@ const getDataFromRedis = async (key, metricMetadata) => { stats.increment('shopify_redis_calls', { type: 'get', field: 'all', - ...metricMetadata, + writeKey: metricMetadata.writeKey, + source: metricMetadata.source, }); const redisData = await RedisDB.getVal(key); if ( @@ -37,7 +38,8 @@ const getDataFromRedis = async (key, metricMetadata) => { (typeof redisData === 'object' && Object.keys(redisData).length === 0) ) { stats.increment('shopify_redis_no_val', { - ...metricMetadata, + writeKey: metricMetadata.writeKey, + source: metricMetadata.source, }); } return redisData; @@ -45,7 +47,8 @@ const getDataFromRedis = async (key, metricMetadata) => { logger.debug(`{{SHOPIFY::}} Get call Failed due redis error ${e}`); stats.increment('shopify_redis_failures', { type: 'get', - ...metricMetadata, + writeKey: metricMetadata.writeKey, + source: metricMetadata.source, }); } return null; @@ -166,7 +169,9 @@ const getAnonymousIdAndSessionId = async (message, metricMetadata, redisData = n if (isDefinedAndNotNull(anonymousId) && isDefinedAndNotNull(sessionId)) { stats.increment('shopify_anon_id_resolve', { method: 'note_attributes', - ...metricMetadata, + writeKey: metricMetadata.writeKey, + source: metricMetadata.source, + shopifyTopic: metricMetadata.shopifyTopic, }); return { anonymousId, sessionId }; } @@ -198,7 +203,9 @@ const getAnonymousIdAndSessionId = async (message, metricMetadata, redisData = n // and for how many stats.increment('shopify_anon_id_resolve', { method: 'database', - ...metricMetadata, + writeKey: metricMetadata.writeKey, + source: metricMetadata.source, + shopifyTopic: metricMetadata.shopifyTopic, }); } return { anonymousId, sessionId }; @@ -215,14 +222,16 @@ const updateCartItemsInRedis = async (cartToken, newCartItemsHash, metricMetadat stats.increment('shopify_redis_calls', { type: 'set', field: 'itemsHash', - ...metricMetadata, + writeKey: metricMetadata.writeKey, + source: metricMetadata.source, }); await RedisDB.setVal(`${cartToken}`, value); } catch (e) { logger.debug(`{{SHOPIFY::}} itemsHash set call Failed due redis error ${e}`); stats.increment('shopify_redis_failures', { type: 'set', - ...metricMetadata, + writeKey: metricMetadata.writeKey, + source: metricMetadata.source, }); } }; diff --git a/src/v0/util/facebookUtils/index.js b/src/v0/util/facebookUtils/index.js index 4c095185592..c7753d255fb 100644 --- a/src/v0/util/facebookUtils/index.js +++ b/src/v0/util/facebookUtils/index.js @@ -147,7 +147,7 @@ const getContentType = (message, defaultValue, categoryToContent, destinationNam return integrationsObj.contentType; } - let { category } = properties; + let { category } = properties || {}; if (!category) { const { products } = properties; if (products && products.length > 0 && Array.isArray(products) && isObject(products[0])) { @@ -298,4 +298,5 @@ module.exports = { transformedPayloadData, formingFinalResponse, fetchUserData, + deduceFbcParam, }; diff --git a/src/v0/util/facebookUtils/index.test.js b/src/v0/util/facebookUtils/index.test.js index 98e4ccec402..20c4ee59f25 100644 --- a/src/v0/util/facebookUtils/index.test.js +++ b/src/v0/util/facebookUtils/index.test.js @@ -1,5 +1,11 @@ -const { transformedPayloadData } = require('./index'); +const { + transformedPayloadData, + fetchUserData, + deduceFbcParam, + getContentType, +} = require('./index'); const sha256 = require('sha256'); +const { MAPPING_CONFIG, CONFIG_CATEGORIES } = require('../../destinations/facebook_pixel/config'); describe('transformedPayloadData_function', () => { // Tests with default values for all parameters @@ -301,3 +307,335 @@ describe('transformedPayloadData_function', () => { expect(result).toEqual({}); }); }); + +describe('deduceFbcParam', () => { + // Should return undefined if message.context.page.url is undefined + it('should return undefined when message.context.page.url is undefined', () => { + const message = {}; + const result = deduceFbcParam(message); + expect(result).toBeUndefined(); + }); + + // Should return undefined if URL constructor throws an error + it('should return undefined when URL constructor throws an error', () => { + const message = { + context: { + page: { + url: 'invalid-url', + }, + }, + }; + const result = deduceFbcParam(message); + expect(result).toBeUndefined(); + }); + + // Should return undefined if fbclid is undefined + it('should return undefined when fbclid is undefined', () => { + const message = { + context: { + page: { + url: 'https://example.com', + }, + }, + }; + const result = deduceFbcParam(message); + expect(result).toBeUndefined(); + }); + + // Should handle message with empty context object + it('should handle message with empty context object', () => { + const message = { + context: {}, + }; + const result = deduceFbcParam(message); + expect(result).toBeUndefined(); + }); + + // Should handle message with empty page object + it('should handle message with empty page object', () => { + const message = { + context: { + page: {}, + }, + }; + const result = deduceFbcParam(message); + expect(result).toBeUndefined(); + }); + + // Should handle message with empty url string + it('should handle message with empty url string', () => { + const message = { + context: { + page: { + url: '', + }, + }, + }; + const result = deduceFbcParam(message); + expect(result).toBeUndefined(); + }); + + // Should return fbc parameter when all conditions are met + it('should return fbc parameter when all conditions are met', () => { + const message = { + context: { + page: { + url: 'https://example.com?fbclid=123456', + }, + }, + }; + const result = deduceFbcParam(message); + expect(result).toEqual(expect.stringContaining('fb.1.')); + }); +}); + +describe('fetchUserData', () => { + const message = { + channel: 'web', + context: { + traits: { + name: 'Rudder Test', + email: 'abc@gmail.com', + firstname: 'Rudder', + lastname: 'Test', + phone: 9000000000, + gender: 'female', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2023-10-14T15:46:51.693229+05:30', + anonymousId: '00000000000000000000000000', + userId: '123456', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }; + + const Config = { + blacklistPiiProperties: [ + { + blacklistPiiProperties: '', + blacklistPiiHash: false, + }, + ], + accessToken: '09876', + pixelId: 'dummyPixelId', + eventsToEvents: [ + { + from: '', + to: '', + }, + ], + eventCustomProperties: [ + { + eventCustomProperties: '', + }, + ], + valueFieldIdentifier: '', + advancedMapping: true, + whitelistPiiProperties: [ + { + whitelistPiiProperties: '', + }, + ], + }; + + // Returns a valid user data object when given valid inputs. + it('should return a valid user data object when given valid inputs without integrations object', () => { + const mappingJson = MAPPING_CONFIG[CONFIG_CATEGORIES.USERDATA.name]; + const destinationName = 'fb_pixel'; + + const result = fetchUserData(message, Config, mappingJson, destinationName); + + expect(result).toEqual({ + external_id: '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + ph: '593a6d58f34eb5c3de4f47e38d1faaa7d389fafe332a85400b1e54498391c579', + ge: '252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111', + ln: '532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25', + fn: '2c2ccf28d806f6f9a34b67aa874d2113b7ac1444f1a4092541b8b75b84771747', + client_ip_address: '0.0.0.0', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + fbc: undefined, + }); + }); + + it('should return a valid user data object when given valid inputs with integrations object', () => { + const mappingJson = MAPPING_CONFIG[CONFIG_CATEGORIES.USERDATA.name]; + const destinationName = 'fb_pixel'; + message.integrations.FacebookPixel = { hashed: true }; + + const result = fetchUserData(message, Config, mappingJson, destinationName); + + expect(result).toEqual({ + em: 'abc@gmail.com', + external_id: '123456', + ph: '9000000000', + ge: '252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111', + ln: 'Test', + fn: 'Rudder', + client_ip_address: '0.0.0.0', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + fbc: undefined, + }); + }); + + it('should return null when mappingJson is undefined', () => { + const mappingJson = undefined; + const destinationName = 'fb_pixel'; + const result = fetchUserData(message, Config, mappingJson, destinationName); + + expect(result).toBeNull(); + }); + + it('should return hashed data when destinationName is undefined', () => { + const mappingJson = MAPPING_CONFIG[CONFIG_CATEGORIES.USERDATA.name]; + const destinationName = undefined; + + const result = fetchUserData(message, Config, mappingJson, destinationName); + + expect(result).toEqual({ + client_ip_address: '0.0.0.0', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + external_id: '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92', + fbc: undefined, + fn: '2c2ccf28d806f6f9a34b67aa874d2113b7ac1444f1a4092541b8b75b84771747', + ge: '252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111', + ln: '532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25', + ph: '593a6d58f34eb5c3de4f47e38d1faaa7d389fafe332a85400b1e54498391c579', + }); + }); +}); + +describe('getContentType', () => { + // Returns default value when no category or categoryToContent is provided + it('should return default value when no category or categoryToContent is provided', () => { + const message = { + properties: { + produtcs: [ + { + product_id: '123', + }, + ], + }, + }; + const defaultValue = 'product'; + const categoryToContent = []; + const destinationName = 'fb_pixel'; + + const result = getContentType(message, defaultValue, categoryToContent, destinationName); + + expect(result).toBe(defaultValue); + }); + + // Returns default value when categoryToContent is not an array + it('should return default value when categoryToContent is not an array', () => { + const message = { + properties: { + products: [ + { + product_id: '123', + }, + ], + }, + }; + const defaultValue = 'product'; + const categoryToContent = 'not an array'; + const destinationName = 'fb_pixel'; + + const result = getContentType(message, defaultValue, categoryToContent, destinationName); + + expect(result).toBe(defaultValue); + }); + + // Returns categoryToContent value when category is provided and matches with categoryToContent + it('should return categoryToContent value when category is provided and matches with categoryToContent', () => { + const message = { + properties: { + category: 'clothing', + }, + }; + const defaultValue = 'product'; + const categoryToContent = [{ from: 'clothing', to: 'garments' }]; + const destinationName = 'fb_pixel'; + + const result = getContentType(message, defaultValue, categoryToContent, destinationName); + + expect(result).toBe(categoryToContent[0].to); + }); + + // Returns integrationsObj.contentType when it exists + it('should return integrationsObj.contentType when it exists', () => { + const message = { + properties: { + products: [ + { + product_id: '123', + }, + ], + }, + integrations: { + fb_pixel: { + contentType: 'content_type_value', + }, + }, + }; + const defaultValue = 'product'; + const categoryToContent = []; + const destinationName = 'fb_pixel'; + const integrationsObj = { + contentType: 'content_type_value', + }; + + const result = getContentType(message, defaultValue, categoryToContent, destinationName); + + expect(result).toBe(integrationsObj.contentType); + }); + + // Returns 'product' when category is 'clothing' and categoryToContent is not provided + it("should return 'product' when category is 'clothing' and categoryToContent is not provided", () => { + const message = { + properties: { + category: 'clothing', + }, + }; + const defaultValue = 'product'; + const categoryToContent = []; + const destinationName = 'fb_pixel'; + + const result = getContentType(message, defaultValue, categoryToContent, destinationName); + + expect(result).toBe(defaultValue); + }); +}); diff --git a/src/v0/util/facebookUtils/networkHandler.js b/src/v0/util/facebookUtils/networkHandler.js index e0d69fa5c8b..d5a731067f5 100644 --- a/src/v0/util/facebookUtils/networkHandler.js +++ b/src/v0/util/facebookUtils/networkHandler.js @@ -1,12 +1,18 @@ const { isEmpty } = require('lodash'); const get = require('get-value'); -const { NetworkError } = require('@rudderstack/integrations-lib'); +const { + NetworkError, + ConfigurationAuthError, + isDefinedAndNotNull, + ERROR_TYPES, + TAG_NAMES, + METADATA, +} = require('@rudderstack/integrations-lib'); const { processAxiosResponse, getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); const { prepareProxyRequest, proxyRequest } = require('../../../adapters/network'); -const tags = require('../tags'); const { ErrorDetailsExtractorBuilder } = require('../../../util/error-extractor'); /** @@ -100,12 +106,26 @@ const errorDetailsMap = { 190: { 460: new ErrorDetailsExtractorBuilder() .setStatus(400) + .setStat({ + [TAG_NAMES.ERROR_TYPE]: ERROR_TYPES.AUTH, + }) .setMessage( 'The session has been invalidated because the user changed their password or Facebook has changed the session for security reasons', ) .build(), + + 463: new ErrorDetailsExtractorBuilder() + .setStatus(400) + .setStat({ + [TAG_NAMES.ERROR_TYPE]: ERROR_TYPES.AUTH, + }) + .setMessageField('message') + .build(), default: new ErrorDetailsExtractorBuilder() .setStatus(400) + .setStat({ + [TAG_NAMES.ERROR_TYPE]: ERROR_TYPES.AUTH, + }) .setMessage('Invalid OAuth 2.0 access token') .build(), }, @@ -217,7 +237,7 @@ const getStatus = (error) => { // Unhandled error response return { status: errorStatus, - tags: { [tags.TAG_NAMES.META]: tags.METADATA.UNHANDLED_STATUS_CODE }, + stats: { [TAG_NAMES.META]: METADATA.UNHANDLED_STATUS_CODE }, }; } errorStatus = errorDetail.status; @@ -227,7 +247,7 @@ const getStatus = (error) => { errorMessage = get(error, errorDetail?.messageDetails?.field); } - return { status: errorStatus, errorMessage }; + return { status: errorStatus, errorMessage, stats: errorDetail?.stat }; }; const errorResponseHandler = (destResponse) => { @@ -237,19 +257,26 @@ const errorResponseHandler = (destResponse) => { return; } const { error } = response; - const { status, errorMessage, tags: errorStatTags } = getStatus(error); + const { status, errorMessage, stats: errorStatTags } = getStatus(error); + if ( + isDefinedAndNotNull(errorStatTags) && + errorStatTags?.[TAG_NAMES.ERROR_TYPE] === ERROR_TYPES.AUTH + ) { + throw new ConfigurationAuthError(errorMessage, { ...response, status: destResponse.status }); + } throw new NetworkError( `${errorMessage || error.message || 'Unknown failure during response transformation'}`, status, { ...errorStatTags, - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + [TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), }, { ...response, status: destResponse.status }, ); }; -const destResponseHandler = (destinationResponse) => { +const destResponseHandler = (responseParams) => { + const { destinationResponse } = responseParams; errorResponseHandler(destinationResponse); return { destinationResponse: destinationResponse.response, diff --git a/src/v0/util/googleUtils/index.js b/src/v0/util/googleUtils/index.js index c8d872e90e9..c153731e730 100644 --- a/src/v0/util/googleUtils/index.js +++ b/src/v0/util/googleUtils/index.js @@ -1,30 +1,91 @@ const GOOGLE_ALLOWED_CONSENT_STATUS = ['UNSPECIFIED', 'UNKNOWN', 'GRANTED', 'DENIED']; +const UNSPECIFIED_CONSENT = 'UNSPECIFIED'; +const UNKNOWN_CONSENT = 'UNKNOWN'; + /** - * Populates the consent object based on the provided properties. + * Populates the consent object based on the provided configuration and consent mapping. * - * @param {object} properties - message.properties containing properties related to consent. - * @returns {object} - An object containing consent information. - * ref : https://developers.google.com/google-ads/api/rest/reference/rest/v15/Consent + * @param {Object} config - The configuration object containing consent values. + * @param {Object} consentConfigMap - The mapping of consent keys to consent types. + * @returns {Object} - The consent object populated with consent values based on the configuration. + * * ref : https://developers.google.com/google-ads/api/rest/reference/rest/v16/Consent */ - -const populateConsentForGoogleDestinations = (properties) => { +const populateConsentFromConfig = (config, consentConfigMap) => { const consent = {}; - if ( - properties?.userDataConsent && - GOOGLE_ALLOWED_CONSENT_STATUS.includes(properties.userDataConsent) - ) { - consent.adUserData = properties.userDataConsent; - } + Object.keys(consentConfigMap).forEach((key) => { + const consentType = consentConfigMap[key]; + if (config?.[key]) { + if (GOOGLE_ALLOWED_CONSENT_STATUS.includes(config[key])) { + consent[consentType] = config[key]; + } else { + consent[consentType] = UNKNOWN_CONSENT; + } + } else { + consent[consentType] = UNSPECIFIED_CONSENT; + } + }); - if ( - properties?.personalizationConsent && - GOOGLE_ALLOWED_CONSENT_STATUS.includes(properties.personalizationConsent) - ) { - consent.adPersonalization = properties.personalizationConsent; - } return consent; }; -module.exports = { populateConsentForGoogleDestinations }; +/** + * Generates the final consent object based on the provided consent configuration map, event-level consent, and destination configuration. + * + * @param {Object} consentConfigMap - The map of consent configuration keys and their corresponding consent types. + * @param {Object} [eventLevelConsent={}] - The event-level consent object. + * @param {Object} [destConfig={}] - The destination configuration object. + * @returns {Object} The final consent object. + * ref : + * 1) For click conversion : + * a) https://developers.google.com/google-ads/api/rest/reference/rest/v16/customers/uploadClickConversions#ClickConversion + * b) https://developers.google.com/google-ads/api/reference/rpc/v16/ClickConversion#consent + * 2) For Call conversion : + * a) https://developers.google.com/google-ads/api/rest/reference/rest/v16/customers/uploadCallConversions#CallConversion + * b) https://developers.google.com/google-ads/api/reference/rpc/v16/CallConversion#consent + * 3) For Store sales conversion : + * a) https://developers.google.com/google-ads/api/reference/rpc/v16/UserData + * b) https://developers.google.com/google-ads/api/reference/rpc/v16/UserData#consent + */ +const finaliseConsent = (consentConfigMap, eventLevelConsent = {}, destConfig = {}) => { + // Initialize defaultConsentBlock with unspecified consent for all keys defined in consentConfigMap + const defaultConsentBlock = Object.keys(consentConfigMap).reduce((acc, key) => { + const consentType = consentConfigMap[key]; + acc[consentType] = UNSPECIFIED_CONSENT; + return acc; + }, {}); + + // If destConfig is provided, update defaultConsentBlock based on it using populateConsentFromConfig + if (Object.keys(destConfig).length > 0) { + const populatedConsent = populateConsentFromConfig(destConfig, consentConfigMap); + Object.assign(defaultConsentBlock, populatedConsent); + } + + const consentObj = {}; + + // Iterate through each key in consentConfigMap to determine the final consent + Object.keys(consentConfigMap).forEach((configKey) => { + const consentKey = consentConfigMap[configKey]; // e.g., 'adUserData' + + // Prioritize event-level consent if available + if (eventLevelConsent && eventLevelConsent.hasOwnProperty(consentKey)) { + consentObj[consentKey] = GOOGLE_ALLOWED_CONSENT_STATUS.includes(eventLevelConsent[consentKey]) + ? eventLevelConsent[consentKey] + : UNKNOWN_CONSENT; + } else { + // Fallback to default consent block + consentObj[consentKey] = defaultConsentBlock[consentKey]; + } + }); + + return consentObj; +}; + +module.exports = { + populateConsentFromConfig, + UNSPECIFIED_CONSENT, + UNKNOWN_CONSENT, + GOOGLE_ALLOWED_CONSENT_STATUS, + finaliseConsent, +}; diff --git a/src/v0/util/googleUtils/index.test.js b/src/v0/util/googleUtils/index.test.js index 27eff2a7936..28e0fa9ac80 100644 --- a/src/v0/util/googleUtils/index.test.js +++ b/src/v0/util/googleUtils/index.test.js @@ -1,50 +1,245 @@ -const { populateConsentForGoogleDestinations } = require('./index'); +const { populateConsentFromConfig, finaliseConsent } = require('./index'); -describe('unit test for populateConsentForGoogleDestinations', () => { - // Returns an empty object when no properties are provided. - it('should return an empty object when no properties are provided', () => { - const result = populateConsentForGoogleDestinations({}); - expect(result).toEqual({}); +describe('unit test for populateConsentFromConfig', () => { + const consentConfigMap = { + personalizationConsent: 'adPersonalization', + userDataConsent: 'adUserData', + }; + it('should return an UNSPECIFIED object when no properties are provided', () => { + const result = populateConsentFromConfig({}, consentConfigMap); + expect(result).toEqual({ + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }); }); - // Sets adUserData property of consent object when userDataConsent property is provided and its value is one of the allowed consent statuses. it('should set adUserData property of consent object when userDataConsent property is provided and its value is one of the allowed consent statuses', () => { const properties = { userDataConsent: 'GRANTED' }; - const result = populateConsentForGoogleDestinations(properties); - expect(result).toEqual({ adUserData: 'GRANTED' }); + const result = populateConsentFromConfig(properties, consentConfigMap); + expect(result).toEqual({ adUserData: 'GRANTED', adPersonalization: 'UNSPECIFIED' }); }); - // Sets adPersonalization property of consent object when personalizationConsent property is provided and its value is one of the allowed consent statuses. it('should set adPersonalization property of consent object when personalizationConsent property is provided and its value is one of the allowed consent statuses', () => { const properties = { personalizationConsent: 'DENIED' }; - const result = populateConsentForGoogleDestinations(properties); - expect(result).toEqual({ adPersonalization: 'DENIED' }); + const result = populateConsentFromConfig(properties, consentConfigMap); + expect(result).toEqual({ adPersonalization: 'DENIED', adUserData: 'UNSPECIFIED' }); + }); + + it('should return an UNSPECIFIED object when properties parameter is not provided', () => { + const result = populateConsentFromConfig(undefined, consentConfigMap); + expect(result).toEqual({ + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }); + }); + + it('should return an UNSPECIFIED object when properties parameter is null', () => { + const result = populateConsentFromConfig(null, consentConfigMap); + expect(result).toEqual({ + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }); + }); + + it('should return an UNSPECIFIED object when properties parameter is an UNSPECIFIED object', () => { + const result = populateConsentFromConfig({}, consentConfigMap); + expect(result).toEqual({ + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }); + }); + + it('should return UNKNOWN when properties parameter contains adUserData and adPersonalization with non-allowed values', () => { + const result = populateConsentFromConfig( + { + userDataConsent: 'RANDOM', + personalizationConsent: 'RANDOM', + }, + consentConfigMap, + ); + expect(result).toEqual({ + adPersonalization: 'UNKNOWN', + adUserData: 'UNKNOWN', + }); + }); +}); + +describe('finaliseConsent', () => { + const consentConfigMap = { + personalizationConsent: 'adPersonalization', + userDataConsent: 'adUserData', + }; + // Returns an object containing consent information. + it('should return an object containing consent information when eventLevelConsent, destConfig, and destinationAllowedConsentKeys are provided', () => { + const eventLevelConsent = { + adUserData: 'GRANTED', + adPersonalization: 'DENIED', + }; + const destConfig = { + userDataConsent: 'UNKNOWN', + personalizationConsent: 'GRANTED', + }; + + const result = finaliseConsent(consentConfigMap, eventLevelConsent, destConfig); + + expect(result).toEqual({ + adUserData: 'GRANTED', + adPersonalization: 'DENIED', + }); + }); + + it('should return an object containing consent information from destConfig when evenLevelConsent is empty object', () => { + const eventLevelConsent = {}; // for store conversion we will use this + const destConfig = { + userDataConsent: 'UNKNOWN', + personalizationConsent: 'GRANTED', + }; + + const result = finaliseConsent(consentConfigMap, eventLevelConsent, destConfig); + + expect(result).toEqual({ + adUserData: 'UNKNOWN', + adPersonalization: 'GRANTED', + }); + }); + + // If destConfig is not provided, it does not return UNSPECIFIED_CONSENT. + it('should not return UNSPECIFIED_CONSENT when destConfig is not provided but event level consent is provided', () => { + const eventLevelConsent = { + adUserData: 'GRANTED', + adPersonalization: 'DENIED', + }; + const result = finaliseConsent(consentConfigMap, eventLevelConsent, undefined); + + // Assert + expect(result).toEqual({ + adUserData: 'GRANTED', + adPersonalization: 'DENIED', + }); }); - // Returns an empty object when properties parameter is not provided. - it('should return an empty object when properties parameter is not provided', () => { - const result = populateConsentForGoogleDestinations(); - expect(result).toEqual({}); + it('should return UNSPECIFIED_CONSENT when both destConfig and event level consent is not provided', () => { + const result = finaliseConsent(consentConfigMap, undefined, undefined); + + // Assert + expect(result).toEqual({ + adUserData: 'UNSPECIFIED', + adPersonalization: 'UNSPECIFIED', + }); + }); + + it('should return UNKWOWN_CONSENT when destConfig is provided with wrong consent value', () => { + const destConfig = { + userDataConsent: 'UNKNOWN', + personalizationConsent: 'WRONG CONSENT', + }; + + const result = finaliseConsent(consentConfigMap, undefined, destConfig); + + expect(result).toEqual({ + adUserData: 'UNKNOWN', + adPersonalization: 'UNKNOWN', + }); + }); + + it('should return UNKWOWN_CONSENT when destConfig is provided with wrong consent value', () => { + const destConfig = { + userDataConsent: 'UNKNOWN', + personalizationConsent: 'WRONG CONSENT', + }; + + const result = finaliseConsent(consentConfigMap, undefined, destConfig); + + expect(result).toEqual({ + adPersonalization: 'UNKNOWN', + adUserData: 'UNKNOWN', + }); + }); + + it('should return consent block with appropriate fields and values from destConfig', () => { + const consentConfigMap = { + personalizationConsent: 'newKey1', + userDataConsent: 'newKey2', + }; + const destConfig = { + userDataConsent: 'GRANTED', + personalizationConsent: 'GRANTED', + }; + + const result = finaliseConsent(consentConfigMap, undefined, destConfig); + + expect(result).toEqual({ + newKey1: 'GRANTED', + newKey2: 'GRANTED', + }); }); - // Returns an empty object when properties parameter is null. - it('should return an empty object when properties parameter is null', () => { - const result = populateConsentForGoogleDestinations(null); - expect(result).toEqual({}); + it('should return consent block with appropriate fields from consentConfigMap and values from eventLevel consent', () => { + const consentConfigMap = { + personalizationConsent: 'newKey1', + userDataConsent: 'newKey2', + }; + const destConfig = { + userDataConsent: 'GRANTED', + personalizationConsent: 'GRANTED', + }; + + const eventLevelConsent = { + newKey1: 'UNKNOWN', + newKey2: 'UNSPECIFIED', + }; + + const result = finaliseConsent(consentConfigMap, eventLevelConsent, destConfig); + + expect(result).toEqual({ + newKey1: 'UNKNOWN', + newKey2: 'UNSPECIFIED', + }); }); - // Returns an empty object when properties parameter is an empty object. - it('should return an empty object when properties parameter is an empty object', () => { - const result = populateConsentForGoogleDestinations({}); - expect(result).toEqual({}); + it('consentConfig and eventLevelConsent should have parity, also the values should be within allowed values otherwise UNKNOWN is returned ', () => { + const consentConfigMap = { + personalizationConsent: 'newKey1', + userDataConsent: 'newKey2', + }; + const destConfig = { + userDataConsent: 'GRANTED', + personalizationConsent: 'GRANTED', + }; + + const eventLevelConsent = { + adUserData: 'UNKNOWN', + adPersonalization: 'UNSPECIFIED', + }; + + const result = finaliseConsent(consentConfigMap, eventLevelConsent, destConfig); + + expect(result).toEqual({ + newKey1: 'GRANTED', + newKey2: 'GRANTED', + }); }); - // Returns an empty object when properties parameter is an empty object. - it('should return an empty object when properties parameter contains adUserData and adPersonalization with non-allowed values', () => { - const result = populateConsentForGoogleDestinations({ - adUserData: 'RANDOM', - personalizationConsent: 'RANDOM', + it('consentConfig and eventLevelConsent should have parity, otherwise it will take values from destConfig ', () => { + const consentConfigMap = { + personalizationConsent: 'newKey1', + userDataConsent: 'newKey2', + }; + const destConfig = { + userDataConsent: 'GRANTED', + personalizationConsent: 'GRANTED', + }; + + const eventLevelConsent = { + newKey1: 'DENIED', + newKey2: 'RANDOM', + }; + + const result = finaliseConsent(consentConfigMap, eventLevelConsent, destConfig); + + expect(result).toEqual({ + newKey1: 'DENIED', + newKey2: 'UNKNOWN', }); - expect(result).toEqual({}); }); }); diff --git a/src/v0/util/index.js b/src/v0/util/index.js index c7a26b6a2fb..32872cc5d9c 100644 --- a/src/v0/util/index.js +++ b/src/v0/util/index.js @@ -22,6 +22,7 @@ const { PlatformError, TransformationError, OAuthSecretError, + getErrorRespEvents, } = require('@rudderstack/integrations-lib'); const logger = require('../../logger'); const stats = require('../../util/stats'); @@ -33,6 +34,7 @@ const { AUTH_STATUS_INACTIVE, } = require('../../adapters/networkhandler/authConstants'); const { FEATURE_FILTER_CODE, FEATURE_GZIP_SUPPORT } = require('./constant'); +const { CommonUtils } = require('../../util/common'); // ======================================================================== // INLINERS @@ -50,6 +52,7 @@ const removeUndefinedAndNullAndEmptyValues = (obj) => lodash.pickBy(obj, isDefinedAndNotNullAndNotEmpty); const isBlank = (value) => lodash.isEmpty(lodash.toString(value)); const flattenMap = (collection) => lodash.flatMap(collection, (x) => x); +const isNull = (x) => lodash.isNull(x); // ======================================================================== // GENERIC UTLITY // ======================================================================== @@ -481,16 +484,6 @@ const getSuccessRespEvents = ( destination, }); -// Router transformer -// Error responses -const getErrorRespEvents = (metadata, statusCode, error, statTags, batched = false) => ({ - metadata, - batched, - statusCode, - error, - statTags, -}); - // ======================================================================== // Error Message UTILITIES // ======================================================================== @@ -1279,6 +1272,31 @@ function getFullName(message) { return fullName; } +/** + * Generates an exclusion list from mapping config. + * + * @param {Array} mappingConfig - The mapping config. + * [ + * { + * "destKey": "item_code", + * "sourceKeys": [ + * "product_id", + * "sku" + * ] + * }, + * { + * "destKey": "name", + * "sourceKeys": "name" + * } + * ] + * @returns {Array} - The generated exclusion list. + * ["product_id", "sku", "name"] + */ +const generateExclusionList = (mappingConfig) => + mappingConfig.flatMap((mapping) => + Array.isArray(mapping.sourceKeys) ? [...mapping.sourceKeys] : [mapping.sourceKeys], + ); + /** * Extract fileds from message with exclusions * Pass the keys of message for extraction and @@ -1305,10 +1323,10 @@ function getFullName(message) { * ) * ------------------------------------------- * The above call will map the fields other than the - * exlusion list from the given keys to the destination payload + * exclusion list from the given keys to the destination payload * */ -function extractCustomFields(message, destination, keys, exclusionFields) { +function extractCustomFields(message, payload, keys, exclusionFields) { const mappingKeys = []; if (Array.isArray(keys)) { keys.forEach((key) => { @@ -1319,7 +1337,7 @@ function extractCustomFields(message, destination, keys, exclusionFields) { }); mappingKeys.forEach((mappingKey) => { if (!(typeof messageContext[mappingKey] === 'undefined')) { - set(destination, mappingKey, get(messageContext, mappingKey)); + set(payload, mappingKey, get(messageContext, mappingKey)); } }); } @@ -1330,14 +1348,14 @@ function extractCustomFields(message, destination, keys, exclusionFields) { }); mappingKeys.forEach((mappingKey) => { if (!(typeof message[mappingKey] === 'undefined')) { - set(destination, mappingKey, get(message, mappingKey)); + set(payload, mappingKey, get(message, mappingKey)); } }); } else { logger.debug('unable to parse keys'); } - return destination; + return payload; } // Deleting nested properties from objects @@ -1401,6 +1419,11 @@ function getStringValueOfJSON(json) { return output; } +const getTrackingPlanMetadata = (metadata) => ({ + trackingPlanId: metadata.trackingPlanId, + workspaceId: metadata.workspaceId, +}); + const getMetadata = (metadata) => ({ sourceType: metadata.sourceType, destinationType: metadata.destinationType, @@ -1635,7 +1658,7 @@ function getValidDynamicFormConfig( */ const checkInvalidRtTfEvents = (inputs) => { if (!Array.isArray(inputs) || inputs.length === 0) { - const respEvents = getErrorRespEvents(null, 400, 'Invalid event array'); + const respEvents = getErrorRespEvents([], 400, 'Invalid event array'); return [respEvents]; } return []; @@ -1697,11 +1720,6 @@ const handleRtTfSingleEventError = (input, error, reqMetadata) => { * @returns */ const simpleProcessRouterDest = async (inputs, singleTfFunc, reqMetadata, processParams) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } - const respList = await Promise.all( inputs.map(async (input) => { try { @@ -1729,10 +1747,6 @@ const simpleProcessRouterDest = async (inputs, singleTfFunc, reqMetadata, proces * @returns */ const simpleProcessRouterDestSync = async (inputs, singleTfFunc, reqMetadata, processParams) => { - const errorRespEvents = checkInvalidRtTfEvents(inputs); - if (errorRespEvents.length > 0) { - return errorRespEvents; - } const respList = []; // eslint-disable-next-line no-restricted-syntax for (const input of inputs) { @@ -2111,6 +2125,106 @@ const parseConfigArray = (arr, key) => { return arr.map((item) => item[key]); }; +/** + * Finds an existing batch based on metadata JobIds from the provided batch and metadataMap. + * @param {*} batch + * @param {*} metadataMap The map containing metadata items indexed by JobIds. + * @returns + */ +const findExistingBatch = (batch, metadataMap) => { + const existingMetadataItem = batch.metadata.find((metadataItem) => + metadataMap.has(metadataItem.jobId), + ); + return existingMetadataItem ? metadataMap.get(existingMetadataItem.jobId) : null; +}; + +/** + * Removes duplicate metadata within each merged batch object. + * @param {*} mergedBatches An array of merged batch objects. + */ +const removeDuplicateMetadata = (mergedBatches) => { + mergedBatches.forEach((batch) => { + const metadataSet = new Set(); + // eslint-disable-next-line no-param-reassign + batch.metadata = batch.metadata.filter((metadataItem) => { + if (!metadataSet.has(metadataItem.jobId)) { + metadataSet.add(metadataItem.jobId); + return true; + } + return false; + }); + }); +}; + +/** + * Combines batched requests with the same JobIds. + * @param {*} inputBatches The array of batched request objects. + * @returns The combined batched requests with merged JobIds. + * + */ +const combineBatchRequestsWithSameJobIds = (inputBatches) => { + const combineBatches = (batches) => { + const clonedBatches = [...batches]; + const mergedBatches = []; + const metadataMap = new Map(); + + clonedBatches.forEach((batch) => { + const existingBatch = findExistingBatch(batch, metadataMap); + + if (existingBatch) { + // Merge batchedRequests arrays + existingBatch.batchedRequest = [ + ...CommonUtils.toArray(existingBatch.batchedRequest), + ...CommonUtils.toArray(batch.batchedRequest), + ]; + + // Merge metadata + batch.metadata.forEach((metadataItem) => { + if (!metadataMap.has(metadataItem.jobId)) { + metadataMap.set(metadataItem.jobId, existingBatch); + } + existingBatch.metadata.push(metadataItem); + }); + } else { + mergedBatches.push(batch); + batch.metadata.forEach((metadataItem) => { + metadataMap.set(metadataItem.jobId, batch); + }); + } + }); + + // Remove duplicate metadata within each merged object + removeDuplicateMetadata(mergedBatches); + + return mergedBatches; + }; + // We need to run this twice because in first pass some batches might not get merged + // and in second pass they might get merged + // Example: [[{jobID:1}, {jobID:2}], [{jobID:3}], [{jobID:1}, {jobID:3}]] + // 1st pass: [[{jobID:1}, {jobID:2}, {jobID:3}], [{jobID:3}]] + // 2nd pass: [[{jobID:1}, {jobID:2}, {jobID:3}]] + return combineBatches(combineBatches(inputBatches)); +}; + +/** + * This function validates the event and return it as string. + * @param {*} isMandatory The event is a required field. + * @param {*} convertToLowerCase The event should be converted to lower-case. + * @returns {string} Event name converted to string. + */ +const validateEventAndLowerCaseConversion = (event, isMandatory, convertToLowerCase) => { + if (!isDefined(event) || typeof event === 'object' || typeof event === 'boolean') { + throw new InstrumentationError('Event should not be a object, NaN, boolean or undefined'); + } + + // handling 0 as it is a valid value + if (isMandatory && !event && event !== 0) { + throw new InstrumentationError('Event is a required field'); + } + + return convertToLowerCase ? event.toString().toLowerCase() : event.toString(); +}; + // ======================================================================== // EXPORTS // ======================================================================== @@ -2132,6 +2246,7 @@ module.exports = { defaultPutRequestConfig, defaultRequestConfig, deleteObjectProperty, + generateExclusionList, extractCustomFields, flattenJson, flattenMap, @@ -2146,7 +2261,6 @@ module.exports = { getDestinationExternalIDInfoForRetl, getDestinationExternalIDObjectForRetl, getDeviceModel, - getErrorRespEvents, getEventTime, getFieldValueFromMessage, getFirstAndLastName, @@ -2158,6 +2272,7 @@ module.exports = { getMappingConfig, getMetadata, getTransformationMetadata, + getTrackingPlanMetadata, getParsedIP, getStringValueOfJSON, getSuccessRespEvents, @@ -2177,6 +2292,7 @@ module.exports = { isDefinedAndNotNullAndNotEmpty, isEmpty, isNotEmpty, + isNull, isEmptyObject, isHttpStatusRetryable, isHttpStatusSuccess, @@ -2223,4 +2339,8 @@ module.exports = { isNewStatusCodesAccepted, IsGzipSupported, parseConfigArray, + findExistingBatch, + removeDuplicateMetadata, + combineBatchRequestsWithSameJobIds, + validateEventAndLowerCaseConversion, }; diff --git a/src/v0/util/index.test.js b/src/v0/util/index.test.js index a46b55fdd4e..810eb5a9d48 100644 --- a/src/v0/util/index.test.js +++ b/src/v0/util/index.test.js @@ -1,8 +1,14 @@ -const { TAG_NAMES } = require('@rudderstack/integrations-lib'); +const { TAG_NAMES, InstrumentationError } = require('@rudderstack/integrations-lib'); const utilities = require('.'); const { getFuncTestData } = require('../../../test/testHelper'); const { FilteredEventsError } = require('./errorTypes'); -const { hasCircularReference, flattenJson } = require('./index'); +const { + hasCircularReference, + flattenJson, + generateExclusionList, + combineBatchRequestsWithSameJobIds, + validateEventAndLowerCaseConversion, +} = require('./index'); // Names of the utility functions to test const functionNames = [ @@ -31,7 +37,6 @@ describe('Utility Functions Tests', () => { test.each(funcTestData)('$description', async ({ description, input, output }) => { try { let result; - // This is to allow sending multiple arguments to the function if (Array.isArray(input)) { result = utilities[funcName](...input); @@ -125,3 +130,379 @@ describe('tests for generateErrorObject', () => { expect(outputErrObj.statTags).toEqual({}); }); }); + +describe('generateExclusionList', () => { + it('should return an array of excluded keys when given a mapping config', () => { + const mappingConfig = [ + { + destKey: 'item_code', + sourceKeys: ['product_id', 'sku'], + }, + { + destKey: 'name', + sourceKeys: 'name', + }, + ]; + const expected = ['product_id', 'sku', 'name']; + const result = generateExclusionList(mappingConfig); + expect(result).toEqual(expected); + }); + + it('should return an empty array when the mapping config is empty', () => { + const mappingConfig = []; + const expected = []; + const result = generateExclusionList(mappingConfig); + expect(result).toEqual(expected); + }); + + it('should return an array with unique keys when the mapping config has duplicate destination keys', () => { + const mappingConfig = [ + { + destKey: 'item_code', + sourceKeys: ['product_id'], + }, + { + destKey: 'item_code', + sourceKeys: ['sku'], + }, + ]; + const expected = ['product_id', 'sku']; + const result = generateExclusionList(mappingConfig); + expect(result).toEqual(expected); + }); +}); + +describe('Unit test cases for combineBatchRequestsWithSameJobIds', () => { + it('Combine batch request with same jobIds', async () => { + const input = [ + { + batchedRequest: { + endpoint: 'https://endpoint1', + }, + metadata: [ + { + jobId: 1, + }, + { + jobId: 4, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + { + batchedRequest: { + endpoint: 'https://endpoint2', + }, + metadata: [ + { + jobId: 3, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + { + batchedRequest: { + endpoint: 'https://endpoint1', + }, + metadata: [ + { + jobId: 5, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + { + batchedRequest: { + endpoint: 'https://endpoint3', + }, + metadata: [ + { + jobId: 1, + }, + { + jobId: 3, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + { + batchedRequest: { + endpoint: 'https://endpoint2', + }, + metadata: [ + { + jobId: 6, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + ]; + + const expectedOutput = [ + { + batchedRequest: [ + { + endpoint: 'https://endpoint1', + }, + { + endpoint: 'https://endpoint3', + }, + { + endpoint: 'https://endpoint2', + }, + ], + metadata: [ + { + jobId: 1, + }, + { + jobId: 4, + }, + { + jobId: 3, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + { + batchedRequest: { + endpoint: 'https://endpoint1', + }, + metadata: [ + { + jobId: 5, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + { + batchedRequest: { + endpoint: 'https://endpoint2', + }, + metadata: [ + { + jobId: 6, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + ]; + expect(combineBatchRequestsWithSameJobIds(input)).toEqual(expectedOutput); + }); + + it('Each batchRequest contains unique jobIds (no event multiplexing)', async () => { + const input = [ + { + batchedRequest: { + endpoint: 'https://endpoint1', + }, + metadata: [ + { + jobId: 1, + }, + { + jobId: 4, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + { + batchedRequest: { + endpoint: 'https://endpoint3', + }, + metadata: [ + { + jobId: 2, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + { + batchedRequest: { + endpoint: 'https://endpoint3', + }, + metadata: [ + { + jobId: 5, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + ]; + + const expectedOutput = [ + { + batchedRequest: { + endpoint: 'https://endpoint1', + }, + + metadata: [ + { + jobId: 1, + }, + { + jobId: 4, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + { + batchedRequest: { + endpoint: 'https://endpoint3', + }, + metadata: [ + { + jobId: 2, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + { + batchedRequest: { + endpoint: 'https://endpoint3', + }, + metadata: [ + { + jobId: 5, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + key: 'value', + }, + }, + }, + ]; + expect(combineBatchRequestsWithSameJobIds(input)).toEqual(expectedOutput); + }); +}); + +describe('validateEventAndLowerCaseConversion Tests', () => { + it('should return string conversion of number types', () => { + const ev = 0; + expect(validateEventAndLowerCaseConversion(ev, false, true)).toBe('0'); + expect(validateEventAndLowerCaseConversion(ev, true, false)).toBe('0'); + }); + + it('should convert string types to lowercase', () => { + const ev = 'Abc'; + expect(validateEventAndLowerCaseConversion(ev, true, true)).toBe('abc'); + }); + + it('should throw error if event is object type', () => { + expect(() => { + validateEventAndLowerCaseConversion({}, true, true); + }).toThrow(InstrumentationError); + expect(() => { + validateEventAndLowerCaseConversion([1, 2], false, true); + }).toThrow(InstrumentationError); + expect(() => { + validateEventAndLowerCaseConversion({ a: 1 }, true, true); + }).toThrow(InstrumentationError); + }); + + it('should convert string to lowercase', () => { + expect(validateEventAndLowerCaseConversion('Abc', true, true)).toBe('abc'); + expect(validateEventAndLowerCaseConversion('ABC', true, false)).toBe('ABC'); + expect(validateEventAndLowerCaseConversion('abc55', false, true)).toBe('abc55'); + expect(validateEventAndLowerCaseConversion(123, false, true)).toBe('123'); + }); + + it('should throw error for null and undefined', () => { + expect(() => { + validateEventAndLowerCaseConversion(null, true, true); + }).toThrow(InstrumentationError); + expect(() => { + validateEventAndLowerCaseConversion(undefined, false, true); + }).toThrow(InstrumentationError); + }); + + it('should throw error for boolean values', () => { + expect(() => { + validateEventAndLowerCaseConversion(true, true, true); + }).toThrow(InstrumentationError); + expect(() => { + validateEventAndLowerCaseConversion(false, false, false); + }).toThrow(InstrumentationError); + }); +}); diff --git a/src/v0/util/tags.js b/src/v0/util/tags.js index 81e6b9a2a65..dce8c0a338a 100644 --- a/src/v0/util/tags.js +++ b/src/v0/util/tags.js @@ -13,6 +13,7 @@ const TAG_NAMES = { DESTINATION_ID: 'destinationId', WORKSPACE_ID: 'workspaceId', SOURCE_ID: 'sourceId', + STATUS: 'statusCode', }; const MODULES = { diff --git a/src/v1/destinations/algolia/networkHandler.js b/src/v1/destinations/algolia/networkHandler.js new file mode 100644 index 00000000000..de25993fb1b --- /dev/null +++ b/src/v1/destinations/algolia/networkHandler.js @@ -0,0 +1,81 @@ +/* eslint-disable no-restricted-syntax */ +const { TransformerProxyError } = require('../../../v0/util/errorTypes'); +const { prepareProxyRequest, proxyRequest } = require('../../../adapters/network'); +const { isHttpStatusSuccess } = require('../../../v0/util/index'); + +const { + processAxiosResponse, + getDynamicErrorType, +} = require('../../../adapters/utils/networkUtils'); +const tags = require('../../../v0/util/tags'); + +const responseHandler = (responseParams) => { + const { destinationResponse, rudderJobMetadata } = responseParams; + const message = `[ALGOLIA Response V1 Handler] - Request Processed Successfully`; + const responseWithIndividualEvents = []; + const { response, status } = destinationResponse; + + if (isHttpStatusSuccess(status)) { + for (const mData of rudderJobMetadata) { + const proxyOutputObj = { + statusCode: 200, + metadata: mData, + error: 'success', + }; + responseWithIndividualEvents.push(proxyOutputObj); + } + + return { + status, + message, + destinationResponse, + response: responseWithIndividualEvents, + }; + } + + // in case of non 2xx status sending 500 for every event, populate response and update dontBatch to true + const errorMessage = response?.error?.message || response?.message || 'unknown error format'; + for (const metadata of rudderJobMetadata) { + metadata.dontBatch = true; + responseWithIndividualEvents.push({ + statusCode: 500, + metadata, + error: errorMessage, + }); + } + + // At least one event in the batch is invalid. + if (status === 422) { + // sending back 500 for retry + throw new TransformerProxyError( + `ALGOLIA: Error transformer proxy v1 during ALGOLIA response transformation`, + 500, + { + [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(500), + }, + destinationResponse, + '', + responseWithIndividualEvents, + ); + } + + throw new TransformerProxyError( + `ALGOLIA: Error transformer proxy v1 during ALGOLIA response transformation`, + status, + { + [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + }, + destinationResponse, + '', + responseWithIndividualEvents, + ); +}; + +function networkHandler() { + this.prepareProxy = prepareProxyRequest; + this.proxy = proxyRequest; + this.processAxiosResponse = processAxiosResponse; + this.responseHandler = responseHandler; +} + +module.exports = { networkHandler }; diff --git a/src/v1/destinations/campaign_manager/networkHandler.js b/src/v1/destinations/campaign_manager/networkHandler.js index 431cbd69662..300b5f96766 100644 --- a/src/v1/destinations/campaign_manager/networkHandler.js +++ b/src/v1/destinations/campaign_manager/networkHandler.js @@ -34,10 +34,11 @@ function isEventAbortableAndExtractErrMsg(element, proxyOutputObj) { return isAbortable; } -const responseHandler = (destinationResponse) => { +const responseHandler = (responseParams) => { + const { destinationResponse, rudderJobMetadata } = responseParams; const message = `[CAMPAIGN_MANAGER Response V1 Handler] - Request Processed Successfully`; const responseWithIndividualEvents = []; - const { response, status, rudderJobMetadata } = destinationResponse; + const { response, status } = destinationResponse; if (isHttpStatusSuccess(status)) { // check for Partial Event failures and Successes @@ -68,7 +69,7 @@ const responseHandler = (destinationResponse) => { const errorMessage = response.error?.message || 'unknown error format'; for (const metadata of rudderJobMetadata) { responseWithIndividualEvents.push({ - statusCode: 500, + statusCode: status, metadata, error: errorMessage, }); @@ -76,7 +77,7 @@ const responseHandler = (destinationResponse) => { throw new TransformerProxyError( `Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation`, - 500, + status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), }, diff --git a/src/warehouse/index.js b/src/warehouse/index.js index 3305a52762f..b3d1c5e4bc7 100644 --- a/src/warehouse/index.js +++ b/src/warehouse/index.js @@ -23,7 +23,7 @@ const whPageColumnMappingRules = require('./config/WHPageConfig.js'); const whScreenColumnMappingRules = require('./config/WHScreenConfig.js'); const whGroupColumnMappingRules = require('./config/WHGroupConfig.js'); const whAliasColumnMappingRules = require('./config/WHAliasConfig.js'); -const {isDataLakeProvider, isBlank} = require('./config/helpers'); +const { isDataLakeProvider, isBlank } = require('./config/helpers'); const { InstrumentationError } = require('@rudderstack/integrations-lib'); const whExtractEventTableColumnMappingRules = require('./config/WHExtractEventTableConfig.js'); diff --git a/src/warehouse/util.js b/src/warehouse/util.js index 11d72bfbfd5..b4b22721fd3 100644 --- a/src/warehouse/util.js +++ b/src/warehouse/util.js @@ -4,7 +4,7 @@ const get = require('get-value'); const v0 = require('./v0/util'); const v1 = require('./v1/util'); const { PlatformError, InstrumentationError } = require('@rudderstack/integrations-lib'); -const {isBlank} = require('./config/helpers'); +const { isBlank } = require('./config/helpers'); const minTimeInMs = Date.parse('0001-01-01T00:00:00Z'); const maxTimeInMs = Date.parse('9999-12-31T23:59:59.999Z'); diff --git a/test/__mocks__/data/sources/shopify/response.json b/test/__mocks__/data/sources/shopify/response.json index ead25067e63..4eef747b940 100644 --- a/test/__mocks__/data/sources/shopify/response.json +++ b/test/__mocks__/data/sources/shopify/response.json @@ -31,4 +31,4 @@ "shopify_test_set_redis_error": { "itemsHash": "EMPTY" } -} \ No newline at end of file +} diff --git a/test/__tests__/auth0_source.test.js b/test/__tests__/auth0_source.test.js index c67db693e34..75d103d46fd 100644 --- a/test/__tests__/auth0_source.test.js +++ b/test/__tests__/auth0_source.test.js @@ -17,7 +17,7 @@ testData.forEach((data, index) => { const output = transformer.process(data.input); expect(output).toEqual(data.output); } catch (error) { - expect(error.message).toEqual(data.output.message); + expect(error.message).toEqual(data.output.error); } }); }); diff --git a/test/__tests__/data/auth0_source.json b/test/__tests__/data/auth0_source.json index d47d7e0180a..e3190bd683c 100644 --- a/test/__tests__/data/auth0_source.json +++ b/test/__tests__/data/auth0_source.json @@ -1116,5 +1116,106 @@ "originalTimestamp": "2022-10-31T06:15:25.196Z" } ] + }, + { + "description": "Missing userId", + "input": { + "log_id": "90020221031055712103169676686005480714681762668315934738", + "data": { + "date": "2022-10-31T05:57:06.859Z", + "type": "ss", + "description": "", + "connection": "Username-Password-Authentication", + "connection_id": "con_djwCjiwyID0vZy1S", + "client_id": "vQcJNDTxsM1W72eHFonRJdzyOvawlwIt", + "client_name": "All Applications", + "ip": "35.166.202.113", + "user_agent": "unknown", + "details": { + "body": { + "email": "testRudderlabs+21@gmail.com", + "tenant": "dev-cu4jy2zgao6yx15x", + "password": "dummyPassword", + "client_id": "vQcJNDTxsM1W72eHFonRJdzyOvawlwIt", + "connection": "Username-Password-Authentication" + } + }, + "user_id": "", + "user_name": "testRudderlabs+21@gmail.com", + "strategy": "auth0", + "strategy_type": "database", + "log_id": "90020221031055712103169676686005480714681762668315934738" + } + }, + "output": { + "statusCode": 400, + "error": "UserId is not present", + "statTags": { + "errorCategory": "dataValidation", + "errorType": "instrumentation", + "module": "source", + "implementation": "native", + "destinationId": "Non determinable", + "workspaceId": "Non determinable" + } + } + }, + { + "description": "UserId is missing for all the requests in a batch", + "input": [ + { + "log_id": "90020221031055712103169676686005480714681762668315934738", + "data": { + "date": "2022-10-31T05:57:06.859Z", + "type": "ss", + "description": "", + "connection": "Username-Password-Authentication", + "connection_id": "con_djwCjiwyID0vZy1S", + "client_id": "vQcJNDTxsM1W72eHFonRJdzyOvawlwIt", + "client_name": "All Applications", + "ip": "35.166.202.113", + "user_agent": "unknown", + "details": { + "body": { + "email": "testRudderlabs+21@gmail.com", + "tenant": "dev-cu4jy2zgao6yx15x", + "password": "dummyPassword", + "client_id": "vQcJNDTxsM1W72eHFonRJdzyOvawlwIt", + "connection": "Username-Password-Authentication" + } + }, + "user_id": "", + "user_name": "testRudderlabs+21@gmail.com", + "strategy": "auth0", + "strategy_type": "database", + "log_id": "90020221031055712103169676686005480714681762668315934738" + } + }, + { + "log_id": "90020221031055712103169676686007898566320991926665347090", + "data": { + "date": "2022-10-31T05:57:06.874Z", + "type": "sapi", + "description": "Create a User", + "client_id": "vQcJNDTxsM1W72eHFonRJdzyOvawlwIt", + "client_name": "", + "ip": "35.166.202.113", + "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36", + "log_id": "90020221031055712103169676686007898566320991926665347090" + } + } + ], + "output": { + "statusCode": 400, + "error": "UserId is not present", + "statTags": { + "errorCategory": "dataValidation", + "errorType": "instrumentation", + "module": "source", + "implementation": "native", + "destinationId": "Non determinable", + "workspaceId": "Non determinable" + } + } } ] diff --git a/test/__tests__/data/customerio_source_input.json b/test/__tests__/data/customerio_source_input.json index 5b825d6a00d..769c1b7fd3c 100644 --- a/test/__tests__/data/customerio_source_input.json +++ b/test/__tests__/data/customerio_source_input.json @@ -111,9 +111,7 @@ "customer_id": "user-123", "delivery_id": "RAECAAFwnUSneIa0ZXkmq8EdkAM==", "headers": { - "Custom-Header": [ - "custom-value" - ] + "Custom-Header": ["custom-value"] }, "identifiers": { "id": "user-123" @@ -389,4 +387,4 @@ "metric": "delivered", "timestamp": 1585751830 } -] \ No newline at end of file +] diff --git a/test/__tests__/data/customerio_source_output.json b/test/__tests__/data/customerio_source_output.json index 24b964d01b4..52df88e833f 100644 --- a/test/__tests__/data/customerio_source_output.json +++ b/test/__tests__/data/customerio_source_output.json @@ -648,4 +648,4 @@ "originalTimestamp": "2020-04-01T14:37:10.000Z", "sentAt": "2020-04-01T14:37:10.000Z" } -] \ No newline at end of file +] diff --git a/test/__tests__/data/formsort_source.json b/test/__tests__/data/formsort_source.json index a12d84a98a3..d94cfd677bd 100644 --- a/test/__tests__/data/formsort_source.json +++ b/test/__tests__/data/formsort_source.json @@ -1,94 +1,94 @@ [ - { - "description": "when we receive finalized as false", - "input": { - "answers": { - "yes": true, - "enter_email": "test@user.com", - "enter_name": "2022-11-17", - "yes_or_no": false - }, - "responder_uuid": "66a8e5bb-67e1-47ec-b55f-a26fd4be2dc7", - "flow_label": "new-flow-2022-11-25", - "variant_label": "main", - "variant_uuid": "0828efa7-7215-4e7d-a7ab-6c1079010cea", - "finalized": false, - "created_at": "2022-11-25T14:41:22+00:00" + { + "description": "when we receive finalized as false", + "input": { + "answers": { + "yes": true, + "enter_email": "test@user.com", + "enter_name": "2022-11-17", + "yes_or_no": false + }, + "responder_uuid": "66a8e5bb-67e1-47ec-b55f-a26fd4be2dc7", + "flow_label": "new-flow-2022-11-25", + "variant_label": "main", + "variant_uuid": "0828efa7-7215-4e7d-a7ab-6c1079010cea", + "finalized": false, + "created_at": "2022-11-25T14:41:22+00:00" + }, + "output": { + "context": { + "library": { + "name": "unknown", + "version": "unknown" + }, + "integration": { + "name": "Formsort" + }, + "page": { + "title": "new-flow-2022-11-25" }, - "output": { - "context": { - "library": { - "name": "unknown", - "version": "unknown" - }, - "integration": { - "name": "Formsort" - }, - "page": { - "title": "new-flow-2022-11-25" - }, - "variantLabel": "main", - "variantUuid": "0828efa7-7215-4e7d-a7ab-6c1079010cea" - }, - "integrations": { - "Formsort": false - }, - "type": "track", - "userId": "66a8e5bb-67e1-47ec-b55f-a26fd4be2dc7", - "originalTimestamp": "2022-11-25T14:41:22+00:00", - "properties": { - "yes": true, - "enter_email": "test@user.com", - "enter_name": "2022-11-17", - "yes_or_no": false - }, - "event": "FlowLoaded" - } + "variantLabel": "main", + "variantUuid": "0828efa7-7215-4e7d-a7ab-6c1079010cea" + }, + "integrations": { + "Formsort": false + }, + "type": "track", + "userId": "66a8e5bb-67e1-47ec-b55f-a26fd4be2dc7", + "originalTimestamp": "2022-11-25T14:41:22+00:00", + "properties": { + "yes": true, + "enter_email": "test@user.com", + "enter_name": "2022-11-17", + "yes_or_no": false + }, + "event": "FlowLoaded" + } + }, + { + "description": "when we receive finalized as true", + "input": { + "answers": { + "yes": true, + "enter_email": "test@user.com", + "enter_name": "2022-11-17", + "yes_or_no": false + }, + "responder_uuid": "66a8e5bb-67e1-47ec-b55f-a26fd4be2dc7", + "flow_label": "new-flow-2022-11-25", + "variant_label": "main", + "variant_uuid": "0828efa7-7215-4e7d-a7ab-6c1079010cea", + "finalized": true, + "created_at": "2022-11-25T14:41:22+00:00" }, - { - "description": "when we receive finalized as true", - "input": { - "answers": { - "yes": true, - "enter_email": "test@user.com", - "enter_name": "2022-11-17", - "yes_or_no": false - }, - "responder_uuid": "66a8e5bb-67e1-47ec-b55f-a26fd4be2dc7", - "flow_label": "new-flow-2022-11-25", - "variant_label": "main", - "variant_uuid": "0828efa7-7215-4e7d-a7ab-6c1079010cea", - "finalized": true, - "created_at": "2022-11-25T14:41:22+00:00" + "output": { + "context": { + "library": { + "name": "unknown", + "version": "unknown" + }, + "integration": { + "name": "Formsort" + }, + "page": { + "title": "new-flow-2022-11-25" }, - "output": { - "context": { - "library": { - "name": "unknown", - "version": "unknown" - }, - "integration": { - "name": "Formsort" - }, - "page": { - "title": "new-flow-2022-11-25" - }, - "variantLabel": "main", - "variantUuid": "0828efa7-7215-4e7d-a7ab-6c1079010cea" - }, - "integrations": { - "Formsort": false - }, - "type": "track", - "userId": "66a8e5bb-67e1-47ec-b55f-a26fd4be2dc7", - "originalTimestamp": "2022-11-25T14:41:22+00:00", - "properties": { - "yes": true, - "enter_email": "test@user.com", - "enter_name": "2022-11-17", - "yes_or_no": false - }, - "event": "FlowFinalized" - } + "variantLabel": "main", + "variantUuid": "0828efa7-7215-4e7d-a7ab-6c1079010cea" + }, + "integrations": { + "Formsort": false + }, + "type": "track", + "userId": "66a8e5bb-67e1-47ec-b55f-a26fd4be2dc7", + "originalTimestamp": "2022-11-25T14:41:22+00:00", + "properties": { + "yes": true, + "enter_email": "test@user.com", + "enter_name": "2022-11-17", + "yes_or_no": false + }, + "event": "FlowFinalized" } -] \ No newline at end of file + } +] diff --git a/test/__tests__/data/proxy_input.json b/test/__tests__/data/proxy_input.json index a647238f9f8..0d7ff24ab7d 100644 --- a/test/__tests__/data/proxy_input.json +++ b/test/__tests__/data/proxy_input.json @@ -263,4 +263,4 @@ "destination": "any" } } -] \ No newline at end of file +] diff --git a/test/__tests__/data/shopify.json b/test/__tests__/data/shopify.json index 0153df4d26a..48ca8c75a01 100644 --- a/test/__tests__/data/shopify.json +++ b/test/__tests__/data/shopify.json @@ -4,9 +4,7 @@ "input": { "id": "shopify_test3", "query_parameters": { - "topic": [ - "carts_create" - ] + "topic": ["carts_create"] }, "token": "shopify_test3", "line_items": [], @@ -33,12 +31,8 @@ "description": "Invalid topic", "input": { "query_parameters": { - "signature": [ - "rudderstack" - ], - "writeKey": [ - "sample-write-key" - ] + "signature": ["rudderstack"], + "writeKey": ["sample-write-key"] } }, "output": { @@ -50,12 +44,8 @@ "input": { "query_parameters": { "topic": [], - "signature": [ - "rudderstack" - ], - "writeKey": [ - "sample-write-key" - ] + "signature": ["rudderstack"], + "writeKey": ["sample-write-key"] } }, "output": { @@ -66,15 +56,9 @@ "description": "Unsupported Event Type", "input": { "query_parameters": { - "topic": [ - "random_event" - ], - "signature": [ - "rudderstack" - ], - "writeKey": [ - "sample-write-key" - ] + "topic": ["random_event"], + "signature": ["rudderstack"], + "writeKey": ["sample-write-key"] } }, "output": { @@ -89,15 +73,9 @@ "description": "Identify Call for customers create event", "input": { "query_parameters": { - "topic": [ - "customers_create" - ], - "signature": [ - "rudderstack" - ], - "writeKey": [ - "sample-write-key" - ] + "topic": ["customers_create"], + "signature": ["rudderstack"], + "writeKey": ["sample-write-key"] }, "id": 5747017285820, "email": "anuraj@rudderstack.com", @@ -256,15 +234,9 @@ "description": "Unsupported checkout event", "input": { "query_parameters": { - "topic": [ - "checkout_delete" - ], - "writeKey": [ - "sample-write-key" - ], - "signature": [ - "rudderstack" - ] + "topic": ["checkout_delete"], + "writeKey": ["sample-write-key"], + "signature": ["rudderstack"] }, "admin_graphql_api_id": "gid://shopify/Fulfillment/4124667937024", "created_at": "2022-01-05T18:13:02+05:30", @@ -292,13 +264,9 @@ "status": "success", "tracking_company": "Amazon Logistics UK", "tracking_number": "Sample001test", - "tracking_numbers": [ - "Sample001test" - ], + "tracking_numbers": ["Sample001test"], "tracking_url": "https://www.amazon.co.uk/gp/help/customer/display.html?nodeId=201910530", - "tracking_urls": [ - "https://www.amazon.co.uk/gp/help/customer/display.html?nodeId=201910530" - ], + "tracking_urls": ["https://www.amazon.co.uk/gp/help/customer/display.html?nodeId=201910530"], "updated_at": "2022-01-05T18:16:48+05:30" }, "output": { @@ -313,15 +281,9 @@ "description": "Track Call -> Fullfillments updated event", "input": { "query_parameters": { - "topic": [ - "fulfillments_update" - ], - "writeKey": [ - "sample-write-key" - ], - "signature": [ - "rudderstack" - ] + "topic": ["fulfillments_update"], + "writeKey": ["sample-write-key"], + "signature": ["rudderstack"] }, "shipping_address": { "address1": "11 Rani Sankari Lane Patuapara Bhowanipore" @@ -420,13 +382,9 @@ "status": "success", "tracking_company": "Amazon Logistics UK", "tracking_number": "Sample001test", - "tracking_numbers": [ - "Sample001test" - ], + "tracking_numbers": ["Sample001test"], "tracking_url": "https://www.amazon.co.uk/gp/help/customer/display.html?nodeId=201910530", - "tracking_urls": [ - "https://www.amazon.co.uk/gp/help/customer/display.html?nodeId=201910530" - ], + "tracking_urls": ["https://www.amazon.co.uk/gp/help/customer/display.html?nodeId=201910530"], "updated_at": "2022-01-05T18:16:48+05:30" }, "output": { @@ -462,9 +420,7 @@ "status": "success", "tracking_company": "Amazon Logistics UK", "tracking_number": "Sample001test", - "tracking_numbers": [ - "Sample001test" - ], + "tracking_numbers": ["Sample001test"], "tracking_url": "https://www.amazon.co.uk/gp/help/customer/display.html?nodeId=201910530", "tracking_urls": [ "https://www.amazon.co.uk/gp/help/customer/display.html?nodeId=201910530" @@ -556,4 +512,4 @@ } } } -] \ No newline at end of file +] diff --git a/test/apitests/data_scenarios/destination/batch/failure_batch.json b/test/apitests/data_scenarios/destination/batch/failure_batch.json index 8063bc74a12..6352ca1a11f 100644 --- a/test/apitests/data_scenarios/destination/batch/failure_batch.json +++ b/test/apitests/data_scenarios/destination/batch/failure_batch.json @@ -1051,125 +1051,314 @@ }, "output": [ { - "metadata": { - "userId": "<<>>testUser<<>>testUser", - "jobId": 2, - "sourceId": "27O0bmEEx3GgfmEhZHUcPwJQVWC", - "destinationId": "2JK3ACpBjq9AmvUbxR1u2pDPSYR", - "attemptNum": 0, - "receivedAt": "2022-12-24T17:29:00.699+05:30", - "createdAt": "2022-12-24T11:59:03.125Z", - "firstAttemptedAt": "", - "transformAt": "processor", - "workspaceId": "27O0bhB6p5ehfOWeeZlOSsSDTLg", - "secret": null, - "jobsT": { - "UUID": "aaa8b7c4-2600-478b-b275-01740e1ef50c", - "JobID": 2, - "UserID": "<<>>testUser<<>>testUser", - "CreatedAt": "2022-12-24T11:59:03.125515Z", - "ExpireAt": "2022-12-24T11:59:03.125515Z", - "CustomVal": "AM", - "EventCount": 1, - "EventPayload": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "events": [ - { - "ip": "[::1]", - "time": 1671883143047, - "library": "rudderstack", - "user_id": "testUser", - "device_id": "anon-id", - "insert_id": "14642496-9a12-4db7-b0f2-9a336cf6cea9", - "event_type": "Product Added", - "session_id": -1, - "user_properties": { - "email": "test.c97@gmail.com", - "phone": "+919876543210", - "gender": "Male", - "lastName": "Rudderlabs", - "firstName": "test" - }, - "event_properties": { - "sku": "F15", - "url": "https://www.website.com/product/path", - "name": "Game", - "brand": "Gamepro", - "price": 13.49, - "coupon": "DISC21", - "variant": "111", - "category": "Games", - "position": 1, - "quantity": 11, - "image_url": "https://www.website.com/product/path.png", - "product_id": "123" + "metadata": [ + { + "userId": "<<>>testUser<<>>testUser", + "jobId": 2, + "sourceId": "27O0bmEEx3GgfmEhZHUcPwJQVWC", + "destinationId": "2JK3ACpBjq9AmvUbxR1u2pDPSYR", + "attemptNum": 0, + "receivedAt": "2022-12-24T17:29:00.699+05:30", + "createdAt": "2022-12-24T11:59:03.125Z", + "firstAttemptedAt": "", + "transformAt": "processor", + "workspaceId": "27O0bhB6p5ehfOWeeZlOSsSDTLg", + "secret": null, + "jobsT": { + "UUID": "aaa8b7c4-2600-478b-b275-01740e1ef50c", + "JobID": 2, + "UserID": "<<>>testUser<<>>testUser", + "CreatedAt": "2022-12-24T11:59:03.125515Z", + "ExpireAt": "2022-12-24T11:59:03.125515Z", + "CustomVal": "AM", + "EventCount": 1, + "EventPayload": { + "body": { + "XML": {}, + "FORM": {}, + "JSON": { + "events": [ + { + "ip": "[::1]", + "time": 1671883143047, + "library": "rudderstack", + "user_id": "testUser", + "device_id": "anon-id", + "insert_id": "14642496-9a12-4db7-b0f2-9a336cf6cea9", + "event_type": "Product Added", + "session_id": -1, + "user_properties": { + "email": "test.c97@gmail.com", + "phone": "+919876543210", + "gender": "Male", + "lastName": "Rudderlabs", + "firstName": "test" + }, + "event_properties": { + "sku": "F15", + "url": "https://www.website.com/product/path", + "name": "Game", + "brand": "Gamepro", + "price": 13.49, + "coupon": "DISC21", + "variant": "111", + "category": "Games", + "position": 1, + "quantity": 11, + "image_url": "https://www.website.com/product/path.png", + "product_id": "123" + } } + ], + "api_key": "dummyApiKey", + "options": { + "min_id_length": 1 } - ], - "api_key": "dummyApiKey", - "options": { - "min_id_length": 1 - } + }, + "JSON_ARRAY": {} }, - "JSON_ARRAY": {} + "type": "REST", + "files": {}, + "method": "POST", + "params": {}, + "userId": "anon-id", + "headers": { + "Content-Type": "application/json" + }, + "version": "1", + "endpoint": "https://api2.amplitude.com/2/httpapi" }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "userId": "anon-id", - "headers": { - "Content-Type": "application/json" + "PayloadSize": 1133, + "LastJobStatus": { + "JobID": 0, + "JobState": "", + "AttemptNum": 0, + "ExecTime": "0001-01-01T00:00:00Z", + "RetryTime": "0001-01-01T00:00:00Z", + "ErrorCode": "", + "ErrorResponse": null, + "Parameters": null, + "WorkspaceId": "" }, - "version": "1", - "endpoint": "https://api2.amplitude.com/2/httpapi" - }, - "PayloadSize": 1133, - "LastJobStatus": { - "JobID": 0, - "JobState": "", - "AttemptNum": 0, - "ExecTime": "0001-01-01T00:00:00Z", - "RetryTime": "0001-01-01T00:00:00Z", - "ErrorCode": "", - "ErrorResponse": null, - "Parameters": null, - "WorkspaceId": "" - }, - "Parameters": { - "record_id": null, - "source_id": "27O0bmEEx3GgfmEhZHUcPwJQVWC", - "event_name": "Product Added", - "event_type": "track", - "message_id": "14642496-9a12-4db7-b0f2-9a336cf6cea9", - "received_at": "2022-12-24T17:29:00.699+05:30", - "workspaceId": "27O0bhB6p5ehfOWeeZlOSsSDTLg", - "transform_at": "processor", - "source_job_id": "", - "destination_id": "2JK3ACpBjq9AmvUbxR1u2pDPSYR", - "gateway_job_id": 1, - "source_task_id": "", - "source_batch_id": "", - "source_category": "", - "source_job_run_id": "", - "source_task_run_id": "", - "source_definition_id": "1b6gJdqOPOCadT3cddw8eidV591", - "destination_definition_id": "" + "Parameters": { + "record_id": null, + "source_id": "27O0bmEEx3GgfmEhZHUcPwJQVWC", + "event_name": "Product Added", + "event_type": "track", + "message_id": "14642496-9a12-4db7-b0f2-9a336cf6cea9", + "received_at": "2022-12-24T17:29:00.699+05:30", + "workspaceId": "27O0bhB6p5ehfOWeeZlOSsSDTLg", + "transform_at": "processor", + "source_job_id": "", + "destination_id": "2JK3ACpBjq9AmvUbxR1u2pDPSYR", + "gateway_job_id": 1, + "source_task_id": "", + "source_batch_id": "", + "source_category": "", + "source_job_run_id": "", + "source_task_run_id": "", + "source_definition_id": "1b6gJdqOPOCadT3cddw8eidV591", + "destination_definition_id": "" + }, + "WorkspaceId": "27O0bhB6p5ehfOWeeZlOSsSDTLg" }, - "WorkspaceId": "27O0bhB6p5ehfOWeeZlOSsSDTLg" - }, - "workerAssignedTime": "2022-12-24T17:29:04.051596+05:30" - }, + "workerAssignedTime": "2022-12-24T17:29:04.051596+05:30" + } + ], "batched": false, "statusCode": 400, "statTags": { "errorCategory": "dataValidation", "errorType": "instrumentation" }, - "error": "Both userId and deviceId cannot be undefined" + "error": "Both userId and deviceId cannot be undefined", + "destination": { + "ID": "2JK3ACpBjq9AmvUbxR1u2pDPSYR", + "Name": "Amplitude-2", + "DestinationDefinition": { + "ID": "1QGzO4fWSyq3lsyFHf4eQAMDSr9", + "Name": "AM", + "DisplayName": "Amplitude", + "Config": { + "destConfig": { + "android": [ + "eventUploadPeriodMillis", + "eventUploadThreshold", + "useNativeSDK", + "enableLocationListening", + "trackSessionEvents", + "useAdvertisingIdForDeviceId" + ], + "defaultConfig": [ + "apiKey", + "groupTypeTrait", + "groupValueTrait", + "trackAllPages", + "trackCategorizedPages", + "trackNamedPages", + "traitsToIncrement", + "traitsToSetOnce", + "traitsToAppend", + "traitsToPrepend", + "trackProductsOnce", + "trackRevenuePerProduct", + "versionName", + "apiSecret", + "residencyServer", + "blacklistedEvents", + "whitelistedEvents", + "eventFilteringOption", + "mapDeviceBrand" + ], + "flutter": [ + "eventUploadPeriodMillis", + "eventUploadThreshold", + "useNativeSDK", + "enableLocationListening", + "trackSessionEvents", + "useAdvertisingIdForDeviceId", + "useIdfaAsDeviceId" + ], + "ios": [ + "eventUploadPeriodMillis", + "eventUploadThreshold", + "useNativeSDK", + "trackSessionEvents", + "useIdfaAsDeviceId" + ], + "reactnative": [ + "eventUploadPeriodMillis", + "eventUploadThreshold", + "useNativeSDK", + "enableLocationListening", + "trackSessionEvents", + "useAdvertisingIdForDeviceId", + "useIdfaAsDeviceId" + ], + "web": [ + "useNativeSDK", + "preferAnonymousIdForDeviceId", + "deviceIdFromUrlParam", + "forceHttps", + "trackGclid", + "trackReferrer", + "saveParamsReferrerOncePerSession", + "trackUtmProperties", + "unsetParamsReferrerOnNewSession", + "batchEvents", + "eventUploadPeriodMillis", + "eventUploadThreshold", + "oneTrustCookieCategories" + ] + }, + "excludeKeys": [], + "includeKeys": [ + "apiKey", + "groupTypeTrait", + "groupValueTrait", + "trackAllPages", + "trackCategorizedPages", + "trackNamedPages", + "traitsToIncrement", + "traitsToSetOnce", + "traitsToAppend", + "traitsToPrepend", + "trackProductsOnce", + "trackRevenuePerProduct", + "preferAnonymousIdForDeviceId", + "deviceIdFromUrlParam", + "forceHttps", + "trackGclid", + "trackReferrer", + "saveParamsReferrerOncePerSession", + "trackUtmProperties", + "unsetParamsReferrerOnNewSession", + "batchEvents", + "eventUploadPeriodMillis", + "eventUploadThreshold", + "versionName", + "enableLocationListening", + "useAdvertisingIdForDeviceId", + "trackSessionEvents", + "useIdfaAsDeviceId", + "blacklistedEvents", + "whitelistedEvents", + "oneTrustCookieCategories", + "eventFilteringOption", + "mapDeviceBrand" + ], + "saveDestinationResponse": true, + "secretKeys": ["apiKey", "apiSecret"], + "supportedMessageTypes": ["alias", "group", "identify", "page", "screen", "track"], + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "warehouse", + "reactnative", + "flutter", + "cordova" + ], + "supportsVisualMapper": true, + "transformAt": "processor", + "transformAtV1": "processor" + }, + "ResponseRules": null + }, + "Config": { + "apiKey": "dummyApiKey", + "apiSecret": "", + "blacklistedEvents": [ + { + "eventName": "" + } + ], + "eventFilteringOption": "disable", + "groupTypeTrait": "", + "groupValueTrait": "", + "mapDeviceBrand": false, + "residencyServer": "standard", + "trackAllPages": false, + "trackCategorizedPages": true, + "trackNamedPages": true, + "trackProductsOnce": false, + "trackRevenuePerProduct": false, + "traitsToAppend": [ + { + "traits": "" + } + ], + "traitsToIncrement": [ + { + "traits": "" + } + ], + "traitsToPrepend": [ + { + "traits": "" + } + ], + "traitsToSetOnce": [ + { + "traits": "" + } + ], + "versionName": "", + "whitelistedEvents": [ + { + "eventName": "" + } + ] + }, + "Enabled": true, + "WorkspaceID": "27O0bhB6p5ehfOWeeZlOSsSDTLg", + "Transformations": [], + "IsProcessorEnabled": true, + "RevisionID": "2JMKUgZX3b8sbtDSZrkUB7okeOY" + } }, { "batchedRequest": { diff --git a/test/apitests/service.api.test.ts b/test/apitests/service.api.test.ts index cbc2abb3b25..266619b6ac2 100644 --- a/test/apitests/service.api.test.ts +++ b/test/apitests/service.api.test.ts @@ -6,6 +6,8 @@ import Koa from 'koa'; import bodyParser from 'koa-bodyparser'; import setValue from 'set-value'; import { applicationRoutes } from '../../src/routes'; +import { FetchHandler } from '../../src/helpers/fetchHandlers'; +import networkHandlerFactory from '../../src/adapters/networkHandlerFactory'; let server: any; const OLD_ENV = process.env; @@ -30,6 +32,10 @@ afterAll(async () => { await httpTerminator.terminate(); }); +afterEach(() => { + jest.clearAllMocks(); +}); + const getDataFromPath = (pathInput) => { const testDataFile = fs.readFileSync(path.resolve(__dirname, pathInput)); return JSON.parse(testDataFile.toString()); @@ -76,6 +82,332 @@ describe('features tests', () => { }); }); +describe('Api tests with a mock source/destination', () => { + test('(mock destination) Processor transformation scenario with single event', async () => { + const destType = '__rudder_test__'; + const version = 'v0'; + + const getInputData = () => { + return [ + { message: { a: 'b1' }, destination: {}, metadata: { jobId: 1 } }, + { message: { a: 'b2' }, destination: {}, metadata: { jobId: 2 } }, + ]; + }; + const tevent = { version: 'v0', endpoint: 'http://abc' }; + + const getDestHandlerSpy = jest + .spyOn(FetchHandler, 'getDestHandler') + .mockImplementationOnce((d, v) => { + expect(d).toEqual(destType); + expect(v).toEqual(version); + return { + process: jest.fn(() => { + return tevent; + }), + }; + }); + + const expected = [ + { + output: { version: 'v0', endpoint: 'http://abc', userId: '' }, + metadata: { jobId: 1 }, + statusCode: 200, + }, + { + output: { version: 'v0', endpoint: 'http://abc', userId: '' }, + metadata: { jobId: 2 }, + statusCode: 200, + }, + ]; + + const response = await request(server) + .post('/v0/destinations/__rudder_test__') + .set('Accept', 'application/json') + .send(getInputData()); + + expect(response.status).toEqual(200); + expect(JSON.parse(response.text)).toEqual(expected); + expect(getDestHandlerSpy).toHaveBeenCalledTimes(1); + }); + + test('(mock destination) Batching', async () => { + const destType = '__rudder_test__'; + const version = 'v0'; + + const getBatchInputData = () => { + return { + input: [ + { message: { a: 'b1' }, destination: {}, metadata: { jobId: 1 } }, + { message: { a: 'b2' }, destination: {}, metadata: { jobId: 2 } }, + ], + destType: destType, + }; + }; + const tevent = [ + { + batchedRequest: { version: 'v0', endpoint: 'http://abc' }, + metadata: [{ jobId: 1 }, { jobId: 2 }], + statusCode: 200, + }, + ]; + + const getDestHandlerSpy = jest + .spyOn(FetchHandler, 'getDestHandler') + .mockImplementationOnce((d, v) => { + expect(d).toEqual(destType); + expect(v).toEqual(version); + return { + batch: jest.fn(() => { + return tevent; + }), + }; + }); + + const response = await request(server) + .post('/batch') + .set('Accept', 'application/json') + .send(getBatchInputData()); + + expect(response.status).toEqual(200); + expect(JSON.parse(response.text)).toEqual(tevent); + expect(getDestHandlerSpy).toHaveBeenCalledTimes(1); + }); + + test('(mock destination) Router transformation', async () => { + const destType = '__rudder_test__'; + const version = 'v0'; + + const getRouterTransformInputData = () => { + return { + input: [ + { message: { a: 'b1' }, destination: {}, metadata: { jobId: 1 } }, + { message: { a: 'b2' }, destination: {}, metadata: { jobId: 2 } }, + ], + destType: destType, + }; + }; + const tevent = [ + { + batchedRequest: { version: 'v0', endpoint: 'http://abc' }, + metadata: [{ jobId: 1 }, { jobId: 2 }], + statusCode: 200, + }, + ]; + + const getDestHandlerSpy = jest + .spyOn(FetchHandler, 'getDestHandler') + .mockImplementationOnce((d, v) => { + expect(d).toEqual(destType); + expect(v).toEqual(version); + return { + processRouterDest: jest.fn(() => { + return tevent; + }), + }; + }); + + const response = await request(server) + .post('/routerTransform') + .set('Accept', 'application/json') + .send(getRouterTransformInputData()); + + expect(response.status).toEqual(200); + expect(JSON.parse(response.text)).toEqual({ output: tevent }); + expect(getDestHandlerSpy).toHaveBeenCalledTimes(1); + }); + + test('(mock destination) v0 proxy', async () => { + const destType = '__rudder_test__'; + const version = 'v0'; + + const getData = () => { + return { + body: { JSON: { a: 'b' } }, + metadata: { a1: 'b1' }, + destinationConfig: { a2: 'b2' }, + }; + }; + + const proxyResponse = { success: true, response: { response: 'response', code: 200 } }; + + const mockNetworkHandler = { + proxy: jest.fn((r, d) => { + expect(r).toEqual(getData()); + expect(d).toEqual(destType); + return proxyResponse; + }), + processAxiosResponse: jest.fn((r) => { + expect(r).toEqual(proxyResponse); + return { response: 'response', status: 200 }; + }), + responseHandler: jest.fn((o, d) => { + expect(o.destinationResponse).toEqual({ response: 'response', status: 200 }); + expect(o.rudderJobMetadata).toEqual({ a1: 'b1' }); + expect(o.destType).toEqual(destType); + return { status: 200, message: 'response', destinationResponse: 'response' }; + }), + }; + + const getNetworkHandlerSpy = jest + .spyOn(networkHandlerFactory, 'getNetworkHandler') + .mockImplementationOnce((d, v) => { + expect(d).toEqual(destType); + expect(v).toEqual(version); + return { + networkHandler: mockNetworkHandler, + handlerVersion: version, + }; + }); + + const response = await request(server) + .post('/v0/destinations/__rudder_test__/proxy') + .set('Accept', 'application/json') + .send(getData()); + + expect(response.status).toEqual(200); + expect(JSON.parse(response.text)).toEqual({ + output: { status: 200, message: 'response', destinationResponse: 'response' }, + }); + expect(getNetworkHandlerSpy).toHaveBeenCalledTimes(1); + }); + + test('(mock destination) v1 proxy', async () => { + const destType = '__rudder_test__'; + const version = 'v1'; + + const getData = () => { + return { + body: { JSON: { a: 'b' } }, + metadata: [{ a1: 'b1' }], + destinationConfig: { a2: 'b2' }, + }; + }; + + const proxyResponse = { success: true, response: { response: 'response', code: 200 } }; + const respHandlerResponse = { + status: 200, + message: 'response', + destinationResponse: 'response', + response: [{ statusCode: 200, metadata: { a1: 'b1' } }], + }; + + const mockNetworkHandler = { + proxy: jest.fn((r, d) => { + expect(r).toEqual(getData()); + expect(d).toEqual(destType); + return proxyResponse; + }), + processAxiosResponse: jest.fn((r) => { + expect(r).toEqual(proxyResponse); + return { response: 'response', status: 200 }; + }), + responseHandler: jest.fn((o, d) => { + expect(o.destinationResponse).toEqual({ response: 'response', status: 200 }); + expect(o.rudderJobMetadata).toEqual([{ a1: 'b1' }]); + expect(o.destType).toEqual(destType); + return respHandlerResponse; + }), + }; + + const getNetworkHandlerSpy = jest + .spyOn(networkHandlerFactory, 'getNetworkHandler') + .mockImplementationOnce((d, v) => { + expect(d).toEqual(destType); + expect(v).toEqual(version); + return { + networkHandler: mockNetworkHandler, + handlerVersion: version, + }; + }); + + const response = await request(server) + .post('/v1/destinations/__rudder_test__/proxy') + .set('Accept', 'application/json') + .send(getData()); + + expect(response.status).toEqual(200); + expect(JSON.parse(response.text)).toEqual({ + output: respHandlerResponse, + }); + expect(getNetworkHandlerSpy).toHaveBeenCalledTimes(1); + }); + + test('(mock source) v0 source transformation', async () => { + const sourceType = '__rudder_test__'; + const version = 'v0'; + + const getData = () => { + return [{ event: { a: 'b1' } }, { event: { a: 'b2' } }]; + }; + + const tevent = { event: 'clicked', type: 'track' }; + + const getSourceHandlerSpy = jest + .spyOn(FetchHandler, 'getSourceHandler') + .mockImplementationOnce((s, v) => { + expect(s).toEqual(sourceType); + return { + process: jest.fn(() => { + return tevent; + }), + }; + }); + + const response = await request(server) + .post('/v0/sources/__rudder_test__') + .set('Accept', 'application/json') + .send(getData()); + + const expected = [ + { output: { batch: [{ event: 'clicked', type: 'track' }] } }, + { output: { batch: [{ event: 'clicked', type: 'track' }] } }, + ]; + + expect(response.status).toEqual(200); + expect(JSON.parse(response.text)).toEqual(expected); + expect(getSourceHandlerSpy).toHaveBeenCalledTimes(1); + }); + + test('(mock source) v1 source transformation', async () => { + const sourceType = '__rudder_test__'; + const version = 'v1'; + + const getData = () => { + return [ + { event: { a: 'b1' }, source: { id: 'id' } }, + { event: { a: 'b2' }, source: { id: 'id' } }, + ]; + }; + + const tevent = { event: 'clicked', type: 'track' }; + + const getSourceHandlerSpy = jest + .spyOn(FetchHandler, 'getSourceHandler') + .mockImplementationOnce((s, v) => { + expect(s).toEqual(sourceType); + return { + process: jest.fn(() => { + return tevent; + }), + }; + }); + + const response = await request(server) + .post('/v1/sources/__rudder_test__') + .set('Accept', 'application/json') + .send(getData()); + + const expected = [ + { output: { batch: [{ event: 'clicked', type: 'track' }] } }, + { output: { batch: [{ event: 'clicked', type: 'track' }] } }, + ]; + + expect(response.status).toEqual(200); + expect(JSON.parse(response.text)).toEqual(expected); + expect(getSourceHandlerSpy).toHaveBeenCalledTimes(1); + }); +}); + describe('Destination api tests', () => { describe('Processor transform tests', () => { test('(webhook) success scenario with single event', async () => { @@ -183,6 +515,7 @@ describe('Destination api tests', () => { expect(response.status).toEqual(200); expect(JSON.parse(response.text)).toEqual(data.output); }); + test('(pinterest_tag) failure router transform(partial failure)', async () => { const data = getDataFromPath('./data_scenarios/destination/router/failure_test.json'); const response = await request(server) diff --git a/test/integrations/common/criteo/network.ts b/test/integrations/common/criteo/network.ts new file mode 100644 index 00000000000..cd5e1ca1e81 --- /dev/null +++ b/test/integrations/common/criteo/network.ts @@ -0,0 +1,72 @@ +const headers = { + Authorization: 'Bearer success_access_token', + 'Content-Type': 'application/json', + Accept: 'application/json', + 'User-Agent': 'RudderLabs', +}; +const params = { destination: 'criteo_audience' }; +const method = 'PATCH'; +const commonData = { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, +}; + +export const networkCallsData = [ + { + description: 'Mock response depicting expired access token error', + httpReq: { + url: 'https://api.criteo.com/2022-10/audiences/3485/contactlist/expiredAccessToken', + data: commonData, + params, + headers, + method, + }, + httpRes: { + code: '400', + data: { + errors: [ + { + traceIdentifier: '80a1a0ba3981b04da847d05700752c77', + type: 'authorization', + code: 'authorization-token-expired', + instance: '/2022-10/audiences/123/contactlist', + title: 'The authorization token has expired', + }, + ], + }, + status: 401, + }, + }, + { + description: 'Mock response depicting invalid access token error', + httpReq: { + url: 'https://api.criteo.com/2022-10/audiences/34895/contactlist/invalidAccessToken', + data: commonData, + params, + headers, + method, + }, + httpRes: { + code: '400', + data: { + errors: [ + { + traceIdentifier: '80a1a0ba3981b04da847d05700752c77', + type: 'authorization', + code: 'authorization-token-invalid', + instance: '/2022-10/audiences/123/contactlist', + title: 'The authorization header is invalid', + }, + ], + }, + status: 401, + }, + }, +]; diff --git a/test/integrations/common/google/network.ts b/test/integrations/common/google/network.ts new file mode 100644 index 00000000000..95b76f8da81 --- /dev/null +++ b/test/integrations/common/google/network.ts @@ -0,0 +1,109 @@ +// Ads API +// Ref: https://developers.google.com/google-ads/api/docs/get-started/common-errors + +export const networkCallsData = [ + { + description: 'Mock response depicting CREDENTIALS_MISSING error', + httpReq: { + method: 'post', + url: 'https://googleapis.com/test_url_for_credentials_missing', + }, + httpRes: { + data: { + error: { + code: 401, + message: + 'Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.', + errors: [ + { + message: 'Login Required.', + domain: 'global', + reason: 'required', + location: 'Authorization', + locationType: 'header', + }, + ], + status: 'UNAUTHENTICATED', + details: [ + { + '@type': 'type.googleapis.com/google.rpc.ErrorInfo', + reason: 'CREDENTIALS_MISSING', + domain: 'googleapis.com', + metadata: { + method: 'google.ads.xfa.op.v4.DfareportingConversions.Batchinsert', + service: 'googleapis.com', + }, + }, + ], + }, + }, + status: 401, + }, + }, + { + description: 'Mock response depicting ACCESS_TOKEN_SCOPE_INSUFFICIENT error', + httpReq: { + method: 'post', + url: 'https://googleapis.com/test_url_for_access_token_scope_insufficient', + }, + httpRes: { + data: { + error: { + code: 403, + message: 'Request had insufficient authentication scopes.', + errors: [ + { + message: 'Insufficient Permission', + domain: 'global', + reason: 'insufficientPermissions', + }, + ], + status: 'PERMISSION_DENIED', + details: [ + { + '@type': 'type.googleapis.com/google.rpc.ErrorInfo', + reason: 'ACCESS_TOKEN_SCOPE_INSUFFICIENT', + domain: 'googleapis.com', + metadata: { + service: 'gmail.googleapis.com', + method: 'caribou.api.proto.MailboxService.GetProfile', + }, + }, + ], + }, + }, + status: 403, + }, + }, + { + description: 'Mock response for google.auth.exceptions.RefreshError invalid_grant error', + httpReq: { + method: 'post', + url: 'https://googleapis.com/test_url_for_invalid_grant', + }, + httpRes: { + data: { + error: { + code: 403, + message: 'invalid_grant', + error_description: 'Bad accesss', + }, + }, + status: 403, + }, + }, + { + description: 'Mock response for google.auth.exceptions.RefreshError refresh_token error', + httpReq: { + method: 'post', + url: 'https://googleapis.com/test_url_for_refresh_error', + }, + httpRes: { + data: { + error: 'unauthorized', + error_description: 'Access token expired: 2020-10-20T12:00:00.000Z', + }, + status: 401, + }, + }, +]; diff --git a/test/integrations/common/network.ts b/test/integrations/common/network.ts new file mode 100644 index 00000000000..a6ab202a4ec --- /dev/null +++ b/test/integrations/common/network.ts @@ -0,0 +1,95 @@ +export const networkCallsData = [ + { + description: 'Mock response depicting SERVICE NOT AVAILABLE error', + httpReq: { + method: 'post', + url: 'https://random_test_url/test_for_service_not_available', + }, + httpRes: { + data: { + error: { + message: 'Service Unavailable', + description: + 'The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later.', + }, + }, + status: 503, + }, + }, + { + description: 'Mock response depicting INTERNAL SERVER ERROR error with post method', + httpReq: { + method: 'post', + url: 'https://random_test_url/test_for_internal_server_error', + }, + httpRes: { + data: 'Internal Server Error', + status: 500, + }, + }, + { + description: 'Mock response depicting INTERNAL SERVER ERROR error with patch method', + httpReq: { + method: 'post', + url: 'https://random_test_url/test_for_internal_server_error', + }, + httpRes: { + data: 'Internal Server Error', + status: 500, + }, + }, + { + description: 'Mock response depicting GATEWAY TIME OUT error', + httpReq: { + method: 'post', + url: 'https://random_test_url/test_for_gateway_time_out', + }, + httpRes: { + data: 'Gateway Timeout', + status: 504, + }, + }, + { + description: 'Mock response depicting null response', + httpReq: { + method: 'post', + url: 'https://random_test_url/test_for_null_response', + }, + httpRes: { + data: null, + status: 500, + }, + }, + { + description: 'Mock response depicting null and no status', + httpReq: { + method: 'post', + url: 'https://random_test_url/test_for_null_and_no_status', + }, + httpRes: { + data: null, + }, + }, + { + description: 'Mock response depicting TOO MANY REQUESTS error with patch method', + httpReq: { + method: 'patch', + url: 'https://random_test_url/test_for_too_many_requests', + }, + httpRes: { + data: {}, + status: 429, + }, + }, + { + description: 'Mock response depicting DNS lookup failure error', + httpReq: { + method: 'post', + url: 'https://random_test_url/dns_lookup_failure', + }, + httpRes: { + data: {}, + status: 400, + }, + }, +]; diff --git a/test/integrations/component.test.ts b/test/integrations/component.test.ts index ec4fb02dc19..388c283c615 100644 --- a/test/integrations/component.test.ts +++ b/test/integrations/component.test.ts @@ -16,6 +16,7 @@ import { getMockHttpCallsData, getAllTestMockDataFilePaths, addMock, + validateTestWithZOD, } from './testUtils'; import tags from '../../src/v0/util/tags'; import { Server } from 'http'; @@ -53,7 +54,7 @@ if (opts.generate === 'true') { let server: Server; -const REPORT_COMPATIBLE_INTEGRATION = ['klaviyo']; +const INTEGRATIONS_WITH_UPDATED_TEST_STRUCTURE = ['klaviyo', 'campaign_manager', 'criteo_audience']; beforeAll(async () => { initaliseReport(); @@ -147,7 +148,8 @@ const testRoute = async (route, tcData: TestCaseData) => { expect(response.status).toEqual(outputResp.status); - if (REPORT_COMPATIBLE_INTEGRATION.includes(tcData.name?.toLocaleLowerCase())) { + if (INTEGRATIONS_WITH_UPDATED_TEST_STRUCTURE.includes(tcData.name?.toLocaleLowerCase())) { + expect(validateTestWithZOD(tcData, response)).toEqual(true); const bodyMatched = _.isEqual(response.body, outputResp.body); const statusMatched = response.status === outputResp.status; if (bodyMatched && statusMatched) { diff --git a/test/integrations/destinations/adj/processor/data.ts b/test/integrations/destinations/adj/processor/data.ts index 2c208d0d084..e28a25cf59d 100644 --- a/test/integrations/destinations/adj/processor/data.ts +++ b/test/integrations/destinations/adj/processor/data.ts @@ -2179,7 +2179,8 @@ export const data = [ status: 200, body: [ { - error: 'App Token is not present. Please configure your app token from config dashbaord', + error: + 'App Token is not present. Please configure your app token from config dashbaord', statTags: { destType: 'ADJ', errorCategory: 'dataValidation', @@ -2205,24 +2206,24 @@ export const data = [ body: [ { message: { - "type": "track", - "event": "Application Installed", - "sentAt": "2022-09-28T20:14:44.995Z", - "userId": "sample_user_id", - "context": { - "device": { - "id": "sample_device_id", - "type": "android", - "advertisingId": "_sample" + type: 'track', + event: 'Application Installed', + sentAt: '2022-09-28T20:14:44.995Z', + userId: 'sample_user_id', + context: { + device: { + id: 'sample_device_id', + type: 'android', + advertisingId: '_sample', + }, + traits: { + userId: '_sample_uid', + anonymousId: '_sample_anonid', }, - "traits": { - "userId": "_sample_uid", - "anonymousId": "_sample_anonid" - } - }, - "timestamp": "2022-09-28T20:14:43.314Z", - "request_ip": "71.189.106.156", - "originalTimestamp": "2022-09-28T20:14:44.995Z" + }, + timestamp: '2022-09-28T20:14:43.314Z', + request_ip: '71.189.106.156', + originalTimestamp: '2022-09-28T20:14:44.995Z', }, destination: { ID: '1i3Em7GMU9xVEiDlZUN8c88BMS9', @@ -2245,8 +2246,7 @@ export const data = [ }, Config: { appToken: 'testAppToken', - customMappings: [ - { from: 'Application Installed', to: '3fdmll' }], + customMappings: [{ from: 'Application Installed', to: '3fdmll' }], partnerParamsKeys: [ { from: 'key1', to: 'partnerParamKey-1' }, { from: 'key2', to: 'partnerParamKey-2' }, @@ -2277,10 +2277,10 @@ export const data = [ endpoint: 'https://s2s.adjust.com/event', headers: { Accept: '*/*' }, params: { - event_token: "3fdmll", - ip_address: "71.189.106.156", + event_token: '3fdmll', + ip_address: '71.189.106.156', android_id: 'sample_device_id', - gps_adid: "_sample", + gps_adid: '_sample', s2s: 1, app_token: 'testAppToken', environment: 'production', @@ -2294,4 +2294,5 @@ export const data = [ ], }, }, - },]; + }, +]; diff --git a/test/integrations/destinations/adobe_analytics/dataDelivery/business.ts b/test/integrations/destinations/adobe_analytics/dataDelivery/business.ts new file mode 100644 index 00000000000..76e07690cf0 --- /dev/null +++ b/test/integrations/destinations/adobe_analytics/dataDelivery/business.ts @@ -0,0 +1,181 @@ +import { ProxyMetdata } from '../../../../../src/types'; +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV1Payload } from '../../../testUtils'; + +const statTags = { + aborted: { + destType: 'ADOBE_ANALYTICS', + destinationId: 'dummyDestinationId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'dummyWorkspaceId', + }, +}; + +export const proxyMetdata: ProxyMetdata = { + jobId: 1, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, +}; +const headers = { + 'Content-Type': 'application/xml', +}; + +export const reqMetadataArray = [proxyMetdata]; + +const failureRequestParameters = { + XML: { + payload: + '17941080sales campaignwebUSD127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellerprodViewGames;;11;148.39failureReport', + }, + params: {}, +}; + +const successRequestParameters = { + XML: { + payload: + '127.0.1.0www.google.co.inGoogleid1110011prodViewGames;Monopoly;1;14.00,Games;UNO;2;6.90successreport', + }, + params: {}, +}; + +export const testScenariosForV1API: ProxyV1TestData[] = [ + { + id: 'adobe_analytics_v1_scenario_1', + name: 'adobe_analytics', + description: '[Proxy v1 API] :: Test for Failure response from Adobe Analytics with reason', + successCriteria: 'Should return a 400 status code with reason', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...failureRequestParameters, + headers, + endpoint: 'https://adobe.failure.omtrdc.net/b/ss//6', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + statTags: statTags.aborted, + message: + '[ADOBE_ANALYTICS Response Handler] Request failed for destination adobe_analytics : NO pagename OR pageurl', + response: [ + { + error: + '[ADOBE_ANALYTICS Response Handler] Request failed for destination adobe_analytics : NO pagename OR pageurl', + metadata: proxyMetdata, + statusCode: 400, + }, + ], + }, + }, + }, + }, + }, + { + id: 'adobe_analytics_v1_scenario_2', + name: 'adobe_analytics', + description: + '[Proxy v1 API] :: Test for Failure response from Adobe Analytics without reason (Generic error)', + successCriteria: 'Should return a 400 status code with a general error', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...failureRequestParameters, + headers, + endpoint: 'https://adobe.failure2.omtrdc.net/b/ss//6', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + statTags: statTags.aborted, + message: + '[ADOBE_ANALYTICS Response Handler] Request failed for destination adobe_analytics with a general error', + response: [ + { + error: + '[ADOBE_ANALYTICS Response Handler] Request failed for destination adobe_analytics with a general error', + metadata: proxyMetdata, + statusCode: 400, + }, + ], + }, + }, + }, + }, + }, + { + id: 'adobe_analytics_v1_scenario_3', + name: 'adobe_analytics', + description: '[Proxy v1 API] :: Test for Success response from Adobe Analytics', + successCriteria: 'Should return a 200 status code with status SUCCESS', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...successRequestParameters, + headers, + endpoint: 'https://adobe.success.omtrdc.net/b/ss//6', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: '[ADOBE_ANALYTICS] - Request Processed Successfully', + response: [ + { + error: '"SUCCESS"', + metadata: proxyMetdata, + statusCode: 200, + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/adobe_analytics/dataDelivery/data.ts b/test/integrations/destinations/adobe_analytics/dataDelivery/data.ts index 182969da73d..2535a0639e9 100644 --- a/test/integrations/destinations/adobe_analytics/dataDelivery/data.ts +++ b/test/integrations/destinations/adobe_analytics/dataDelivery/data.ts @@ -1,4 +1,6 @@ -export const data = [ +import { testScenariosForV1API } from './business'; + +const legacyTests = [ { name: 'adobe_analytics', description: 'Test 0: Failure response from Adobe Analytics with reason', @@ -72,7 +74,7 @@ export const data = [ JSON_ARRAY: {}, XML: { payload: - '17941080sales campaignwebUSD127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellerprodViewGames;;11;148.39failureReportgeneric', + '17941080sales campaignwebUSD127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellerprodViewGames;;11;148.39failureReport', }, FORM: {}, }, @@ -140,3 +142,5 @@ export const data = [ }, }, ]; + +export const data = [...testScenariosForV1API, ...legacyTests]; diff --git a/test/integrations/destinations/adobe_analytics/network.ts b/test/integrations/destinations/adobe_analytics/network.ts index 2fe4f0204ed..7e32c5f10b4 100644 --- a/test/integrations/destinations/adobe_analytics/network.ts +++ b/test/integrations/destinations/adobe_analytics/network.ts @@ -17,7 +17,7 @@ export const networkCallsData = [ { httpReq: { url: 'https://adobe.failure2.omtrdc.net/b/ss//6', - data: '17941080sales campaignwebUSD127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellerprodViewGames;;11;148.39failureReportgeneric', + data: '17941080sales campaignwebUSD127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellerprodViewGames;;11;148.39failureReport', params: {}, headers: { 'Content-Type': 'application/xml', diff --git a/test/integrations/destinations/af/processor/data.ts b/test/integrations/destinations/af/processor/data.ts index 8b639f45c02..d0fd29b0890 100644 --- a/test/integrations/destinations/af/processor/data.ts +++ b/test/integrations/destinations/af/processor/data.ts @@ -45,6 +45,7 @@ export const data = [ destination: { Config: { devKey: 'ef1d42390426e3f7c90ac78272e74344', androidAppId: 'appId' }, Enabled: true, + addPropertiesAtRoot: false, }, }, ], @@ -118,6 +119,7 @@ export const data = [ Config: { devKey: 'ef1d42390426e3f7c90ac78272e74344', androidAppId: 'com.rudderlabs.javascript', + addPropertiesAtRoot: false, }, Enabled: true, }, @@ -305,6 +307,7 @@ export const data = [ Config: { devKey: 'ef1d42390426e3f7c90ac78272e74344', androidAppId: 'com.rudderlabs.javascript', + addPropertiesAtRoot: false, }, Enabled: true, }, @@ -1532,4 +1535,306 @@ export const data = [ }, }, }, + { + name: 'af', + description: 'Place Properties at root level Page Call', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + externalId: [{ type: 'appsflyerExternalId', id: 'afUid' }], + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'testhubspot2@email.com', + name: 'Test Hubspot', + anonymousId: '12345', + }, + library: { name: 'RudderLabs JavaScript SDK', version: '1.0.0' }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-GB', + ip: '0.0.0.0', + os: { name: 'android', version: '' }, + screen: { density: 2 }, + }, + type: 'page', + messageId: 'e8585d9a-7137-4223-b295-68ab1b17dad7', + originalTimestamp: '2019-10-15T09:35:31.289Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { path: '', referrer: '', search: '', title: '', url: '' }, + name: 'ApplicationLoaded', + sentAt: '2019-10-14T11:15:53.296Z', + integrations: { AF: { af_uid: 'afUid' } }, + }, + destination: { + Config: { + devKey: 'ef1d42390426e3f7c90ac78272e74344', + androidAppId: 'com.rudderlabs.javascript', + sharingFilter: 'all', + addPropertiesAtRoot: true, + }, + Enabled: true, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + endpoint: 'https://api2.appsflyer.com/inappevent/com.rudderlabs.javascript', + headers: { + 'Content-Type': 'application/json', + authentication: 'ef1d42390426e3f7c90ac78272e74344', + }, + method: 'POST', + params: {}, + body: { + JSON: { + app_version_name: '1.0.0', + bundleIdentifier: 'com.rudderlabs.javascript', + customer_user_id: '12345', + eventValue: '{"path":"","referrer":"","search":"","title":"","url":""}', + eventName: 'page', + appsflyer_id: 'afUid', + os: '', + ip: '0.0.0.0', + sharing_filter: 'all', + }, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'af', + description: 'Place properties at root level track call', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + externalId: [{ type: 'appsflyerExternalId', id: 'afUid' }], + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { email: 'testhubspot2@email.com', name: 'Test Hubspot' }, + library: { name: 'RudderLabs JavaScript SDK', version: '1.0.0' }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-GB', + ip: '0.0.0.0', + os: { name: 'android', version: '' }, + screen: { density: 2 }, + }, + type: 'track', + messageId: '08829772-d991-427c-b976-b4c4f4430b4e', + originalTimestamp: '2019-10-15T09:35:31.291Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'test track event HS', + properties: { user_actual_role: 'system_admin, system_user', user_actual_id: 12345 }, + sentAt: '2019-10-14T11:15:53.296Z', + integrations: { AF: { af_uid: 'afUid' } }, + }, + destination: { + Config: { + devKey: 'ef1d42390426e3f7c90ac78272e74344', + androidAppId: 'com.rudderlabs.javascript', + addPropertiesAtRoot: true, + }, + Enabled: true, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api2.appsflyer.com/inappevent/com.rudderlabs.javascript', + headers: { + 'Content-Type': 'application/json', + authentication: 'ef1d42390426e3f7c90ac78272e74344', + }, + params: {}, + body: { + JSON: { + eventValue: + '{"user_actual_role":"system_admin, system_user","user_actual_id":12345}', + eventName: 'test track event HS', + customer_user_id: '12345', + ip: '0.0.0.0', + os: '', + appsflyer_id: 'afUid', + app_version_name: '1.0.0', + bundleIdentifier: 'com.rudderlabs.javascript', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'af', + description: 'Place properties at root track call with af data', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 'Order Completed', + sentAt: '2020-08-14T05:30:30.118Z', + context: { + externalId: [{ type: 'appsflyerExternalId', id: 'afUid' }], + source: 'test', + app: { namespace: 'com.rudderlabs.javascript' }, + os: { name: 'android' }, + traits: { anonymousId: '50be5c78-6c3f-4b60-be84-97805a316fb1' }, + library: { name: 'rudder-sdk-ruby-sync', version: '1.0.6' }, + }, + messageId: '7208bbb6-2c4e-45bb-bf5b-ad426f3593e9', + timestamp: '2020-08-14T05:30:30.118Z', + properties: { + tax: 2, + total: 27.5, + coupon: 'hasbros', + revenue: 48, + price: 25, + quantity: 2, + currency: 'ZAR', + discount: 2.5, + order_id: '50314b8e9bcf000000000000', + products: [ + { + sku: '45790-32', + url: 'https://www.example.com/product/path', + name: 'Monopoly: 3rd Edition', + price: 19, + category: 'Games', + quantity: 1, + image_url: 'https:///www.example.com/product/path.jpg', + product_id: '507f1f77bcf86cd799439011', + }, + { + sku: '46493-32', + name: 'Uno Card Game', + price: 3, + category: 'Games', + quantity: 2, + product_id: '505bd76785ebb509fc183733', + }, + ], + shipping: 3, + subtotal: 22.5, + affiliation: 'Google Store', + checkout_id: 'fksdjfsdjfisjf9sdfjsd9f', + }, + anonymousId: '50be5c78-6c3f-4b60-be84-97805a316fb1', + integrations: { AF: { af_uid: 'afUid' } }, + }, + destination: { + Config: { + devKey: 'abcde', + androidAppId: 'com.rudderlabs.javascript', + groupTypeTrait: 'email', + groupValueTrait: 'age', + trackProductsOnce: false, + trackRevenuePerProduct: false, + addPropertiesAtRoot: true, + }, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api2.appsflyer.com/inappevent/com.rudderlabs.javascript', + headers: { 'Content-Type': 'application/json', authentication: 'abcde' }, + params: {}, + body: { + JSON: { + bundleIdentifier: 'com.rudderlabs.javascript', + eventValue: + '{"tax":2,"total":27.5,"coupon":"hasbros","revenue":48,"price":25,"quantity":2,"currency":"ZAR","discount":2.5,"order_id":"50314b8e9bcf000000000000","products":[{"sku":"45790-32","url":"https://www.example.com/product/path","name":"Monopoly: 3rd Edition","price":19,"category":"Games","quantity":1,"image_url":"https:///www.example.com/product/path.jpg","product_id":"507f1f77bcf86cd799439011"},{"sku":"46493-32","name":"Uno Card Game","price":3,"category":"Games","quantity":2,"product_id":"505bd76785ebb509fc183733"}],"shipping":3,"subtotal":22.5,"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","af_revenue":48,"af_price":[19,3],"af_quantity":[1,2],"af_order_id":"50314b8e9bcf000000000000","af_content_id":["507f1f77bcf86cd799439011","505bd76785ebb509fc183733"]}', + eventName: 'Order Completed', + eventCurrency: 'ZAR', + eventTime: '2020-08-14T05:30:30.118Z', + appsflyer_id: 'afUid', + }, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, ]; diff --git a/test/integrations/destinations/algolia/dataDelivery/business.ts b/test/integrations/destinations/algolia/dataDelivery/business.ts new file mode 100644 index 00000000000..8ba964e2ddb --- /dev/null +++ b/test/integrations/destinations/algolia/dataDelivery/business.ts @@ -0,0 +1,331 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV0Payload, generateProxyV1Payload } from '../../../testUtils'; +import { abortStatTags, commonRequestProperties, metadataArray, retryStatTags } from './constant'; +const proxyMetdata3 = { + jobId: 3, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, +}; +export const testScenariosForV0API = [ + { + id: 'algolia_v0_bussiness_scenario_1', + name: 'algolia', + description: '[Proxy v0 API] :: algolia all valid events', + successCriteria: 'Proper response from destination is received', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestProperties.commonHeaders, + endpoint: 'https://insights.algolia.io/1/events', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: + '[Generic Response Handler] Request for destination: algolia Processed Successfully', + destinationResponse: { + response: { + message: 'OK', + status: 200, + }, + status: 200, + }, + }, + }, + }, + }, + }, + { + id: 'algolia_v0_bussiness_scenario_2', + name: 'algolia', + description: '[Proxy v0 API] :: algolia with invalid event', + successCriteria: 'Error Response from destination is received', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestProperties.commonHeaders, + endpoint: 'https://insights.algolia.io/1/events', + JSON: commonRequestProperties.singleInValidEvent, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 422, + body: { + output: { + status: 422, + message: + '[Generic Response Handler] Request failed for destination algolia with status: 422', + destinationResponse: { + response: { + status: 422, + message: 'EventType must be one of "click", "conversion" or "view"', + }, + status: 422, + }, + statTags: abortStatTags, + }, + }, + }, + }, + }, + { + id: 'algolia_v0_bussiness_scenario_3', + name: 'algolia', + description: '[Proxy v0 API] :: algolia with invalid events in batch', + successCriteria: 'Error Response from destination is received', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestProperties.commonHeaders, + endpoint: 'https://insights.algolia.io/1/events', + JSON: commonRequestProperties.combinedValidInvalidEvents, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 422, + body: { + output: { + status: 422, + message: + '[Generic Response Handler] Request failed for destination algolia with status: 422', + destinationResponse: { + response: { + status: 422, + message: 'EventType must be one of "click", "conversion" or "view"', + }, + status: 422, + }, + statTags: abortStatTags, + }, + }, + }, + }, + }, +]; + +export const testScenariosForV1API: ProxyV1TestData[] = [ + { + id: 'algolia_v1_bussiness_scenario_1', + name: 'algolia', + description: '[Proxy v1 API] :: algolia all valid events in batch', + successCriteria: 'Success response from destination is received', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestProperties.commonHeaders, + endpoint: 'https://insights.algolia.io/1/events', + JSON: commonRequestProperties.multipleValidEvent, + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: '[ALGOLIA Response V1 Handler] - Request Processed Successfully', + destinationResponse: { + response: { + message: 'OK', + status: 200, + }, + status: 200, + }, + response: [ + { + error: 'success', + metadata: metadataArray[0], + statusCode: 200, + }, + { + error: 'success', + metadata: metadataArray[1], + statusCode: 200, + }, + ], + }, + }, + }, + }, + }, + { + id: 'algolia_v1_bussiness_scenario_2', + name: 'algolia', + description: '[Proxy v1 API] :: algolia all invalid events in batch', + successCriteria: 'Send response with dontBatch as true', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + ...commonRequestProperties.commonHeaders, + endpoint: 'https://insights.algolia.io/1/events', + JSON: commonRequestProperties.singleInValidEvent, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 500, + message: 'ALGOLIA: Error transformer proxy v1 during ALGOLIA response transformation', + response: [ + { + error: + '{"status":422,"message":"EventType must be one of \\"click\\", \\"conversion\\" or \\"view\\""}', + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: true, + }, + statusCode: 500, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'ALGOLIA', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + }, + }, + }, + }, + }, + { + id: 'algolia_v1_bussiness_scenario_3', + name: 'algolia', + description: '[Proxy v1 API] :: algolia combination of valid and invalid events in batch', + successCriteria: 'Should use dontBatch true and proper response returned', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestProperties.commonHeaders, + endpoint: 'https://insights.algolia.io/1/events', + JSON: commonRequestProperties.combinedValidInvalidEvents, + }, + [...metadataArray, proxyMetdata3], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 500, + message: 'ALGOLIA: Error transformer proxy v1 during ALGOLIA response transformation', + response: [ + { + error: + '{"status":422,"message":"EventType must be one of \\"click\\", \\"conversion\\" or \\"view\\""}', + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: true, + }, + statusCode: 500, + }, + { + error: + '{"status":422,"message":"EventType must be one of \\"click\\", \\"conversion\\" or \\"view\\""}', + metadata: { + jobId: 2, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: true, + }, + statusCode: 500, + }, + { + error: + '{"status":422,"message":"EventType must be one of \\"click\\", \\"conversion\\" or \\"view\\""}', + metadata: { + jobId: 3, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: true, + }, + statusCode: 500, + }, + ], + statTags: retryStatTags, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/algolia/dataDelivery/constant.ts b/test/integrations/destinations/algolia/dataDelivery/constant.ts new file mode 100644 index 00000000000..e8d0817a7fe --- /dev/null +++ b/test/integrations/destinations/algolia/dataDelivery/constant.ts @@ -0,0 +1,118 @@ +const proxyMetdata1 = { + jobId: 1, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, +}; + +const proxyMetdata2 = { + jobId: 2, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, +}; + +export const metadataArray = [proxyMetdata1, proxyMetdata2]; + +export const abortStatTags = { + errorCategory: 'network', + errorType: 'aborted', + destType: 'ALGOLIA', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', +}; + +export const commonRequestProperties = { + commonHeaders: { + 'X-Algolia-API-Key': 'dummyApiKey', + 'X-Algolia-Application-Id': 'O2YARRI15I', + 'User-Agent': 'RudderLabs', + }, + singleValidEvent: { + events: [ + { + eventName: 'product clicked', + eventType: 'click', + filters: ['field1:hello', 'val1:val2'], + index: 'products', + userToken: 'testuserId1', + }, + ], + }, + singleInValidEvent: { + events: [ + { + eventName: 'product clicked', + eventType: 'abc', + filters: ['field1:hello', 'val1:val2'], + index: 'products', + userToken: 'testuserId1', + }, + ], + }, + multipleValidEvent: { + events: [ + { + eventName: 'product clicked', + eventType: 'click', + filters: ['field1:hello', 'val1:val2'], + index: 'products', + userToken: 'testuserId1', + }, + { + eventName: 'product clicked', + eventType: 'view', + filters: ['field1:hello', 'val1:val2'], + index: 'products', + userToken: 'testuserId1', + }, + ], + }, + combinedValidInvalidEvents: { + events: [ + { + eventName: 'product clicked', + eventType: 'click', + filters: ['field1:hello', 'val1:val2'], + index: 'products', + userToken: 'testuserId1', + }, + { + eventName: 'product clicked', + eventType: 'view', + filters: ['field1:hello', 'val1:val2'], + index: 'products', + userToken: 'testuserId1', + }, + { + eventName: 'product clicked', + eventType: 'abc', + filters: ['field1:hello', 'val1:val2'], + index: 'products', + userToken: 'testuserId1', + }, + ], + }, +}; + +export const retryStatTags = { + errorCategory: 'network', + errorType: 'retryable', + destType: 'ALGOLIA', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', +}; diff --git a/test/integrations/destinations/algolia/dataDelivery/data.ts b/test/integrations/destinations/algolia/dataDelivery/data.ts new file mode 100644 index 00000000000..feb4eb46c50 --- /dev/null +++ b/test/integrations/destinations/algolia/dataDelivery/data.ts @@ -0,0 +1,9 @@ +import { testScenariosForV0API, testScenariosForV1API } from './business'; +import { otherScenariosV0, otherScenariosV1 } from './other'; + +export const data = [ + ...testScenariosForV0API, + ...testScenariosForV1API, + ...otherScenariosV0, + ...otherScenariosV1, +]; diff --git a/test/integrations/destinations/algolia/dataDelivery/other.ts b/test/integrations/destinations/algolia/dataDelivery/other.ts new file mode 100644 index 00000000000..f5ccc703378 --- /dev/null +++ b/test/integrations/destinations/algolia/dataDelivery/other.ts @@ -0,0 +1,524 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV0Payload, generateProxyV1Payload } from '../../../testUtils'; + +export const otherScenariosV0 = [ + { + id: 'algolia_v0_other_scenario_1', + name: 'algolia', + description: + '[Proxy v0 API] :: Scenario for testing Service Unavailable error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + endpoint: 'https://random_test_url/test_for_service_not_available', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 503, + body: { + output: { + status: 503, + message: + '[Generic Response Handler] Request failed for destination algolia with status: 503', + destinationResponse: { + response: { + error: { + message: 'Service Unavailable', + description: + 'The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later.', + }, + }, + status: 503, + }, + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'ALGOLIA', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + }, + }, + }, + }, + }, + { + id: 'algolia_v0_other_scenario_2', + name: 'algolia', + description: '[Proxy v0 API] :: Scenario for testing Internal Server error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + endpoint: 'https://random_test_url/test_for_internal_server_error', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + '[Generic Response Handler] Request failed for destination algolia with status: 500', + destinationResponse: { + response: 'Internal Server Error', + status: 500, + }, + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'ALGOLIA', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + }, + }, + }, + }, + }, + { + id: 'algolia_v0_other_scenario_3', + name: 'algolia', + description: '[Proxy v0 API] :: Scenario for testing Gateway Time Out error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + endpoint: 'https://random_test_url/test_for_gateway_time_out', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 504, + body: { + output: { + status: 504, + message: + '[Generic Response Handler] Request failed for destination algolia with status: 504', + destinationResponse: { + response: 'Gateway Timeout', + status: 504, + }, + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'ALGOLIA', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + }, + }, + }, + }, + }, + { + id: 'algolia_v0_other_scenario_4', + name: 'algolia', + description: '[Proxy v0 API] :: Scenario for testing null response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + endpoint: 'https://random_test_url/test_for_null_response', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + '[Generic Response Handler] Request failed for destination algolia with status: 500', + destinationResponse: { + response: '', + status: 500, + }, + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'ALGOLIA', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + }, + }, + }, + }, + }, + { + id: 'algolia_v0_other_scenario_5', + name: 'algolia', + description: + '[Proxy v0 API] :: Scenario for testing null and no status response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + endpoint: 'https://random_test_url/test_for_null_and_no_status', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + '[Generic Response Handler] Request failed for destination algolia with status: 500', + destinationResponse: { + response: '', + status: 500, + }, + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'ALGOLIA', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + }, + }, + }, + }, + }, +]; + +export const otherScenariosV1: ProxyV1TestData[] = [ + { + id: 'algolia_v1_other_scenario_1', + name: 'algolia', + description: + '[Proxy v1 API] :: Scenario for testing Service Unavailable error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_service_not_available', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: + '{"error":{"message":"Service Unavailable","description":"The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later."}}', + statusCode: 503, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: true, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'ALGOLIA', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + message: 'ALGOLIA: Error transformer proxy v1 during ALGOLIA response transformation', + status: 503, + }, + }, + }, + }, + }, + { + id: 'algolia_v1_other_scenario_2', + name: 'algolia', + description: '[Proxy v1 API] :: Scenario for testing Internal Server error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_internal_server_error', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Internal Server Error"', + statusCode: 500, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: true, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'ALGOLIA', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + message: 'ALGOLIA: Error transformer proxy v1 during ALGOLIA response transformation', + status: 500, + }, + }, + }, + }, + }, + { + id: 'algolia_v1_other_scenario_3', + name: 'algolia', + description: '[Proxy v1 API] :: Scenario for testing Gateway Time Out error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_gateway_time_out', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Gateway Timeout"', + statusCode: 504, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: true, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'ALGOLIA', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + message: 'ALGOLIA: Error transformer proxy v1 during ALGOLIA response transformation', + status: 504, + }, + }, + }, + }, + }, + { + id: 'algolia_v1_other_scenario_4', + name: 'algolia', + description: '[Proxy v1 API] :: Scenario for testing null response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_response', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: true, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'ALGOLIA', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + message: 'ALGOLIA: Error transformer proxy v1 during ALGOLIA response transformation', + status: 500, + }, + }, + }, + }, + }, + { + id: 'algolia_v1_other_scenario_5', + name: 'algolia', + description: + '[Proxy v1 API] :: Scenario for testing null and no status response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_and_no_status', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: true, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'ALGOLIA', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + message: 'ALGOLIA: Error transformer proxy v1 during ALGOLIA response transformation', + status: 500, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/algolia/network.ts b/test/integrations/destinations/algolia/network.ts new file mode 100644 index 00000000000..84e932bbdbf --- /dev/null +++ b/test/integrations/destinations/algolia/network.ts @@ -0,0 +1,117 @@ +export const networkCallsData = [ + { + httpReq: { + url: 'https://insights.algolia.io/1/events', + data: { + events: [ + { + eventName: 'product clicked', + eventType: 'abc', + filters: ['field1:hello', 'val1:val2'], + index: 'products', + userToken: 'testuserId1', + }, + ], + }, + params: {}, + headers: { 'User-Agent': 'RudderLabs' }, + method: 'POST', + }, + httpRes: { + data: { + status: 422, + message: 'EventType must be one of "click", "conversion" or "view"', + }, + status: 422, + }, + }, + { + httpReq: { + url: 'https://insights.algolia.io/1/events', + data: { + events: [ + { + eventName: 'product clicked', + eventType: 'abc', + filters: ['field1:hello', 'val1:val2'], + index: 'products', + userToken: 'testuserId1', + }, + { + eventName: 'product clicked', + eventType: 'click', + filters: ['field1:hello', 'val1:val2'], + index: 'products', + userToken: 'testuserId1', + }, + ], + }, + params: {}, + headers: { 'User-Agent': 'RudderLabs' }, + method: 'POST', + }, + httpRes: { + data: { + status: 422, + message: 'EventType must be one of "click", "conversion" or "view"', + }, + status: 422, + }, + }, + { + httpReq: { + url: 'https://insights.algolia.io/1/events', + data: { + events: [ + { + eventName: 'product clicked', + eventType: 'click', + filters: ['field1:hello', 'val1:val2'], + index: 'products', + userToken: 'testuserId1', + }, + { + eventName: 'product clicked', + eventType: 'view', + filters: ['field1:hello', 'val1:val2'], + index: 'products', + userToken: 'testuserId1', + }, + { + eventName: 'product clicked', + eventType: 'abc', + filters: ['field1:hello', 'val1:val2'], + index: 'products', + userToken: 'testuserId1', + }, + ], + }, + params: {}, + headers: { 'User-Agent': 'RudderLabs' }, + method: 'POST', + }, + httpRes: { + data: { + status: 422, + message: 'EventType must be one of "click", "conversion" or "view"', + }, + status: 422, + }, + }, + { + httpReq: { + url: 'https://insights.algolia.io/1/events', + method: 'POST', + headers: { + 'User-Agent': 'RudderLabs', + }, + }, + httpRes: { + data: { + status: 200, + message: 'OK', + }, + status: 200, + }, + }, +]; diff --git a/test/integrations/destinations/algolia/processor/data.ts b/test/integrations/destinations/algolia/processor/data.ts index 0cbdd8b31b2..7c37c9642ae 100644 --- a/test/integrations/destinations/algolia/processor/data.ts +++ b/test/integrations/destinations/algolia/processor/data.ts @@ -380,7 +380,7 @@ export const data = [ body: [ { error: - 'Either filters or objectIds is required.: Workflow: procWorkflow, Step: validateDestPayload, ChildStep: undefined, OriginalError: Either filters or objectIds is required.', + 'Either filters or objectIds is required and must be non empty.: Workflow: procWorkflow, Step: validateDestPayload, ChildStep: undefined, OriginalError: Either filters or objectIds is required and must be non empty.', statTags: { destType: 'ALGOLIA', errorCategory: 'dataValidation', @@ -1417,4 +1417,214 @@ export const data = [ }, }, }, + { + name: 'algolia', + description: 'Eventype must be one of click, conversion pr view', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + page: { + path: '/destinations/ometria', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/ometria', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'product clicked', + userId: 'testuserId1', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + excludeKeys: [], + includeKeys: [], + }, + }, + Config: { + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'product clicked', + to: 'abcd', + }, + ], + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'eventType can be either click, view or conversion: Workflow: procWorkflow, Step: preparePayload, ChildStep: undefined, OriginalError: eventType can be either click, view or conversion', + statTags: { + destType: 'ALGOLIA', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'algolia', + description: 'filters or objectIds must be non empty', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 'product clicked', + sentAt: '2024-02-25T17:55:36.882Z', + userId: '12345', + channel: 'web', + properties: { + index: 'products', + list_id: 'search_results_page', + queryId: '8e737', + products: [], + eventName: 'productListView', + list_name: 'Search Results Page', + objectIds: [], + positions: [], + userToken: 'e494', + additional_attributes: {}, + }, + receivedAt: '2024-02-25T17:55:38.089Z', + request_ip: '107.130.37.100', + anonymousId: '68e9f4b8-fd4d-4c56-8ca4-858de2fd1df8', + integrations: { + All: true, + }, + originalTimestamp: '2024-02-25T17:55:36.880Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + excludeKeys: [], + includeKeys: [], + }, + }, + Config: { + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'product clicked', + to: 'cLick ', + }, + ], + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Either filters or objectIds is required and must be non empty.: Workflow: procWorkflow, Step: validateDestPayload, ChildStep: undefined, OriginalError: Either filters or objectIds is required and must be non empty.', + statTags: { + destType: 'ALGOLIA', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, ]; diff --git a/test/integrations/destinations/algolia/router/data.ts b/test/integrations/destinations/algolia/router/data.ts index 65c74342dc8..dca899693e5 100644 --- a/test/integrations/destinations/algolia/router/data.ts +++ b/test/integrations/destinations/algolia/router/data.ts @@ -2220,4 +2220,2406 @@ export const data = [ }, }, }, + { + name: 'algolia', + description: 'dontBatch true for all', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 1, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: true, + }, + }, + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: true, + }, + }, + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 3, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: true, + }, + }, + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 4, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: true, + }, + }, + ], + destType: 'algolia', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: { + body: { + JSON: { + events: [ + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights.algolia.io/1/events', + headers: { + 'X-Algolia-Application-Id': 'O2YARRI15I', + 'X-Algolia-API-Key': 'dummyApiKey', + }, + params: {}, + files: {}, + }, + metadata: [ + { + jobId: 1, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: true, + }, + ], + batched: true, + statusCode: 200, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + }, + { + batchedRequest: { + body: { + JSON: { + events: [ + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights.algolia.io/1/events', + headers: { + 'X-Algolia-Application-Id': 'O2YARRI15I', + 'X-Algolia-API-Key': 'dummyApiKey', + }, + params: {}, + files: {}, + }, + metadata: [ + { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: true, + }, + ], + batched: true, + statusCode: 200, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + }, + { + batchedRequest: { + body: { + JSON: { + events: [ + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights.algolia.io/1/events', + headers: { + 'X-Algolia-Application-Id': 'O2YARRI15I', + 'X-Algolia-API-Key': 'dummyApiKey', + }, + params: {}, + files: {}, + }, + metadata: [ + { + jobId: 3, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: true, + }, + ], + batched: true, + statusCode: 200, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + }, + { + batchedRequest: { + body: { + JSON: { + events: [ + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights.algolia.io/1/events', + headers: { + 'X-Algolia-Application-Id': 'O2YARRI15I', + 'X-Algolia-API-Key': 'dummyApiKey', + }, + params: {}, + files: {}, + }, + metadata: [ + { + jobId: 4, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: true, + }, + ], + batched: true, + statusCode: 200, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + }, + ], + }, + }, + }, + }, + { + name: 'algolia', + description: 'dontBatch Partial true for events in a batch', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 1, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + }, + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + }, + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 3, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + }, + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 4, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: true, + }, + }, + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 5, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: true, + }, + }, + ], + destType: 'algolia', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: { + body: { + JSON: { + events: [ + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights.algolia.io/1/events', + headers: { + 'X-Algolia-Application-Id': 'O2YARRI15I', + 'X-Algolia-API-Key': 'dummyApiKey', + }, + params: {}, + files: {}, + }, + metadata: [ + { + jobId: 1, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + { + jobId: 3, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + ], + batched: true, + statusCode: 200, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + }, + { + batchedRequest: { + body: { + JSON: { + events: [ + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights.algolia.io/1/events', + headers: { + 'X-Algolia-Application-Id': 'O2YARRI15I', + 'X-Algolia-API-Key': 'dummyApiKey', + }, + params: {}, + files: {}, + }, + metadata: [ + { + jobId: 4, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: true, + }, + ], + batched: true, + statusCode: 200, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + }, + { + batchedRequest: { + body: { + JSON: { + events: [ + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights.algolia.io/1/events', + headers: { + 'X-Algolia-Application-Id': 'O2YARRI15I', + 'X-Algolia-API-Key': 'dummyApiKey', + }, + params: {}, + files: {}, + }, + metadata: [ + { + jobId: 5, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: true, + }, + ], + batched: true, + statusCode: 200, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + }, + ], + }, + }, + }, + }, + { + name: 'algolia', + description: 'dontBatch false for all events, all events are batched in 1', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 1, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + }, + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + }, + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 3, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + }, + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 4, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + }, + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + message: { + channel: 'web', + context: { + traits: { + email: 'testone@gmail.com', + firstName: 'test', + lastName: 'one', + }, + }, + type: 'track', + anonymousId: '345345', + event: 'product clicked', + userId: 'test', + properties: { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + }, + integrations: { + All: true, + }, + }, + metadata: { + jobId: 5, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + }, + ], + destType: 'algolia', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: { + body: { + JSON: { + events: [ + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + { + index: 'products', + filters: ['field1:hello', 'val1:val2'], + userToken: 'test', + eventName: 'product clicked', + eventType: 'click', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights.algolia.io/1/events', + headers: { + 'X-Algolia-Application-Id': 'O2YARRI15I', + 'X-Algolia-API-Key': 'dummyApiKey', + }, + params: {}, + files: {}, + }, + metadata: [ + { + jobId: 1, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + { + jobId: 3, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + { + jobId: 4, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + { + jobId: 5, + attemptNum: 0, + userId: '', + sourceId: '2bAiFXtSLvENPDRAxVRxf0Udfaz', + destinationId: '2dH3xYIQnTNqfgPCqfVs88gWQdQ', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: null, + dontBatch: false, + }, + ], + batched: true, + statusCode: 200, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + cdkV2Enabled: true, + apiKey: 'dummyApiKey', + applicationId: 'O2YARRI15I', + eventTypeSettings: [ + { + from: 'Product List Filtered', + to: 'click', + }, + { + from: 'Product List Viewed', + to: 'view', + }, + { + from: 'Order Completed', + to: 'view', + }, + { + from: 'Product Added', + to: 'conversion', + }, + { + from: 'Product Viewed', + to: 'view', + }, + { + from: 'Product Clicked', + to: 'click', + }, + ], + pixelId: '123456789', + advertiserId: '429047995', + eventId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + customProperties: [ + { + properties: 'presentclass', + }, + { + properties: 'presentgrade', + }, + ], + eventsMapping: [ + { + from: 'ABC Searched', + to: 'WatchVideo', + }, + ], + }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'ALGOLIA', + Enabled: true, + cdkV2Enabled: true, + Transformations: [], + }, + }, + ], + }, + }, + }, + }, ]; diff --git a/test/integrations/destinations/am/batch/data.ts b/test/integrations/destinations/am/batch/data.ts index aa67df06c7c..91a17606a90 100644 --- a/test/integrations/destinations/am/batch/data.ts +++ b/test/integrations/destinations/am/batch/data.ts @@ -61,7 +61,7 @@ export const data = [ endpoint: 'https://api.eu.amplitude.com/2/httpapi', }, metadata: { - job_id: 1, + jobId: 1, userId: 'u1', }, destination: { @@ -83,16 +83,24 @@ export const data = [ { batched: false, error: 'Both userId and deviceId cannot be undefined', - //TODO fix this - metadata: { - job_id: 1, - userId: 'u1', - }, + metadata: [ + { + jobId: 1, + userId: 'u1', + }, + ], statTags: { errorCategory: 'dataValidation', errorType: 'instrumentation', }, statusCode: 400, + destination: { + ID: 'a', + url: 'a', + Config: { + residencyServer: 'EU', + }, + }, }, ], }, @@ -163,7 +171,7 @@ export const data = [ endpoint: 'https://api.eu.amplitude.com/2/httpapi', }, metadata: { - job_id: 1, + jobId: 1, userId: 'u1', }, destination: { @@ -218,7 +226,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 2, + jobId: 2, userId: 'u1', }, destination: { @@ -273,7 +281,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 3, + jobId: 3, userId: 'u1', }, destination: { @@ -331,7 +339,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 4, + jobId: 4, userId: 'u1', }, destination: { @@ -389,7 +397,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 5, + jobId: 5, userId: 'u1', }, destination: { @@ -423,7 +431,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/groupidentify', }, metadata: { - job_id: 6, + jobId: 6, userId: 'u1', }, destination: { @@ -455,7 +463,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/usermap', }, metadata: { - job_id: 7, + jobId: 7, userId: 'u1', }, destination: { @@ -529,7 +537,7 @@ export const data = [ }, metadata: [ { - job_id: 1, + jobId: 1, userId: 'u1', }, ], @@ -565,7 +573,7 @@ export const data = [ }, metadata: [ { - job_id: 6, + jobId: 6, userId: 'u1', }, ], @@ -599,7 +607,7 @@ export const data = [ }, metadata: [ { - job_id: 7, + jobId: 7, userId: 'u1', }, ], @@ -710,19 +718,19 @@ export const data = [ }, metadata: [ { - job_id: 2, + jobId: 2, userId: 'u1', }, { - job_id: 3, + jobId: 3, userId: 'u1', }, { - job_id: 4, + jobId: 4, userId: 'u1', }, { - job_id: 5, + jobId: 5, userId: 'u1', }, ], @@ -801,7 +809,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 1, + jobId: 1, userId: 'u1', }, destination: { @@ -854,7 +862,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 2, + jobId: 2, userId: 'u1', }, destination: { @@ -907,7 +915,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 3, + jobId: 3, userId: 'u1', }, destination: { @@ -963,7 +971,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 4, + jobId: 4, userId: 'u1', }, destination: { @@ -1019,7 +1027,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 5, + jobId: 5, userId: 'u1', }, destination: { @@ -1053,7 +1061,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/groupidentify', }, metadata: { - job_id: 6, + jobId: 6, userId: 'u1', }, destination: { @@ -1085,7 +1093,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/usermap', }, metadata: { - job_id: 7, + jobId: 7, userId: 'u1', }, destination: { @@ -1157,7 +1165,7 @@ export const data = [ }, metadata: [ { - job_id: 1, + jobId: 1, userId: 'u1', }, ], @@ -1193,7 +1201,7 @@ export const data = [ }, metadata: [ { - job_id: 6, + jobId: 6, userId: 'u1', }, ], @@ -1227,7 +1235,7 @@ export const data = [ }, metadata: [ { - job_id: 7, + jobId: 7, userId: 'u1', }, ], @@ -1338,19 +1346,19 @@ export const data = [ }, metadata: [ { - job_id: 2, + jobId: 2, userId: 'u1', }, { - job_id: 3, + jobId: 3, userId: 'u1', }, { - job_id: 4, + jobId: 4, userId: 'u1', }, { - job_id: 5, + jobId: 5, userId: 'u1', }, ], @@ -2117,7 +2125,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 1, + jobId: 1, userId: 'u1', }, destination: { @@ -2172,7 +2180,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 2, + jobId: 2, userId: 'u1', }, destination: { @@ -2227,7 +2235,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 3, + jobId: 3, userId: 'u1', }, destination: { @@ -2285,7 +2293,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 4, + jobId: 4, userId: 'u1', }, destination: { @@ -2343,7 +2351,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 5, + jobId: 5, userId: 'u1', }, destination: { @@ -2377,7 +2385,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/groupidentify', }, metadata: { - job_id: 6, + jobId: 6, userId: 'u1', }, destination: { @@ -2409,7 +2417,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/usermap', }, metadata: { - job_id: 7, + jobId: 7, userId: 'u1', }, destination: { @@ -2483,7 +2491,7 @@ export const data = [ }, metadata: [ { - job_id: 1, + jobId: 1, userId: 'u1', }, ], @@ -2519,7 +2527,7 @@ export const data = [ }, metadata: [ { - job_id: 6, + jobId: 6, userId: 'u1', }, ], @@ -2553,7 +2561,7 @@ export const data = [ }, metadata: [ { - job_id: 7, + jobId: 7, userId: 'u1', }, ], @@ -2664,19 +2672,19 @@ export const data = [ }, metadata: [ { - job_id: 2, + jobId: 2, userId: 'u1', }, { - job_id: 3, + jobId: 3, userId: 'u1', }, { - job_id: 4, + jobId: 4, userId: 'u1', }, { - job_id: 5, + jobId: 5, userId: 'u1', }, ], @@ -2756,7 +2764,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 1, + jobId: 1, userId: 'u1', }, destination: { @@ -2811,7 +2819,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 2, + jobId: 2, userId: 'u1', }, destination: { @@ -2866,7 +2874,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 3, + jobId: 3, userId: 'u1', }, destination: { @@ -2924,7 +2932,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 4, + jobId: 4, userId: 'u1', }, destination: { @@ -2982,7 +2990,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/2/httpapi', }, metadata: { - job_id: 5, + jobId: 5, userId: 'u1', }, destination: { @@ -3016,7 +3024,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/groupidentify', }, metadata: { - job_id: 6, + jobId: 6, userId: 'u1', }, destination: { @@ -3048,7 +3056,7 @@ export const data = [ endpoint: 'https://api2.amplitude.com/usermap', }, metadata: { - job_id: 7, + jobId: 7, userId: 'u1', }, destination: { @@ -3121,7 +3129,7 @@ export const data = [ }, metadata: [ { - job_id: 1, + jobId: 1, userId: 'u1', }, ], @@ -3157,7 +3165,7 @@ export const data = [ }, metadata: [ { - job_id: 6, + jobId: 6, userId: 'u1', }, ], @@ -3191,7 +3199,7 @@ export const data = [ }, metadata: [ { - job_id: 7, + jobId: 7, userId: 'u1', }, ], @@ -3302,19 +3310,19 @@ export const data = [ }, metadata: [ { - job_id: 2, + jobId: 2, userId: 'u1', }, { - job_id: 3, + jobId: 3, userId: 'u1', }, { - job_id: 4, + jobId: 4, userId: 'u1', }, { - job_id: 5, + jobId: 5, userId: 'u1', }, ], diff --git a/test/integrations/destinations/am/processor/data.ts b/test/integrations/destinations/am/processor/data.ts index f28606da0cd..01f9feb44a3 100644 --- a/test/integrations/destinations/am/processor/data.ts +++ b/test/integrations/destinations/am/processor/data.ts @@ -10739,6 +10739,7 @@ export const data = [ integrations: { All: true, Amplitude: { + skipUserPropertiesSync: false, event_id: 2, }, }, @@ -10894,6 +10895,7 @@ export const data = [ integrations: { All: true, Amplitude: { + skipUserPropertiesSync: true, event_id: 2, }, }, @@ -10949,6 +10951,7 @@ export const data = [ insert_id: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', ip: '1.1.1.1', event_id: 2, + $skip_user_properties_sync: true, user_properties: { initial_referrer: 'https://docs.rudderstack.com', initial_referring_domain: 'docs.rudderstack.com', @@ -11327,4 +11330,57 @@ export const data = [ }, }, }, + { + name: 'am', + description: + 'Test 78 -> Page call invalid event type as page name and template is not provided', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + request_ip: '1.1.1.1', + type: 'page', + userId: '12345', + properties: {}, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + apiKey: 'abcde', + useUserDefinedPageEventName: true, + userProvidedPageEventString: '', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: + 'Event type is missing. Please send it under `event.type`. For page/screen events, send it under `event.name`', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'AM', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, ]; diff --git a/test/integrations/destinations/bluecore/data.ts b/test/integrations/destinations/bluecore/data.ts new file mode 100644 index 00000000000..c2205c25a18 --- /dev/null +++ b/test/integrations/destinations/bluecore/data.ts @@ -0,0 +1,6 @@ +import { ecomTestData } from './ecommTestData'; +import { identifyData } from './identifyTestData'; +import { trackTestData } from './trackTestData'; +import { validationTestData } from './validationTestData'; + +export const data = [...identifyData, ...trackTestData, ...ecomTestData, ...validationTestData]; diff --git a/test/integrations/destinations/bluecore/ecommTestData.ts b/test/integrations/destinations/bluecore/ecommTestData.ts new file mode 100644 index 00000000000..de7584df781 --- /dev/null +++ b/test/integrations/destinations/bluecore/ecommTestData.ts @@ -0,0 +1,489 @@ +import { generateSimplifiedTrackPayload, transformResultBuilder } from '../../testUtils'; + +const metadata = { + sourceType: '', + destinationType: '', + namespace: '', + destinationId: '', +}; + +const destination = { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'BLUECORE', + Config: { + bluecoreNamespace: 'dummy_sandbox', + eventsMapping: [ + { + from: 'ABC Searched', + to: 'search', + }, + { + from: 'testPurchase', + to: 'purchase', + }, + { + from: 'testboth', + to: 'wishlist', + }, + { + from: 'testboth', + to: 'add_to_cart', + }, + ], + }, + Enabled: true, + Transformations: [], + DestinationDefinition: { Config: { cdkV2Enabled: true } }, +}; + +const commonTraits = { + id: 'user@1', + age: '22', + anonymousId: '9c6bd77ea9da3e68', +}; + +const commonPropsWithProducts = { + property1: 'value1', + property2: 'value2', + products: [ + { + product_id: '123', + sku: 'sku123', + name: 'Product 1', + price: 100, + quantity: 2, + }, + { + product_id: '124', + sku: 'sku124', + name: 'Product 2', + price: 200, + quantity: 3, + }, + ], +}; + +const commonPropsWithoutProducts = { + property1: 'value1', + property2: 'value2', + product_id: '123', +}; + +const commonOutputHeaders = { + 'Content-Type': 'application/json', +}; + +const eventEndPoint = 'https://api.bluecore.com/api/track/mobile/v1'; + +export const ecomTestData = [ + { + id: 'bluecore-track-test-1', + name: 'bluecore', + description: + 'Track event call with custom event mapped in destination config to purchase event. This will fail as order_id is not present in the payload', + scenario: 'Business', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: destination, + metadata, + message: generateSimplifiedTrackPayload({ + type: 'track', + event: 'testPurchase', + userId: 'sajal12', + context: { + traits: { + ...commonTraits, + email: 'test@rudderstack.com', + phone: '9112340375', + }, + }, + properties: commonPropsWithProducts, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + '[Bluecore] property:: order_id is required for purchase event: Workflow: procWorkflow, Step: handleTrackEvent, ChildStep: preparePayload, OriginalError: [Bluecore] property:: order_id is required for purchase event', + metadata, + statTags: { + destType: 'BLUECORE', + destinationId: '', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'bluecore-track-test-2', + name: 'bluecore', + description: + 'Track event call with custom event mapped in destination config to purchase event. This will fail as total is not present in the payload', + scenario: 'Business', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: destination, + metadata, + message: generateSimplifiedTrackPayload({ + type: 'track', + event: 'testPurchase', + userId: 'sajal12', + context: { + traits: { + ...commonTraits, + email: 'test@rudderstack.com', + phone: '9112340375', + }, + }, + properties: { ...commonPropsWithProducts, order_id: '123' }, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + '[Bluecore] property:: total is required for purchase event: Workflow: procWorkflow, Step: handleTrackEvent, ChildStep: preparePayload, OriginalError: [Bluecore] property:: total is required for purchase event', + metadata, + statTags: { + destType: 'BLUECORE', + destinationId: '', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'bluecore-track-test-3', + name: 'bluecore', + description: + 'Track event call with products searched event not mapped in destination config. This will fail as search_query is not present in the payload', + scenario: 'Business', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: destination, + metadata, + message: generateSimplifiedTrackPayload({ + type: 'track', + event: 'Products Searched', + userId: 'sajal12', + context: { + traits: { + ...commonTraits, + email: 'test@rudderstack.com', + phone: '9112340375', + }, + }, + properties: { ...commonPropsWithoutProducts }, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + '[Bluecore] property:: search_query is required for search event: Workflow: procWorkflow, Step: handleTrackEvent, ChildStep: preparePayload, OriginalError: [Bluecore] property:: search_query is required for search event', + metadata, + statTags: { + destType: 'BLUECORE', + destinationId: '', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'bluecore-track-test-4', + name: 'bluecore', + description: + 'Track event call with Product Viewed event not mapped in destination config. This will be sent with viewed_product name. This event without properties.products will add entire property object as products as this event type is recommended to sent with products', + scenario: 'Business', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: destination, + metadata, + message: generateSimplifiedTrackPayload({ + type: 'track', + event: 'product viewed', + userId: 'sajal12', + context: { + traits: { + ...commonTraits, + email: 'test@rudderstack.com', + phone: '9112340375', + }, + }, + properties: commonPropsWithoutProducts, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'POST', + endpoint: eventEndPoint, + headers: commonOutputHeaders, + JSON: { + properties: { + distinct_id: 'test@rudderstack.com', + customer: { + age: '22', + email: 'test@rudderstack.com', + }, + products: [ + { + id: '123', + property1: 'value1', + property2: 'value2', + }, + ], + }, + event: 'viewed_product', + token: 'dummy_sandbox', + }, + userId: '', + }), + metadata, + statusCode: 200, + }, + ], + }, + }, + }, + { + id: 'bluecore-track-test-5', + name: 'bluecore', + description: + 'Track event call with custom event mapped with two standard ecomm events in destination config. Both of the two corresponding standard events will be sent ', + scenario: 'Business', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 'testboth', + sentAt: '2020-08-14T05:30:30.118Z', + channel: 'web', + context: { + source: 'test', + userAgent: 'chrome', + traits: { + id: 'user@1', + age: '22', + anonymousId: '9c6bd77ea9da3e68', + }, + device: { + advertisingId: 'abc123', + }, + library: { + name: 'rudder-sdk-ruby-sync', + version: '1.0.6', + }, + }, + properties: { + property1: 'value1', + property2: 'value2', + product_id: '123', + }, + anonymousId: 'new-id', + integrations: { + All: true, + }, + }, + metadata, + destination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'POST', + endpoint: eventEndPoint, + headers: commonOutputHeaders, + JSON: { + properties: { + distinct_id: 'user@1', + customer: { + age: '22', + }, + products: [ + { + id: '123', + property1: 'value1', + property2: 'value2', + }, + ], + }, + event: 'wishlist', + token: 'dummy_sandbox', + }, + userId: '', + }), + metadata, + statusCode: 200, + }, + { + output: transformResultBuilder({ + method: 'POST', + endpoint: eventEndPoint, + headers: commonOutputHeaders, + JSON: { + properties: { + distinct_id: 'user@1', + customer: { + age: '22', + }, + products: [ + { + id: '123', + property1: 'value1', + property2: 'value2', + }, + ], + }, + event: 'add_to_cart', + token: 'dummy_sandbox', + }, + userId: '', + }), + metadata, + statusCode: 200, + }, + ], + }, + }, + }, + { + id: 'bluecore-track-test-6', + name: 'bluecore', + description: + 'Track event call with Order Completed event without product array and not mapped in destination config. This will be sent with purchase name. This event without properties.products will generate error as products array is required for purchase event and ordered completed is a standard ecomm event', + scenario: 'Business', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: destination, + metadata, + message: generateSimplifiedTrackPayload({ + type: 'track', + event: 'Order Completed', + userId: 'sajal12', + context: { + traits: { + ...commonTraits, + email: 'test@rudderstack.com', + phone: '9112340375', + }, + }, + properties: commonPropsWithoutProducts, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + '[Bluecore]:: products array is required for purchase event: Workflow: procWorkflow, Step: handleTrackEvent, ChildStep: preparePayload, OriginalError: [Bluecore]:: products array is required for purchase event', + metadata, + statTags: { + destType: 'BLUECORE', + destinationId: '', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/bluecore/identifyTestData.ts b/test/integrations/destinations/bluecore/identifyTestData.ts new file mode 100644 index 00000000000..660e335bc69 --- /dev/null +++ b/test/integrations/destinations/bluecore/identifyTestData.ts @@ -0,0 +1,381 @@ +import { + overrideDestination, + transformResultBuilder, + generateSimplifiedIdentifyPayload, +} from '../../testUtils'; + +const destination = { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'BLUECORE', + Config: { + bluecoreNamespace: 'dummy_sandbox', + eventsMapping: [ + { + from: 'ABC Searched', + to: 'search', + }, + ], + }, + Enabled: true, + Transformations: [], + DestinationDefinition: { Config: { cdkV2Enabled: true } }, +}; + +const metadata = { + sourceType: '', + destinationType: '', + namespace: '', + destinationId: '', +}; + +const commonTraits = { + anonymousId: '50be5c78-6c3f-4b60-be84-97805a316fb1', + phone: '+1234589947', + gender: 'non-binary', + db: '19950715', + lastname: 'Rudderlabs', + firstName: 'Test', + address: { + city: 'Kolkata', + state: 'WB', + zip: '700114', + country: 'IN', + }, +}; + +const contextWithExternalId = { + traits: { + ...commonTraits, + email: 'abc@gmail.com', + }, + externalId: [{ type: 'bluecoreExternalId', id: '54321' }], +}; + +const commonOutputCustomerProperties = { + first_name: 'Test', + last_name: 'Rudderlabs', + sex: 'non-binary', + address: { + city: 'Kolkata', + state: 'WB', + zip: '700114', + country: 'IN', + }, +}; + +const commonOutputHeaders = { + 'Content-Type': 'application/json', +}; + +const anonymousId = '97c46c81-3140-456d-b2a9-690d70aaca35'; +const userId = 'user@1'; +const sentAt = '2021-01-03T17:02:53.195Z'; +const originalTimestamp = '2021-01-03T17:02:53.193Z'; +const commonEndpoint = 'https://api.bluecore.com/api/track/mobile/v1'; + +export const identifyData = [ + { + id: 'bluecore-identify-test-1', + name: 'bluecore', + description: + '[Success]: Identify call with all properties, that creates a customer in bluecore by default', + scenario: 'Business', + successCriteria: + 'Response should containt one payload with event name as customer_patch and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + metadata, + message: generateSimplifiedIdentifyPayload({ + context: { + traits: { ...commonTraits, email: 'abc@gmail.com' }, + }, + anonymousId, + userId, + sentAt, + originalTimestamp, + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + method: 'POST', + endpoint: commonEndpoint, + headers: commonOutputHeaders, + JSON: { + properties: { + distinct_id: 'abc@gmail.com', + customer: { ...commonOutputCustomerProperties, email: 'abc@gmail.com' }, + }, + token: 'dummy_sandbox', + event: 'customer_patch', + }, + }), + metadata: { + sourceType: '', + destinationType: '', + namespace: '', + destinationId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + id: 'bluecore-identify-test-2', + name: 'bluecore', + description: + '[Success]: Identify call with all properties,along with action as identify that mandatorily needs email to link distict_id with customer in bluecore', + scenario: 'Business', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + metadata, + message: generateSimplifiedIdentifyPayload({ + context: { + traits: commonTraits, + }, + traits: { + action: 'identify', + }, + anonymousId, + userId, + sentAt, + originalTimestamp, + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + '[Bluecore] property:: email is required for identify action: Workflow: procWorkflow, Step: prepareIdentifyPayload, ChildStep: undefined, OriginalError: [Bluecore] property:: email is required for identify action', + metadata: { + destinationId: '', + destinationType: '', + namespace: '', + sourceType: '', + }, + statTags: { + destType: 'BLUECORE', + destinationId: '', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'bluecore-identify-test-3', + name: 'bluecore', + description: + '[Success]: Identify call with all properties,along with action as random which is not supported by bluecore for identify action', + scenario: 'Business', + successCriteria: + 'Response should containt one payload with event name as identify and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + metadata, + message: generateSimplifiedIdentifyPayload({ + context: { + traits: commonTraits, + }, + traits: { + action: 'random', + }, + anonymousId, + userId, + sentAt, + originalTimestamp, + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + "[Bluecore] traits.action must be 'identify' for identify action: Workflow: procWorkflow, Step: prepareIdentifyPayload, ChildStep: undefined, OriginalError: [Bluecore] traits.action must be 'identify' for identify action", + metadata: { + destinationId: '', + destinationType: '', + namespace: '', + sourceType: '', + }, + statTags: { + destType: 'BLUECORE', + destinationId: '', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'bluecore-identify-test-4', + name: 'bluecore', + description: + '[Success]: Identify call with all properties, that stitches a customer email with distinct_id in bluecore if action is identify and email is present in traits', + scenario: 'Business', + successCriteria: + 'Response should containt one payload with event name as identify and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + metadata, + message: generateSimplifiedIdentifyPayload({ + context: { + traits: { ...commonTraits, email: 'abc@gmail.com' }, + }, + traits: { + action: 'identify', + }, + anonymousId, + userId, + sentAt, + originalTimestamp, + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + method: 'POST', + endpoint: commonEndpoint, + headers: commonOutputHeaders, + JSON: { + properties: { + distinct_id: 'user@1', + customer: { ...commonOutputCustomerProperties, email: 'abc@gmail.com' }, + }, + token: 'dummy_sandbox', + event: 'identify', + }, + }), + metadata: { + destinationId: '', + destinationType: '', + namespace: '', + sourceType: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + id: 'bluecore-identify-test-5', + name: 'bluecore', + description: + '[Success]: Identify call with all properties and externalId, that creates a customer in bluecore by default, distinct_id is set to externalId value', + scenario: 'Business', + successCriteria: + 'Response should containt one payload with event name as customer_patch and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + metadata, + message: generateSimplifiedIdentifyPayload({ + context: contextWithExternalId, + anonymousId, + userId, + sentAt, + originalTimestamp, + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + method: 'POST', + endpoint: commonEndpoint, + headers: commonOutputHeaders, + JSON: { + properties: { + distinct_id: '54321', + customer: { ...commonOutputCustomerProperties, email: 'abc@gmail.com' }, + }, + token: 'dummy_sandbox', + event: 'customer_patch', + }, + }), + metadata: { + sourceType: '', + destinationType: '', + namespace: '', + destinationId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/bluecore/trackTestData.ts b/test/integrations/destinations/bluecore/trackTestData.ts new file mode 100644 index 00000000000..72d48bf93dc --- /dev/null +++ b/test/integrations/destinations/bluecore/trackTestData.ts @@ -0,0 +1,439 @@ +import { + generateSimplifiedTrackPayload, + generateTrackPayload, + overrideDestination, + transformResultBuilder, +} from '../../testUtils'; + +const destination = { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'BLUECORE', + Config: { + bluecoreNamespace: 'dummy_sandbox', + eventsMapping: [ + { + from: 'ABC Searched', + to: 'search', + }, + { + from: 'testPurchase', + to: 'purchase', + }, + { + from: 'testboth', + to: 'wishlist', + }, + { + from: 'testboth', + to: 'add_to_cart', + }, + ], + }, + Enabled: true, + Transformations: [], + DestinationDefinition: { Config: { cdkV2Enabled: true } }, +}; + +const metadata = { + sourceType: '', + destinationType: '', + namespace: '', + destinationId: '', +}; + +const commonTraits = { + id: 'user@1', + age: '22', + anonymousId: '9c6bd77ea9da3e68', +}; + +const contextWithExternalId = { + traits: { + ...commonTraits, + email: 'abc@gmail.com', + }, + externalId: [{ type: 'bluecoreExternalId', id: '54321' }], +}; + +const commonPropsWithProducts = { + property1: 'value1', + property2: 'value2', + products: [ + { + product_id: '123', + sku: 'sku123', + name: 'Product 1', + price: 100, + quantity: 2, + }, + { + product_id: '124', + sku: 'sku124', + name: 'Product 2', + price: 200, + quantity: 3, + }, + ], +}; + +const commonPropsWithoutProducts = { + property1: 'value1', + property2: 'value2', + product_id: '123', +}; + +const commonOutputHeaders = { + 'Content-Type': 'application/json', +}; + +const eventEndPoint = 'https://api.bluecore.com/api/track/mobile/v1'; + +export const trackTestData = [ + { + id: 'bluecore-track-test-1', + name: 'bluecore', + description: + 'Track event call with custom event with properties not mapped in destination config. This will be sent with its original name', + scenario: 'Business', + successCriteria: + 'Response should contain only event payload and status code should be 200, for the event payload should contain flattened properties in the payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: destination, + metadata, + message: generateSimplifiedTrackPayload({ + type: 'track', + event: 'TestEven001', + userId: 'sajal12', + context: { + traits: { + ...commonTraits, + email: 'test@rudderstack.com', + phone: '9112340375', + }, + }, + properties: commonPropsWithProducts, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'POST', + endpoint: eventEndPoint, + headers: commonOutputHeaders, + JSON: { + properties: { + distinct_id: 'test@rudderstack.com', + customer: { + age: '22', + email: 'test@rudderstack.com', + }, + products: [ + { + name: 'Product 1', + price: 100, + id: '123', + quantity: 2, + }, + { + name: 'Product 2', + price: 200, + id: '124', + quantity: 3, + }, + ], + }, + event: 'TestEven001', + token: 'dummy_sandbox', + }, + userId: '', + }), + metadata, + statusCode: 200, + }, + ], + }, + }, + }, + { + id: 'bluecore-track-test-2', + name: 'bluecore', + description: + 'Track event call with custom event without properties not mapped in destination config. This will be sent with its original name', + scenario: 'Business', + successCriteria: + 'Response should contain only event payload and status code should be 200. As the event paylaod does not contains products, product array will not be sent', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: destination, + metadata, + message: generateSimplifiedTrackPayload({ + type: 'track', + event: 'TestEven001', + userId: 'sajal12', + context: { + traits: { + ...commonTraits, + email: 'test@rudderstack.com', + phone: '9112340375', + }, + }, + properties: commonPropsWithoutProducts, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'POST', + endpoint: eventEndPoint, + headers: commonOutputHeaders, + JSON: { + properties: { + distinct_id: 'test@rudderstack.com', + customer: { + age: '22', + email: 'test@rudderstack.com', + }, + }, + event: 'TestEven001', + token: 'dummy_sandbox', + }, + userId: '', + }), + metadata, + statusCode: 200, + }, + ], + }, + }, + }, + { + id: 'bluecore-track-test-3', + name: 'bluecore', + description: + 'optin event is also considered as a track event, user need to not map it from the UI , it will be sent with the same event name to bluecore', + scenario: 'Business', + successCriteria: + 'Response should contain only event payload and status code should be 200, for the event payload should contain flattened properties in the payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: destination, + metadata, + message: generateSimplifiedTrackPayload({ + type: 'track', + event: 'optin', + userId: 'sajal12', + context: { + traits: { + ...commonTraits, + email: 'test@rudderstack.com', + phone: '9112340375', + }, + }, + properties: commonPropsWithoutProducts, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'POST', + endpoint: eventEndPoint, + headers: commonOutputHeaders, + JSON: { + properties: { + distinct_id: 'test@rudderstack.com', + customer: { + age: '22', + email: 'test@rudderstack.com', + }, + }, + event: 'optin', + token: 'dummy_sandbox', + }, + userId: '', + }), + metadata, + statusCode: 200, + }, + ], + }, + }, + }, + { + id: 'bluecore-track-test-4', + name: 'bluecore', + description: + 'unsubscribe event is also considered as a track event, user need to not map it from the UI , it will be sent with the same event name to bluecore', + scenario: 'Business', + successCriteria: + 'Response should contain only event payload and status code should be 200, for the event payload should contain flattened properties in the payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: destination, + metadata, + message: generateSimplifiedTrackPayload({ + type: 'track', + event: 'unsubscribe', + userId: 'sajal12', + context: { + traits: { + ...commonTraits, + email: 'test@rudderstack.com', + phone: '9112340375', + }, + }, + properties: commonPropsWithoutProducts, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'POST', + endpoint: eventEndPoint, + headers: commonOutputHeaders, + JSON: { + properties: { + distinct_id: 'test@rudderstack.com', + customer: { + age: '22', + email: 'test@rudderstack.com', + }, + }, + event: 'unsubscribe', + token: 'dummy_sandbox', + }, + userId: '', + }), + metadata, + statusCode: 200, + }, + ], + }, + }, + }, + { + id: 'bluecore-track-test-5', + name: 'bluecore', + description: + 'Track event call with with externalId. This will map externalId to distinct_id in the payload', + scenario: 'Business', + successCriteria: + 'Response should contain only event payload and status code should be 200, for the event payload should contain flattened properties in the payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: destination, + metadata, + message: generateSimplifiedTrackPayload({ + type: 'track', + event: 'TestEven001', + userId: 'sajal12', + context: contextWithExternalId, + properties: commonPropsWithProducts, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'POST', + endpoint: eventEndPoint, + headers: commonOutputHeaders, + JSON: { + properties: { + distinct_id: '54321', + customer: { + age: '22', + email: 'abc@gmail.com', + }, + products: [ + { + name: 'Product 1', + price: 100, + id: '123', + quantity: 2, + }, + { + name: 'Product 2', + price: 200, + id: '124', + quantity: 3, + }, + ], + }, + event: 'TestEven001', + token: 'dummy_sandbox', + }, + userId: '', + }), + metadata, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/bluecore/validationTestData.ts b/test/integrations/destinations/bluecore/validationTestData.ts new file mode 100644 index 00000000000..5b81f8c95a8 --- /dev/null +++ b/test/integrations/destinations/bluecore/validationTestData.ts @@ -0,0 +1,150 @@ +const metadata = { + sourceType: '', + destinationType: '', + namespace: '', + destinationId: '', +}; + +const outputStatTags = { + destType: 'BLUECORE', + destinationId: '', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', +}; + +export const validationTestData = [ + { + id: 'bluecore-validation-test-1', + name: 'bluecore', + description: '[Error]: Check for unsupported message type', + scenario: 'Framework', + successCriteria: + 'Response should contain error message and status code should be 400, as we are sending a message type which is not supported by bluecore destination and the error message should be Event type random is not supported', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'BLUECORE', + Config: { + bluecoreNamespace: 'dummy_sandbox', + eventsMapping: [ + { + from: 'ABC Searched', + to: 'search', + }, + ], + }, + Enabled: true, + Transformations: [], + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata, + message: { + userId: 'user123', + type: 'random', + groupId: 'XUepkK', + traits: { + subscribe: true, + }, + context: { + traits: { + email: 'test@rudderstack.com', + phone: '+12 345 678 900', + consent: 'email', + }, + }, + timestamp: '2020-01-21T00:21:34.208Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'message type random is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type random is not supported', + metadata, + statTags: outputStatTags, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'bluecore-validation-test-1', + name: 'bluecore', + description: '[Error]: Check for not finding bluecoreNamespace', + scenario: 'Framework', + successCriteria: + 'Response should contain error message and status code should be 400, as bluecoreNamespace is not found in the destination config', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'BLUECORE', + Config: { + eventsMapping: [ + { + from: 'ABC Searched', + to: 'search', + }, + ], + }, + Enabled: true, + Transformations: [], + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: metadata, + message: { + userId: 'user123', + type: 'random', + groupId: 'XUepkK', + traits: { + subscribe: true, + }, + context: { + traits: { + email: 'test@rudderstack.com', + phone: '+12 345 678 900', + consent: 'email', + }, + }, + timestamp: '2020-01-21T00:21:34.208Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'message type random is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type random is not supported', + metadata, + statTags: outputStatTags, + statusCode: 400, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/branch/processor/data.ts b/test/integrations/destinations/branch/processor/data.ts index 9fed3542358..dc1bdd33bca 100644 --- a/test/integrations/destinations/branch/processor/data.ts +++ b/test/integrations/destinations/branch/processor/data.ts @@ -1490,4 +1490,160 @@ export const data = [ }, }, }, + { + name: 'branch', + description: 'Map event name to branch standard event name in track call', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + branchKey: 'test_branch_key', + eventsMapping: [ + { + from: 'Order Completed', + to: 'PURCHASE', + }, + ], + useNativeSDK: false, + }, + DestinationDefinition: { + DisplayName: 'Branch Metrics', + ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', + Name: 'BRANCH', + }, + Enabled: true, + ID: '1WTpIHpH7NTBgjeiUPW1kCUgZGI', + Name: 'branch test', + Transformations: [], + }, + message: { + anonymousId: 'anonId123', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: true, + advertisingId: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: { + anonymousId: 'anonId123', + email: 'test_user@gmail.com', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Order Completed', + integrations: { + All: true, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + properties: { + name: 't-shirt', + revenue: '10', + currency: 'USD', + key1: 'value1', + key2: 'value2', + order_id: 'order123', + }, + receivedAt: '2020-01-17T10:23:52.688+05:30', + request_ip: '[::1]:64059', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + type: 'track', + userId: 'userId123', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api2.branch.io/v2/event/standard', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + }, + params: {}, + body: { + JSON: { + branch_key: 'test_branch_key', + name: 'PURCHASE', + content_items: [ + { + $product_name: 't-shirt', + }, + ], + event_data: { + revenue: '10', + currency: 'USD', + }, + custom_data: { + key1: 'value1', + key2: 'value2', + order_id: 'order123', + }, + user_data: { + os: 'iOS', + os_version: '14.4.1', + app_version: '1.0.0', + screen_dpi: 2, + developer_identity: 'userId123', + idfa: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + idfv: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + limit_ad_tracking: false, + model: 'AOSP on IA Emulator', + user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + }, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: 'anonId123', + }, + statusCode: 200, + }, + ], + }, + }, + }, ]; diff --git a/test/integrations/destinations/braze/dataDelivery/business.ts b/test/integrations/destinations/braze/dataDelivery/business.ts new file mode 100644 index 00000000000..4997c5ffaeb --- /dev/null +++ b/test/integrations/destinations/braze/dataDelivery/business.ts @@ -0,0 +1,377 @@ +import { ProxyMetdata } from '../../../../../src/types'; +import { ProxyV1TestData } from '../../../testTypes'; +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; + +const BRAZE_USERS_TRACK_ENDPOINT = 'https://rest.iad-03.braze.com/users/track'; + +const partner = 'RudderStack'; + +const headers = { + Accept: 'application/json', + Authorization: 'Bearer api_key', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', +}; + +const BrazeEvent1 = { + name: 'Product List Viewed', + time: '2023-11-30T21:48:45.634Z', + properties: { + products: [ + { + sku: '23-04-52-62-01-18', + name: 'Broman Hoodie', + price: '97.99', + variant: [ + { + id: 39653520310368, + sku: '23-04-52-62-01-18', + grams: 0, + price: '97.99', + title: '(SM)', + weight: 0, + option1: '(SM)', + taxable: true, + position: 1, + tax_code: '', + created_at: '2023-05-18T12:56:22-06:00', + product_id: 6660780884064, + updated_at: '2023-11-30T15:48:43-06:00', + weight_unit: 'kg', + quantity_rule: { + min: 1, + increment: 1, + }, + compare_at_price: '139.99', + inventory_policy: 'deny', + requires_shipping: true, + inventory_quantity: 8, + fulfillment_service: 'manual', + inventory_management: 'shopify', + quantity_price_breaks: [], + old_inventory_quantity: 8, + }, + ], + category: '62 OTHER/RETRO', + currency: 'CAD', + product_id: 6660780884064, + }, + { + sku: '23-04-08-61-01-18', + name: 'Kipling Camo Hoodie', + price: '69.99', + variant: [ + { + id: 39672628740192, + sku: '23-04-08-61-01-18', + grams: 0, + price: '69.99', + title: '(SM)', + weight: 0, + option1: '(SM)', + taxable: true, + position: 1, + tax_code: '', + created_at: '2023-06-28T12:52:56-06:00', + product_id: 6666835853408, + updated_at: '2023-11-30T15:48:43-06:00', + weight_unit: 'kg', + quantity_rule: { + min: 1, + increment: 1, + }, + compare_at_price: '99.99', + inventory_policy: 'deny', + requires_shipping: true, + inventory_quantity: 8, + fulfillment_service: 'manual', + inventory_management: 'shopify', + quantity_price_breaks: [], + old_inventory_quantity: 8, + }, + ], + category: 'Misc', + currency: 'CAD', + product_id: 6666835853408, + }, + ], + }, + _update_existing_only: false, + user_alias: { + alias_name: 'ab7de609-9bec-8e1c-42cd-084a1cd93a4e', + alias_label: 'rudder_id', + }, +}; + +const BrazeEvent2 = { + name: 'Add to Cart', + time: '2020-01-24T11:59:02.403+05:30', + properties: { + revenue: 50, + }, + external_id: 'mickeyMouse', +}; + +const BrazePurchaseEvent = { + product_id: '507f1f77bcf86cd799439011', + price: 0, + currency: 'USD', + quantity: 1, + time: '2020-01-24T11:59:02.402+05:30', + _update_existing_only: false, + user_alias: { + alias_name: 'e6ab2c5e-2cda-44a9-a962-e2f67df78bca', + alias_label: 'rudder_id', + }, +}; + +const metadataArray = [generateMetadata(1), generateMetadata(2), generateMetadata(3)]; + +const errorMessages = { + message_1: '{"events_processed":2,"purchases_processed":1,"message":"success"}', + message_2: + '{"events_processed":1,"message":"success","errors":[{"type":"\'external_id\', \'braze_id\', \'user_alias\', \'email\' or \'phone\' is required","input_array":"events","index":1},{"type":"\'quantity\' is not valid","input_array":"purchases","index":0}]}', + message_3: + '{"message":"Valid data must be provided in the \'attributes\', \'events\', or \'purchases\' fields.","errors":[{"type":"\'external_id\', \'braze_id\', \'user_alias\', \'email\' or \'phone\' is required","input_array":"events","index":0},{"type":"\'external_id\', \'braze_id\', \'user_alias\', \'email\' or \'phone\' is required","input_array":"events","index":1},{"type":"\'quantity\' is not valid","input_array":"purchases","index":0}]}', +}; + +const expectedStatTags = { + errorCategory: 'network', + errorType: 'aborted', + destType: 'BRAZE', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', +}; + +export const testScenariosForV1API: ProxyV1TestData[] = [ + { + id: 'braze_v1_scenario_1', + name: 'braze', + description: + '[Proxy v1 API] :: Test for a valid request - 2 events and 1 purchase event are sent where the destination responds with 200 without any error', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + JSON: { + partner, + events: [BrazeEvent1, BrazeEvent2], + purchases: [BrazePurchaseEvent], + }, + headers, + endpoint: `${BRAZE_USERS_TRACK_ENDPOINT}/valid_scenario1`, + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: errorMessages.message_1, + statusCode: 200, + metadata: generateMetadata(1), + }, + { + error: errorMessages.message_1, + statusCode: 200, + metadata: generateMetadata(2), + }, + { + error: errorMessages.message_1, + statusCode: 200, + metadata: generateMetadata(3), + }, + ], + status: 200, + message: 'Request for braze Processed Successfully', + }, + }, + }, + }, + }, + { + id: 'braze_v1_scenario_2', + name: 'braze', + description: + '[Proxy v1 API] :: Test for a invalid request - 2 events and 1 purchase event are sent where the destination responds with 200 with error for a one of the event and the purchase event', + successCriteria: 'Should return 200 with error for one of the event and the purchase event', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + JSON: { + partner, + events: [{ ...BrazeEvent1, user_alias: undefined }, BrazeEvent2], // modifying first event to be invalid + purchases: [{ ...BrazePurchaseEvent, quantity: 'invalid quantity' }], // modifying purchase event to be invalid + }, + headers, + endpoint: `${BRAZE_USERS_TRACK_ENDPOINT}/invalid_scenario1`, + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: errorMessages.message_2, + statusCode: 200, + metadata: generateMetadata(1), + }, + { + error: errorMessages.message_2, + statusCode: 200, + metadata: generateMetadata(2), + }, + { + error: errorMessages.message_2, + statusCode: 200, + metadata: generateMetadata(3), + }, + ], + status: 200, + message: 'Request for braze Processed Successfully', + }, + }, + }, + }, + }, + { + id: 'braze_v1_scenario_3', + name: 'braze', + description: '[Proxy v1 API] :: Test for an invalid request - all the payloads are invalid', + successCriteria: 'Should return 400 with error for all the payloads', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + JSON: { + partner, + events: [ + { ...BrazeEvent1, user_alias: undefined }, + { ...BrazeEvent2, external_id: undefined }, + ], // modifying first event to be invalid + purchases: [{ ...BrazePurchaseEvent, quantity: 'invalid quantity' }], // modifying purchase event to be invalid + }, + headers, + endpoint: `${BRAZE_USERS_TRACK_ENDPOINT}/invalid_scenario2`, + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: errorMessages.message_3, + statusCode: 400, + metadata: generateMetadata(1), + }, + { + error: errorMessages.message_3, + statusCode: 400, + metadata: generateMetadata(2), + }, + { + error: errorMessages.message_3, + statusCode: 400, + metadata: generateMetadata(3), + }, + ], + statTags: expectedStatTags, + message: 'Request failed for braze with status: 400', + status: 400, + }, + }, + }, + }, + }, + { + id: 'braze_v1_scenario_4', + name: 'braze', + description: '[Proxy v1 API] :: Test for invalid auth scneario', + successCriteria: 'Should return 400 for all the payloads', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + JSON: { + partner, + events: [BrazeEvent1, BrazeEvent2], + purchases: [BrazePurchaseEvent], + }, + headers, + endpoint: `${BRAZE_USERS_TRACK_ENDPOINT}/invalid_scenario3`, + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '{"message":"Invalid API Key"}', + statusCode: 401, + metadata: generateMetadata(1), + }, + { + error: '{"message":"Invalid API Key"}', + statusCode: 401, + metadata: generateMetadata(2), + }, + { + error: '{"message":"Invalid API Key"}', + statusCode: 401, + metadata: generateMetadata(3), + }, + ], + statTags: expectedStatTags, + message: 'Request failed for braze with status: 401', + status: 401, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/braze/dataDelivery/data.ts b/test/integrations/destinations/braze/dataDelivery/data.ts index 8162e75720a..2596a4b9592 100644 --- a/test/integrations/destinations/braze/dataDelivery/data.ts +++ b/test/integrations/destinations/braze/dataDelivery/data.ts @@ -1,6 +1,8 @@ import MockAdapter from 'axios-mock-adapter'; +import { testScenariosForV1API } from './business'; +import { otherScenariosV1 } from './other'; -export const data = [ +export const existingTestData = [ { name: 'braze', description: 'Test 0', @@ -629,7 +631,7 @@ export const data = [ }, output: { response: { - status: 401, + status: 200, body: { output: { status: 401, @@ -662,7 +664,6 @@ export const data = [ module: 'destination', workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', }, - authErrorCategory: '', message: 'Request failed for braze with status: 401', }, }, @@ -770,7 +771,7 @@ export const data = [ }, output: { response: { - status: 401, + status: 200, body: { output: { status: 401, @@ -840,7 +841,6 @@ export const data = [ module: 'destination', workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', }, - authErrorCategory: '', message: 'Request failed for braze with status: 401', }, }, @@ -848,3 +848,5 @@ export const data = [ }, }, ]; + +export const data = [...existingTestData, ...testScenariosForV1API, ...otherScenariosV1]; diff --git a/test/integrations/destinations/braze/dataDelivery/other.ts b/test/integrations/destinations/braze/dataDelivery/other.ts new file mode 100644 index 00000000000..9353899a654 --- /dev/null +++ b/test/integrations/destinations/braze/dataDelivery/other.ts @@ -0,0 +1,204 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; + +const expectedStatTags = { + errorCategory: 'network', + errorType: 'retryable', + destType: 'BRAZE', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', +}; + +export const otherScenariosV1: ProxyV1TestData[] = [ + { + id: 'braze_v1_other_scenario_1', + name: 'braze', + description: + '[Proxy v1 API] :: Scenario for testing Service Unavailable error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_service_not_available', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: + '{"error":{"message":"Service Unavailable","description":"The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later."}}', + statusCode: 503, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + message: 'Request failed for braze with status: 503', + status: 503, + }, + }, + }, + }, + }, + { + id: 'braze_v1_other_scenario_2', + name: 'braze', + description: '[Proxy v1 API] :: Scenario for testing Internal Server error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_internal_server_error', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Internal Server Error"', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + message: 'Request failed for braze with status: 500', + status: 500, + }, + }, + }, + }, + }, + { + id: 'braze_v1_other_scenario_3', + name: 'braze', + description: '[Proxy v1 API] :: Scenario for testing Gateway Time Out error from destination', + successCriteria: 'Should return 504 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_gateway_time_out', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Gateway Timeout"', + statusCode: 504, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + message: 'Request failed for braze with status: 504', + status: 504, + }, + }, + }, + }, + }, + { + id: 'braze_v1_other_scenario_4', + name: 'braze', + description: '[Proxy v1 API] :: Scenario for testing null response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_response', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + message: 'Request failed for braze with status: 500', + status: 500, + }, + }, + }, + }, + }, + { + id: 'braze_v1_other_scenario_5', + name: 'braze', + description: + '[Proxy v1 API] :: Scenario for testing null and no status response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_and_no_status', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + message: 'Request failed for braze with status: 500', + status: 500, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/braze/network.ts b/test/integrations/destinations/braze/network.ts index 40d75c9d343..ae093ce1f48 100644 --- a/test/integrations/destinations/braze/network.ts +++ b/test/integrations/destinations/braze/network.ts @@ -524,4 +524,104 @@ const deleteNwData = [ }, }, ]; -export const networkCallsData = [...deleteNwData, ...dataDeliveryMocksData]; + +const BRAZE_USERS_TRACK_ENDPOINT = 'https://rest.iad-03.braze.com/users/track'; + +// New Mocks for Braze +const updatedDataDeliveryMocksData = [ + { + description: + 'Mock response from destination depicting a valid request for 2 valid events and 1 purchase event', + httpReq: { + url: `${BRAZE_USERS_TRACK_ENDPOINT}/valid_scenario1`, + method: 'POST', + }, + httpRes: { + data: { + events_processed: 2, + purchases_processed: 1, + message: 'success', + }, + status: 200, + }, + }, + + { + description: + 'Mock response from destination depicting a request with 1 valid and 1 invalid event and 1 invalid purchase event', + httpReq: { + url: `${BRAZE_USERS_TRACK_ENDPOINT}/invalid_scenario1`, + method: 'POST', + }, + httpRes: { + data: { + events_processed: 1, + message: 'success', + errors: [ + { + type: "'external_id', 'braze_id', 'user_alias', 'email' or 'phone' is required", + input_array: 'events', + index: 1, + }, + { + type: "'quantity' is not valid", + input_array: 'purchases', + index: 0, + }, + ], + }, + status: 200, + }, + }, + + { + description: + 'Mock response from destination depicting a request with all the payloads are invalid', + httpReq: { + url: `${BRAZE_USERS_TRACK_ENDPOINT}/invalid_scenario2`, + method: 'POST', + }, + httpRes: { + data: { + message: + "Valid data must be provided in the 'attributes', 'events', or 'purchases' fields.", + errors: [ + { + type: "'external_id', 'braze_id', 'user_alias', 'email' or 'phone' is required", + input_array: 'events', + index: 0, + }, + { + type: "'external_id', 'braze_id', 'user_alias', 'email' or 'phone' is required", + input_array: 'events', + index: 1, + }, + { + type: "'quantity' is not valid", + input_array: 'purchases', + index: 0, + }, + ], + }, + status: 400, + }, + }, + { + description: 'Mock response from destination depicting a request with invalid credentials', + httpReq: { + url: `${BRAZE_USERS_TRACK_ENDPOINT}/invalid_scenario3`, + method: 'POST', + }, + httpRes: { + data: { + message: 'Invalid API Key', + }, + status: 401, + }, + }, +]; +export const networkCallsData = [ + ...deleteNwData, + ...dataDeliveryMocksData, + ...updatedDataDeliveryMocksData, +]; diff --git a/test/integrations/destinations/campaign_manager/dataDelivery/business.ts b/test/integrations/destinations/campaign_manager/dataDelivery/business.ts new file mode 100644 index 00000000000..e663f3212a8 --- /dev/null +++ b/test/integrations/destinations/campaign_manager/dataDelivery/business.ts @@ -0,0 +1,606 @@ +import { ProxyMetdata } from '../../../../../src/types'; +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV0Payload, generateProxyV1Payload } from '../../../testUtils'; + +// Boilerplate data for the test cases +// ====================================== + +const commonHeaders = { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', +}; + +const encryptionInfo = { + kind: 'dfareporting#encryptionInfo', + encryptionSource: 'AD_SERVING', + encryptionEntityId: '3564523', + encryptionEntityType: 'DCM_ACCOUNT', +}; + +const testConversion1 = { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, +}; + +const testConversion2 = { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 8, + gclid: '321', + limitAdTracking: true, + childDirectedTreatment: true, +}; + +const commonRequestParameters = { + headers: commonHeaders, + JSON: { + kind: 'dfareporting#conversionsBatchInsertRequest', + encryptionInfo, + conversions: [testConversion1, testConversion2], + }, +}; + +const proxyMetdata1: ProxyMetdata = { + jobId: 1, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, +}; + +const proxyMetdata2: ProxyMetdata = { + jobId: 2, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, +}; + +const metadataArray = [proxyMetdata1, proxyMetdata2]; + +// Test scenarios for the test cases +// =================================== + +export const testScenariosForV0API = [ + { + id: 'cm360_v0_scenario_1', + name: 'campaign_manager', + description: + '[Proxy v0 API] :: Test for a valid request with a successful 200 response from the destination', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://dfareporting.googleapis.com/test_url_for_valid_request', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: '[CAMPAIGN_MANAGER Response Handler] - Request Processed Successfully', + destinationResponse: { + response: { + hasFailures: false, + status: [ + { + conversion: testConversion1, + kind: 'dfareporting#conversionStatus', + }, + { + conversion: testConversion2, + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + }, + }, + }, + }, + }, + }, + { + id: 'cm360_v0_scenario_2', + name: 'campaign_manager', + description: + '[Proxy v0 API] :: Test for a valid request - where the destination responds with 200 with error for conversion 2', + successCriteria: 'Should return 400 with error and with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://dfareporting.googleapis.com/test_url_for_invalid_request_conversion_2', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 400, + body: { + output: { + status: 400, + message: 'Campaign Manager: Aborting during CAMPAIGN_MANAGER response transformation', + destinationResponse: { + response: { + hasFailures: true, + status: [ + { + conversion: testConversion1, + kind: 'dfareporting#conversionStatus', + }, + { + conversion: testConversion2, + errors: [ + { + code: 'NOT_FOUND', + message: 'Floodlight config id: 213123123 was not found.', + kind: 'dfareporting#conversionError', + }, + ], + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + }, + statTags: { + errorCategory: 'network', + errorType: 'aborted', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + }, + }, + }, + }, + }, + { + id: 'cm360_v0_scenario_3', + name: 'campaign_manager', + description: + '[Proxy v0 API] :: Test for a valid request - where the destination responds with 200 with error for both conversions', + successCriteria: 'Should return 400 with error and with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: + 'https://dfareporting.googleapis.com/test_url_for_invalid_request_both_conversions', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 400, + body: { + output: { + status: 400, + message: 'Campaign Manager: Aborting during CAMPAIGN_MANAGER response transformation', + destinationResponse: { + response: { + hasFailures: true, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + errors: [ + { + code: 'INVALID_ARGUMENT', + message: 'Gclid is not valid.', + kind: 'dfareporting#conversionError', + }, + ], + kind: 'dfareporting#conversionStatus', + }, + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 8, + gclid: '321', + limitAdTracking: true, + childDirectedTreatment: true, + }, + errors: [ + { + code: 'NOT_FOUND', + message: 'Floodlight config id: 213123123 was not found.', + kind: 'dfareporting#conversionError', + }, + ], + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + }, + statTags: { + errorCategory: 'network', + errorType: 'aborted', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + }, + }, + }, + }, + }, +]; + +export const testScenariosForV1API: ProxyV1TestData[] = [ + { + id: 'cm360_v1_scenario_1', + name: 'campaign_manager', + description: + '[Proxy v1 API] :: Test for a valid request - where the destination responds with 200 without any error', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: 'https://dfareporting.googleapis.com/test_url_for_valid_request', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: '[CAMPAIGN_MANAGER Response V1 Handler] - Request Processed Successfully', + destinationResponse: { + response: { + hasFailures: false, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + kind: 'dfareporting#conversionStatus', + }, + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 8, + gclid: '321', + limitAdTracking: true, + childDirectedTreatment: true, + }, + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + }, + response: [ + { + statusCode: 200, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, + }, + error: 'success', + }, + { + statusCode: 200, + metadata: { + jobId: 2, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, + }, + error: 'success', + }, + ], + }, + }, + }, + }, + }, + { + id: 'cm360_v1_scenario_2', + name: 'campaign_manager', + description: + '[Proxy v1 API] :: Test for a valid request - where the destination responds with 200 with error for conversion 2', + successCriteria: 'Should return 200 with partial failures within the response payload', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: + 'https://dfareporting.googleapis.com/test_url_for_invalid_request_conversion_2', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: '[CAMPAIGN_MANAGER Response V1 Handler] - Request Processed Successfully', + destinationResponse: { + response: { + hasFailures: true, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + kind: 'dfareporting#conversionStatus', + }, + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 8, + gclid: '321', + limitAdTracking: true, + childDirectedTreatment: true, + }, + errors: [ + { + code: 'NOT_FOUND', + message: 'Floodlight config id: 213123123 was not found.', + kind: 'dfareporting#conversionError', + }, + ], + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + }, + response: [ + { + statusCode: 200, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, + }, + error: 'success', + }, + { + statusCode: 400, + metadata: { + jobId: 2, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, + }, + error: 'Floodlight config id: 213123123 was not found., ', + }, + ], + }, + }, + }, + }, + }, + { + id: 'cm360_v1_scenario_3', + name: 'campaign_manager', + description: + '[Proxy v0 API] :: Test for a valid request - where the destination responds with 200 with error for both conversions', + successCriteria: 'Should return 200 with all failures within the response payload', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: + 'https://dfareporting.googleapis.com/test_url_for_invalid_request_both_conversions', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: '[CAMPAIGN_MANAGER Response V1 Handler] - Request Processed Successfully', + destinationResponse: { + response: { + hasFailures: true, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + errors: [ + { + code: 'INVALID_ARGUMENT', + message: 'Gclid is not valid.', + kind: 'dfareporting#conversionError', + }, + ], + kind: 'dfareporting#conversionStatus', + }, + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 8, + gclid: '321', + limitAdTracking: true, + childDirectedTreatment: true, + }, + errors: [ + { + code: 'NOT_FOUND', + message: 'Floodlight config id: 213123123 was not found.', + kind: 'dfareporting#conversionError', + }, + ], + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + }, + response: [ + { + statusCode: 400, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, + }, + error: 'Gclid is not valid., ', + }, + { + statusCode: 400, + metadata: { + jobId: 2, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, + }, + error: 'Floodlight config id: 213123123 was not found., ', + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/campaign_manager/dataDelivery/data.ts b/test/integrations/destinations/campaign_manager/dataDelivery/data.ts index 601ad56401f..0373ca99926 100644 --- a/test/integrations/destinations/campaign_manager/dataDelivery/data.ts +++ b/test/integrations/destinations/campaign_manager/dataDelivery/data.ts @@ -1,604 +1,12 @@ +import { testScenariosForV0API, testScenariosForV1API } from './business'; +import { v0oauthScenarios, v1oauthScenarios } from './oauth'; +import { otherScenariosV0, otherScenariosV1 } from './other'; + export const data = [ - { - name: 'campaign_manager', - description: 'Sucess insert request V0', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: - 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437689/conversions/batchinsert', - headers: { - Authorization: 'Bearer dummyApiKey', - 'Content-Type': 'application/json', - }, - params: {}, - body: { - JSON: { - kind: 'dfareporting#conversionsBatchInsertRequest', - encryptionInfo: { - kind: 'dfareporting#encryptionInfo', - encryptionSource: 'AD_SERVING', - encryptionEntityId: '3564523', - encryptionEntityType: 'DCM_ACCOUNT', - }, - conversions: [ - { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - }, - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: { - output: { - status: 200, - message: '[CAMPAIGN_MANAGER Response Handler] - Request Processed Successfully', - destinationResponse: { - response: { - hasFailures: false, - status: [ - { - conversion: { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - kind: 'dfareporting#conversionStatus', - }, - ], - kind: 'dfareporting#conversionsBatchInsertResponse', - }, - status: 200, - }, - }, - }, - }, - }, - }, - { - name: 'campaign_manager', - description: 'Failure insert request', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: - 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437690/conversions/batchinsert', - headers: { - Authorization: 'Bearer dummyApiKey', - 'Content-Type': 'application/json', - }, - params: {}, - body: { - JSON: { - kind: 'dfareporting#conversionsBatchInsertRequest', - encryptionInfo: { - kind: 'dfareporting#encryptionInfo', - encryptionSource: 'AD_SERVING', - encryptionEntityId: '3564523', - encryptionEntityType: 'DCM_ACCOUNT', - }, - conversions: [ - { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - }, - method: 'POST', - }, - }, - output: { - response: { - status: 400, - body: { - output: { - status: 400, - message: 'Campaign Manager: Aborting during CAMPAIGN_MANAGER response transformation', - statTags: { - errorCategory: 'network', - errorType: 'aborted', - destType: 'CAMPAIGN_MANAGER', - module: 'destination', - implementation: 'native', - feature: 'dataDelivery', - destinationId: 'Non-determininable', - workspaceId: 'Non-determininable', - }, - destinationResponse: { - response: { - hasFailures: true, - status: [ - { - conversion: { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - errors: [ - { - code: 'NOT_FOUND', - message: 'Floodlight config id: 213123123 was not found.', - kind: 'dfareporting#conversionError', - }, - ], - kind: 'dfareporting#conversionStatus', - }, - ], - kind: 'dfareporting#conversionsBatchInsertResponse', - }, - status: 200, - }, - }, - }, - }, - }, - }, - { - name: 'campaign_manager', - description: 'Failure insert request Aborted', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: - 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437691/conversions/batchinsert', - headers: { - Authorization: 'Bearer dummyApiKey', - 'Content-Type': 'application/json', - }, - params: {}, - body: { - JSON: { - kind: 'dfareporting#conversionsBatchInsertRequest', - encryptionInfo: { - kind: 'dfareporting#encryptionInfo', - encryptionSource: 'AD_SERVING', - encryptionEntityId: '3564523', - encryptionEntityType: 'DCM_ACCOUNT', - }, - conversions: [ - { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - }, - method: 'POST', - }, - }, - output: { - response: { - status: 400, - body: { - output: { - status: 400, - message: 'Campaign Manager: Aborting during CAMPAIGN_MANAGER response transformation', - statTags: { - errorCategory: 'network', - errorType: 'aborted', - destType: 'CAMPAIGN_MANAGER', - module: 'destination', - implementation: 'native', - feature: 'dataDelivery', - destinationId: 'Non-determininable', - workspaceId: 'Non-determininable', - }, - destinationResponse: { - response: { - hasFailures: true, - status: [ - { - conversion: { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - errors: [ - { - code: 'INVALID_ARGUMENT', - message: 'Floodlight config id: 213123123 was not found.', - kind: 'dfareporting#conversionError', - }, - ], - kind: 'dfareporting#conversionStatus', - }, - ], - kind: 'dfareporting#conversionsBatchInsertResponse', - }, - status: 200, - }, - }, - }, - }, - }, - }, - { - name: 'campaign_manager', - description: 'Sucess and fail insert request v1', - feature: 'dataDelivery', - module: 'destination', - version: 'v1', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: - 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437692/conversions/batchinsert', - headers: { - Authorization: 'Bearer dummyApiKey', - 'Content-Type': 'application/json', - }, - params: {}, - body: { - JSON: { - kind: 'dfareporting#conversionsBatchInsertRequest', - conversions: [ - { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 8, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - metadata: [ - { - jobId: 2, - attemptNum: 0, - userId: '', - sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', - destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', - workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', - secret: { - access_token: 'secret', - refresh_token: 'refresh', - developer_token: 'developer_Token', - }, - }, - { - jobId: 3, - attemptNum: 1, - userId: '', - sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', - destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', - workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', - secret: { - access_token: 'secret', - refresh_token: 'refresh', - developer_token: 'developer_Token', - }, - }, - ], - files: {}, - }, - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: { - output: { - status: 200, - message: '[CAMPAIGN_MANAGER Response V1 Handler] - Request Processed Successfully', - destinationResponse: { - response: { - hasFailures: true, - status: [ - { - conversion: { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - kind: 'dfareporting#conversionStatus', - errors: [ - { - code: 'INVALID_ARGUMENT', - kind: 'dfareporting#conversionError', - message: 'Floodlight config id: 213123123 was not found.', - }, - ], - }, - { - conversion: { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 8, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - kind: 'dfareporting#conversionStatus', - }, - ], - kind: 'dfareporting#conversionsBatchInsertResponse', - }, - status: 200, - rudderJobMetadata: [ - { - jobId: 2, - attemptNum: 0, - userId: '', - sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', - destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', - workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', - secret: { - access_token: 'secret', - refresh_token: 'refresh', - developer_token: 'developer_Token', - }, - }, - { - jobId: 3, - attemptNum: 1, - userId: '', - sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', - destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', - workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', - secret: { - access_token: 'secret', - refresh_token: 'refresh', - developer_token: 'developer_Token', - }, - }, - ], - }, - response: [ - { - error: 'Floodlight config id: 213123123 was not found., ', - statusCode: 400, - metadata: { - attemptNum: 0, - destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', - jobId: 2, - secret: { - access_token: 'secret', - developer_token: 'developer_Token', - refresh_token: 'refresh', - }, - sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', - userId: '', - workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', - }, - }, - { - error: 'success', - metadata: { - attemptNum: 1, - destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', - jobId: 3, - secret: { - access_token: 'secret', - developer_token: 'developer_Token', - refresh_token: 'refresh', - }, - sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', - userId: '', - workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', - }, - statusCode: 200, - }, - ], - }, - }, - }, - }, - }, - { - name: 'campaign_manager', - description: 'Sucess insert request v1', - feature: 'dataDelivery', - module: 'destination', - version: 'v1', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: - 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/43770/conversions/batchinsert', - headers: { - Authorization: 'Bearer dummyApiKey', - 'Content-Type': 'application/json', - }, - params: {}, - body: { - JSON: { - kind: 'dfareporting#conversionsBatchInsertRequest', - encryptionInfo: { - kind: 'dfareporting#encryptionInfo', - encryptionSource: 'AD_SERVING', - encryptionEntityId: '3564523', - encryptionEntityType: 'DCM_ACCOUNT', - }, - conversions: [ - { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - metadata: { - jobId: 2, - attemptNum: 0, - userId: '', - sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', - destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', - workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', - secret: { - access_token: 'secret', - refresh_token: 'refresh', - developer_token: 'developer_Token', - }, - }, - files: {}, - }, - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: { - output: { - status: 200, - message: '[CAMPAIGN_MANAGER Response V1 Handler] - Request Processed Successfully', - destinationResponse: { - response: { - hasFailures: false, - status: [ - { - conversion: { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - kind: 'dfareporting#conversionStatus', - }, - ], - kind: 'dfareporting#conversionsBatchInsertResponse', - }, - status: 200, - rudderJobMetadata: { - jobId: 2, - attemptNum: 0, - userId: '', - sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', - destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', - workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', - secret: { - access_token: 'secret', - refresh_token: 'refresh', - developer_token: 'developer_Token', - }, - }, - }, - response: [ - { - error: 'success', - statusCode: 200, - }, - ], - }, - }, - }, - }, - }, + ...testScenariosForV0API, + ...testScenariosForV1API, + ...v0oauthScenarios, + ...v1oauthScenarios, + ...otherScenariosV0, + ...otherScenariosV1, ]; diff --git a/test/integrations/destinations/campaign_manager/dataDelivery/oauth.ts b/test/integrations/destinations/campaign_manager/dataDelivery/oauth.ts new file mode 100644 index 00000000000..288a06bfe6f --- /dev/null +++ b/test/integrations/destinations/campaign_manager/dataDelivery/oauth.ts @@ -0,0 +1,558 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV1Payload, generateProxyV0Payload } from '../../../testUtils'; +// Boilerplat data for the test cases +// ====================================== + +const commonHeaders = { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', +}; + +const encryptionInfo = { + kind: 'dfareporting#encryptionInfo', + encryptionSource: 'AD_SERVING', + encryptionEntityId: '3564523', + encryptionEntityType: 'DCM_ACCOUNT', +}; + +const testConversion1 = { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, +}; + +const testConversion2 = { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 8, + gclid: '321', + limitAdTracking: true, + childDirectedTreatment: true, +}; + +const commonRequestParameters = { + headers: commonHeaders, + JSON: { + kind: 'dfareporting#conversionsBatchInsertRequest', + encryptionInfo, + conversions: [testConversion1, testConversion2], + }, +}; + +// Test scenarios for the test cases +// =================================== + +export const v0oauthScenarios = [ + { + id: 'cm360_v0_oauth_scenario_1', + name: 'campaign_manager', + description: + '[Proxy v0 API] :: Oauth where valid credentials are missing as mock response from destination', + successCriteria: + 'Since the error from the destination is 401 - the proxy should return 500 with authErrorCategory as REFRESH_TOKEN', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://googleapis.com/test_url_for_credentials_missing', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + 'Campaign Manager: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project. during CAMPAIGN_MANAGER response transformation 3', + destinationResponse: { + response: { + error: { + code: 401, + message: + 'Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.', + errors: [ + { + message: 'Login Required.', + domain: 'global', + reason: 'required', + location: 'Authorization', + locationType: 'header', + }, + ], + status: 'UNAUTHENTICATED', + details: [ + { + '@type': 'type.googleapis.com/google.rpc.ErrorInfo', + reason: 'CREDENTIALS_MISSING', + domain: 'googleapis.com', + metadata: { + method: 'google.ads.xfa.op.v4.DfareportingConversions.Batchinsert', + service: 'googleapis.com', + }, + }, + ], + }, + }, + status: 401, + }, + statTags: { + errorCategory: 'network', + errorType: 'aborted', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + authErrorCategory: 'REFRESH_TOKEN', + }, + }, + }, + }, + }, + { + id: 'cm360_v0_oauth_scenario_2', + name: 'campaign_manager', + description: + '[Proxy v0 API] :: Oauth where ACCESS_TOKEN_SCOPE_INSUFFICIENT error as mock response from destination', + successCriteria: + 'Since the error from the destination is 403 - the proxy should return 500 with authErrorCategory as AUTH_STATUS_INACTIVE', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://googleapis.com/test_url_for_access_token_scope_insufficient', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + 'Campaign Manager: Request had insufficient authentication scopes. during CAMPAIGN_MANAGER response transformation 3', + destinationResponse: { + response: { + error: { + code: 403, + message: 'Request had insufficient authentication scopes.', + errors: [ + { + message: 'Insufficient Permission', + domain: 'global', + reason: 'insufficientPermissions', + }, + ], + status: 'PERMISSION_DENIED', + details: [ + { + '@type': 'type.googleapis.com/google.rpc.ErrorInfo', + reason: 'ACCESS_TOKEN_SCOPE_INSUFFICIENT', + domain: 'googleapis.com', + metadata: { + service: 'gmail.googleapis.com', + method: 'caribou.api.proto.MailboxService.GetProfile', + }, + }, + ], + }, + }, + status: 403, + }, + statTags: { + errorCategory: 'network', + errorType: 'aborted', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + authErrorCategory: 'AUTH_STATUS_INACTIVE', + }, + }, + }, + }, + }, + { + id: 'cm360_v0_oauth_scenario_3', + name: 'campaign_manager', + description: + '[Proxy v0 API] :: Oauth where google.auth.exceptions.RefreshError invalid_grant error as mock response from destination', + successCriteria: + 'Since the error from the destination is 403 - the proxy should return 500 with authErrorCategory as AUTH_STATUS_INACTIVE', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://googleapis.com/test_url_for_invalid_grant', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + 'Campaign Manager: invalid_grant during CAMPAIGN_MANAGER response transformation 3', + destinationResponse: { + response: { + error: { + code: 403, + message: 'invalid_grant', + error_description: 'Bad accesss', + }, + }, + status: 403, + }, + statTags: { + errorCategory: 'network', + errorType: 'aborted', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + authErrorCategory: 'AUTH_STATUS_INACTIVE', + }, + }, + }, + }, + }, + { + id: 'cm360_v0_oauth_scenario_4', + name: 'campaign_manager', + description: + '[Proxy v0 API] :: Oauth where google.auth.exceptions.RefreshError refresh error as mock response from destination', + successCriteria: 'Should return 500 with authErrorCategory as AUTH_STATUS_INACTIVE', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://googleapis.com/test_url_for_refresh_error', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + 'Campaign Manager: undefined during CAMPAIGN_MANAGER response transformation 3', + destinationResponse: { + response: { + error: 'unauthorized', + error_description: 'Access token expired: 2020-10-20T12:00:00.000Z', + }, + status: 401, + }, + statTags: { + errorCategory: 'network', + errorType: 'aborted', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + authErrorCategory: 'REFRESH_TOKEN', + }, + }, + }, + }, + }, +]; + +export const v1oauthScenarios: ProxyV1TestData[] = [ + { + id: 'cm360_v1_oauth_scenario_1', + name: 'campaign_manager', + description: + '[Proxy v1 API] :: Oauth where valid credentials are missing as mock response from destination', + successCriteria: + 'Since the error from the destination is 401 - the proxy should return 500 with authErrorCategory as REFRESH_TOKEN', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + ...commonRequestParameters, + endpoint: 'https://googleapis.com/test_url_for_credentials_missing', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 401, + body: { + output: { + response: [ + { + error: + '{"error":{"code":401,"message":"Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.","errors":[{"message":"Login Required.","domain":"global","reason":"required","location":"Authorization","locationType":"header"}],"status":"UNAUTHENTICATED","details":[{"@type":"type.googleapis.com/google.rpc.ErrorInfo","reason":"CREDENTIALS_MISSING","domain":"googleapis.com","metadata":{"method":"google.ads.xfa.op.v4.DfareportingConversions.Batchinsert","service":"googleapis.com"}}]}}', + statusCode: 401, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: false, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'aborted', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + authErrorCategory: 'REFRESH_TOKEN', + message: + 'Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation', + status: 401, + }, + }, + }, + }, + }, + { + id: 'cm360_v1_oauth_scenario_2', + name: 'campaign_manager', + description: + '[Proxy v1 API] :: Oauth where ACCESS_TOKEN_SCOPE_INSUFFICIENT error as mock response from destination', + successCriteria: + 'Since the error from the destination is 403 - the proxy should return 500 with authErrorCategory as AUTH_STATUS_INACTIVE', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + ...commonRequestParameters, + endpoint: 'https://googleapis.com/test_url_for_access_token_scope_insufficient', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 403, + body: { + output: { + response: [ + { + error: + '{"error":{"code":403,"message":"Request had insufficient authentication scopes.","errors":[{"message":"Insufficient Permission","domain":"global","reason":"insufficientPermissions"}],"status":"PERMISSION_DENIED","details":[{"@type":"type.googleapis.com/google.rpc.ErrorInfo","reason":"ACCESS_TOKEN_SCOPE_INSUFFICIENT","domain":"googleapis.com","metadata":{"service":"gmail.googleapis.com","method":"caribou.api.proto.MailboxService.GetProfile"}}]}}', + statusCode: 403, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: false, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'aborted', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + authErrorCategory: 'AUTH_STATUS_INACTIVE', + message: + 'Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation', + status: 403, + }, + }, + }, + }, + }, + { + id: 'cm360_v1_oauth_scenario_3', + name: 'campaign_manager', + description: + '[Proxy v1 API] :: Oauth where google.auth.exceptions.RefreshError invalid_grant error as mock response from destination', + successCriteria: + 'Since the error from the destination is 403 - the proxy should return 500 with authErrorCategory as AUTH_STATUS_INACTIVE', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + ...commonRequestParameters, + endpoint: 'https://googleapis.com/test_url_for_invalid_grant', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 403, + body: { + output: { + response: [ + { + error: + '{"error":{"code":403,"message":"invalid_grant","error_description":"Bad accesss"}}', + statusCode: 403, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: false, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'aborted', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + authErrorCategory: 'AUTH_STATUS_INACTIVE', + message: + 'Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation', + status: 403, + }, + }, + }, + }, + }, + { + id: 'cm360_v1_oauth_scenario_4', + name: 'campaign_manager', + description: + '[Proxy v1 API] :: Oauth where google.auth.exceptions.RefreshError refresh error as mock response from destination', + successCriteria: 'Should return 500 with authErrorCategory as AUTH_STATUS_INACTIVE', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + ...commonRequestParameters, + endpoint: 'https://googleapis.com/test_url_for_refresh_error', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 401, + body: { + output: { + response: [ + { + error: + '{"error":"unauthorized","error_description":"Access token expired: 2020-10-20T12:00:00.000Z"}', + statusCode: 401, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: false, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'aborted', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + authErrorCategory: 'REFRESH_TOKEN', + message: + 'Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation', + status: 401, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/campaign_manager/dataDelivery/other.ts b/test/integrations/destinations/campaign_manager/dataDelivery/other.ts new file mode 100644 index 00000000000..1c0c45728c0 --- /dev/null +++ b/test/integrations/destinations/campaign_manager/dataDelivery/other.ts @@ -0,0 +1,529 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV0Payload, generateProxyV1Payload } from '../../../testUtils'; + +export const otherScenariosV0 = [ + { + id: 'cm360_v0_other_scenario_1', + name: 'campaign_manager', + description: + '[Proxy v0 API] :: Scenario for testing Service Unavailable error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + endpoint: 'https://random_test_url/test_for_service_not_available', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + 'Campaign Manager: Service Unavailable during CAMPAIGN_MANAGER response transformation 3', + destinationResponse: { + response: { + error: { + message: 'Service Unavailable', + description: + 'The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later.', + }, + }, + status: 503, + }, + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + }, + }, + }, + }, + }, + { + id: 'cm360_v0_other_scenario_2', + name: 'campaign_manager', + description: '[Proxy v0 API] :: Scenario for testing Internal Server error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + endpoint: 'https://random_test_url/test_for_internal_server_error', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + 'Campaign Manager: undefined during CAMPAIGN_MANAGER response transformation 3', + destinationResponse: { + response: 'Internal Server Error', + status: 500, + }, + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + }, + }, + }, + }, + }, + { + id: 'cm360_v0_other_scenario_3', + name: 'campaign_manager', + description: '[Proxy v0 API] :: Scenario for testing Gateway Time Out error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + endpoint: 'https://random_test_url/test_for_gateway_time_out', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + 'Campaign Manager: undefined during CAMPAIGN_MANAGER response transformation 3', + destinationResponse: { + response: 'Gateway Timeout', + status: 504, + }, + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + }, + }, + }, + }, + }, + { + id: 'cm360_v0_other_scenario_4', + name: 'campaign_manager', + description: '[Proxy v0 API] :: Scenario for testing null response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + endpoint: 'https://random_test_url/test_for_null_response', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + 'Campaign Manager: undefined during CAMPAIGN_MANAGER response transformation 3', + destinationResponse: { + response: '', + status: 500, + }, + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + }, + }, + }, + }, + }, + { + id: 'cm360_v0_other_scenario_5', + name: 'campaign_manager', + description: + '[Proxy v0 API] :: Scenario for testing null and no status response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + endpoint: 'https://random_test_url/test_for_null_and_no_status', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + 'Campaign Manager: undefined during CAMPAIGN_MANAGER response transformation 3', + destinationResponse: { + response: '', + status: 500, + }, + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + }, + }, + }, + }, + }, +]; + +export const otherScenariosV1: ProxyV1TestData[] = [ + { + id: 'cm360_v1_other_scenario_1', + name: 'campaign_manager', + description: + '[Proxy v1 API] :: Scenario for testing Service Unavailable error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_service_not_available', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: + '{"error":{"message":"Service Unavailable","description":"The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later."}}', + statusCode: 503, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: false, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + message: + 'Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation', + status: 503, + }, + }, + }, + }, + }, + { + id: 'cm360_v1_other_scenario_2', + name: 'campaign_manager', + description: '[Proxy v1 API] :: Scenario for testing Internal Server error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_internal_server_error', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Internal Server Error"', + statusCode: 500, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: false, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + message: + 'Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation', + status: 500, + }, + }, + }, + }, + }, + { + id: 'cm360_v1_other_scenario_3', + name: 'campaign_manager', + description: '[Proxy v1 API] :: Scenario for testing Gateway Time Out error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_gateway_time_out', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Gateway Timeout"', + statusCode: 504, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: false, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + message: + 'Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation', + status: 504, + }, + }, + }, + }, + }, + { + id: 'cm360_v1_other_scenario_4', + name: 'campaign_manager', + description: '[Proxy v1 API] :: Scenario for testing null response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_response', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: false, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + message: + 'Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation', + status: 500, + }, + }, + }, + }, + }, + { + id: 'cm360_v1_other_scenario_5', + name: 'campaign_manager', + description: + '[Proxy v1 API] :: Scenario for testing null and no status response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_and_no_status', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata: { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: false, + }, + }, + ], + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + message: + 'Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation', + status: 500, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/campaign_manager/network.ts b/test/integrations/destinations/campaign_manager/network.ts index ddecbaf8fa0..b7c23012481 100644 --- a/test/integrations/destinations/campaign_manager/network.ts +++ b/test/integrations/destinations/campaign_manager/network.ts @@ -1,49 +1,70 @@ -const Data = [ +const commonHeaders = { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', +}; + +const encryptionInfo = { + kind: 'dfareporting#encryptionInfo', + encryptionSource: 'AD_SERVING', + encryptionEntityId: '3564523', + encryptionEntityType: 'DCM_ACCOUNT', +}; + +const testConversion1 = { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, +}; + +const testConversion2 = { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 8, + gclid: '321', + limitAdTracking: true, + childDirectedTreatment: true, +}; + +const commonRequestParameters = { + headers: commonHeaders, + JSON: { + kind: 'dfareporting#conversionsBatchInsertRequest', + encryptionInfo, + conversions: [testConversion1, testConversion2], + }, +}; + +// MOCK DATA +const businessMockData = [ { + description: 'Mock response from destination depicting a valid request', httpReq: { method: 'post', - url: 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437689/conversions/batchinsert', + url: 'https://dfareporting.googleapis.com/test_url_for_valid_request', data: { kind: 'dfareporting#conversionsBatchInsertRequest', - encryptionInfo: { - kind: 'dfareporting#encryptionInfo', - encryptionSource: 'AD_SERVING', - encryptionEntityId: '3564523', - encryptionEntityType: 'DCM_ACCOUNT', - }, - conversions: [ - { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - ], - }, - headers: { - Authorization: 'Bearer dummyApiKey', - 'Content-Type': 'application/json', + encryptionInfo, + conversions: [testConversion1, testConversion2], }, + headers: commonHeaders, }, httpRes: { data: { hasFailures: false, status: [ { - conversion: { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, + conversion: testConversion1, + kind: 'dfareporting#conversionStatus', + }, + { + conversion: testConversion2, kind: 'dfareporting#conversionStatus', }, ], @@ -54,50 +75,28 @@ const Data = [ }, }, { + description: + 'Mock response from destination depicting a request with 1 valid and 1 invalid conversion', httpReq: { method: 'post', - url: 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437690/conversions/batchinsert', + url: 'https://dfareporting.googleapis.com/test_url_for_invalid_request_conversion_2', data: { kind: 'dfareporting#conversionsBatchInsertRequest', - encryptionInfo: { - kind: 'dfareporting#encryptionInfo', - encryptionSource: 'AD_SERVING', - encryptionEntityId: '3564523', - encryptionEntityType: 'DCM_ACCOUNT', - }, - conversions: [ - { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - ], - }, - headers: { - Authorization: 'Bearer dummyApiKey', - 'Content-Type': 'application/json', + encryptionInfo, + conversions: [testConversion1, testConversion2], }, + headers: commonHeaders, }, httpRes: { data: { hasFailures: true, status: [ { - conversion: { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, + conversion: testConversion1, + kind: 'dfareporting#conversionStatus', + }, + { + conversion: testConversion2, errors: [ { code: 'NOT_FOUND', @@ -115,185 +114,37 @@ const Data = [ }, }, { + description: 'Mock response from destination depicting a request with 2 invalid conversions', httpReq: { method: 'post', - url: 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/43770/conversions/batchinsert', - data: { - kind: 'dfareporting#conversionsBatchInsertRequest', - encryptionInfo: { - kind: 'dfareporting#encryptionInfo', - encryptionSource: 'AD_SERVING', - encryptionEntityId: '3564523', - encryptionEntityType: 'DCM_ACCOUNT', - }, - conversions: [ - { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - ], - }, - headers: { - Authorization: 'Bearer dummyApiKey', - 'Content-Type': 'application/json', - }, - }, - httpRes: { - data: { - hasFailures: false, - status: [ - { - conversion: { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - kind: 'dfareporting#conversionStatus', - }, - ], - kind: 'dfareporting#conversionsBatchInsertResponse', - }, - status: 200, - statusText: 'OK', - }, - }, - { - httpReq: { - method: 'post', - url: 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437692/conversions/batchinsert', + url: 'https://dfareporting.googleapis.com/test_url_for_invalid_request_both_conversions', data: { kind: 'dfareporting#conversionsBatchInsertRequest', - conversions: [ - { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 8, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - ], - }, - headers: { - Authorization: 'Bearer dummyApiKey', - 'Content-Type': 'application/json', + encryptionInfo, + conversions: [testConversion1, testConversion2], }, + headers: commonHeaders, }, httpRes: { data: { hasFailures: true, status: [ { - conversion: { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, + conversion: testConversion1, errors: [ { code: 'INVALID_ARGUMENT', - message: 'Floodlight config id: 213123123 was not found.', + message: 'Gclid is not valid.', kind: 'dfareporting#conversionError', }, ], kind: 'dfareporting#conversionStatus', }, { - conversion: { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 8, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - kind: 'dfareporting#conversionStatus', - }, - ], - kind: 'dfareporting#conversionsBatchInsertResponse', - }, - status: 200, - statusText: 'OK', - }, - }, - { - httpReq: { - method: 'post', - url: 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437691/conversions/batchinsert', - data: { - kind: 'dfareporting#conversionsBatchInsertRequest', - encryptionInfo: { - kind: 'dfareporting#encryptionInfo', - encryptionSource: 'AD_SERVING', - encryptionEntityId: '3564523', - encryptionEntityType: 'DCM_ACCOUNT', - }, - conversions: [ - { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, - ], - }, - headers: { - Authorization: 'Bearer dummyApiKey', - 'Content-Type': 'application/json', - }, - }, - httpRes: { - data: { - hasFailures: true, - status: [ - { - conversion: { - timestampMicros: '1668624722000000', - floodlightConfigurationId: '213123123', - ordinal: '1', - floodlightActivityId: '456543345245', - value: 7, - gclid: '123', - limitAdTracking: true, - childDirectedTreatment: true, - }, + conversion: testConversion2, errors: [ { - code: 'INVALID_ARGUMENT', + code: 'NOT_FOUND', message: 'Floodlight config id: 213123123 was not found.', kind: 'dfareporting#conversionError', }, @@ -308,4 +159,5 @@ const Data = [ }, }, ]; -export const networkCallsData = [...Data]; + +export const networkCallsData = [...businessMockData]; diff --git a/test/integrations/destinations/clevertap/dataDelivery/business.ts b/test/integrations/destinations/clevertap/dataDelivery/business.ts new file mode 100644 index 00000000000..d9f83f52f35 --- /dev/null +++ b/test/integrations/destinations/clevertap/dataDelivery/business.ts @@ -0,0 +1,284 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; + +const params = { + destination: 'clevertap', +}; +const headers = { + 'X-CleverTap-Account-Id': '476550467', + 'X-CleverTap-Passcode': + 'fbee74a147828e2932c701d19dc1f2dcfa4ac0048be3aa3a88d427090a59dc1c0fa002f1', + 'Content-Type': 'application/json', +}; + +const statTags = { + destType: 'CLEVERTAP', + destinationId: 'default-destinationId', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'default-workspaceId', +}; + +export const V1BusinessTestScenarion: ProxyV1TestData[] = [ + { + id: 'clevertap_business_0', + scenario: 'business', + successCriteria: 'should return 200 status code with success message', + name: 'clevertap', + description: '[business]:: create an user through identify call', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + params, + headers, + JSON: { + d: [ + { + type: 'profile', + profileData: { + Email: 'jamesDoe@gmail.com', + Name: 'James Doe', + Phone: '92374162212', + Gender: 'M', + Employed: true, + DOB: '1614775793', + Education: 'Science', + Married: 'Y', + 'Customer Type': 'Prime', + graduate: true, + msg_push: true, + msgSms: true, + msgemail: true, + msgwhatsapp: false, + custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', + custom_mappings: '{"Office":"Trastkiv","Country":"Russia"}', + address: + '{"city":"kolkata","country":"India","postalCode":789223,"state":"WB","street":""}', + }, + identity: 'anon_id', + }, + ], + }, + endpoint: 'https://api.clevertap.com/1/upload/test1', + }, + [generateMetadata(123)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + response: [ + { + metadata: generateMetadata(123), + error: '{"status":"success","processed":1,"unprocessed":[]}', + statusCode: 200, + }, + ], + }, + }, + }, + }, + }, + { + id: 'clevertap_business_1', + scenario: 'business', + successCriteria: 'should return 401 status code with error message', + name: 'clevertap', + description: '[business]:: event failed due to invalid credentials', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + params, + headers: { + 'X-CleverTap-Account-Id': 'fakeId123', + 'X-CleverTap-Passcode': 'fakePasscode123', + 'Content-Type': 'application/json', + }, + JSON: { + d: [ + { + identity: 'anon-id-new', + type: 'event', + evtName: 'Web Page Viewed: Rudder', + evtData: { + title: 'Home', + path: '/', + }, + }, + ], + }, + endpoint: 'https://api.clevertap.com/1/upload/test2', + }, + [generateMetadata(123)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 401, + message: 'Request failed with status: 401', + response: [ + { + metadata: generateMetadata(123), + error: '{"status":"fail","error":"Invalid Credentials","code":401}', + statusCode: 401, + }, + ], + statTags, + }, + }, + }, + }, + }, + { + id: 'clevertap_business_2', + scenario: 'business', + successCriteria: 'should return 401 status code with error message', + name: 'clevertap', + description: '[business]:: event failed due to invalid credentials', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + params, + headers: { + 'X-CleverTap-Account-Id': '476550467', + 'X-CleverTap-Passcode': + 'fbee74a147828e2932c701d19dc1f2dcfa4ac0048be3aa3a88d427090a59dc1c0fa002f1', + 'Content-Type': 'application/json', + }, + JSON: { + d: [ + { + identity: 'anon-id-new', + type: 'event', + evtData: { + title: 'Home', + path: '/', + }, + }, + ], + }, + endpoint: 'https://api.clevertap.com/1/upload/test3', + }, + [generateMetadata(123)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'Request failed with status: 200', + response: [ + { + metadata: generateMetadata(123), + error: '{"status":"fail","processed":0,"unprocessed":[]}', + statusCode: 400, + }, + ], + statTags, + }, + }, + }, + }, + }, + { + id: 'clevertap_business_3', + scenario: 'business', + successCriteria: 'should return 200 status code with success message', + name: 'clevertap', + description: '[business]:: create an user through identify call', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + params, + headers, + JSON: { + d: [ + { + identity: 'testUser1', + type: 'profile', + profileData: { + Name: 'Test User1', + Email: 'test1@testMail.com', + }, + }, + { + evtData: { + name: 1234, + revenue: 4.99, + }, + type: 'event', + identity: 'user123', + }, + { + identity: 'testUser2', + type: 'profile', + profileData: { + Name: 'Test User2', + Email: 'test2@testMail.com', + }, + }, + ], + }, + endpoint: 'https://api.clevertap.com/1/upload/test4', + }, + [generateMetadata(123)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + statTags, + status: 400, + message: 'Request failed with status: 200', + response: [ + { + metadata: generateMetadata(123), + error: + '{"status":"partial","processed":2,"unprocessed":[{"status":"fail","code":509,"error":"Event Name is incorrect. ErrorCode: 509 - Event name is mandatory. Skipped record number : 2","record":{"evtData":{"name":1234,"revenue":4.99},"type":"event","identity":"user123"}}]}', + statusCode: 400, + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/clevertap/dataDelivery/data.ts b/test/integrations/destinations/clevertap/dataDelivery/data.ts index 13a70d38c93..57e0d0ceea1 100644 --- a/test/integrations/destinations/clevertap/dataDelivery/data.ts +++ b/test/integrations/destinations/clevertap/dataDelivery/data.ts @@ -1,227 +1,233 @@ -export const data = [ +import { V1BusinessTestScenarion } from './business'; +const oldV0TestCases = [ { - "name": "clevertap", - "description": "Test 0", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.clevertap.com/1/upload/test1", - "headers": { - "X-CleverTap-Account-Id": "476550467", - "X-CleverTap-Passcode": "fbee74a147828e2932c701d19dc1f2dcfa4ac0048be3aa3a88d427090a59dc1c0fa002f1", - "Content-Type": "application/json" + name: 'clevertap', + description: 'Test 0', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.clevertap.com/1/upload/test1', + headers: { + 'X-CleverTap-Account-Id': '476550467', + 'X-CleverTap-Passcode': + 'fbee74a147828e2932c701d19dc1f2dcfa4ac0048be3aa3a88d427090a59dc1c0fa002f1', + 'Content-Type': 'application/json', }, - "body": { - "JSON": { - "d": [ + body: { + JSON: { + d: [ { - "type": "profile", - "profileData": { - "Email": "jamesDoe@gmail.com", - "Name": "James Doe", - "Phone": "92374162212", - "Gender": "M", - "Employed": true, - "DOB": "1614775793", - "Education": "Science", - "Married": "Y", - "Customer Type": "Prime", - "graduate": true, - "msg_push": true, - "msgSms": true, - "msgemail": true, - "msgwhatsapp": false, - "custom_tags": "[\"Test_User\",\"Interested_User\",\"DIY_Hobby\"]", - "custom_mappings": "{\"Office\":\"Trastkiv\",\"Country\":\"Russia\"}", - "address": "{\"city\":\"kolkata\",\"country\":\"India\",\"postalCode\":789223,\"state\":\"WB\",\"street\":\"\"}" + type: 'profile', + profileData: { + Email: 'jamesDoe@gmail.com', + Name: 'James Doe', + Phone: '92374162212', + Gender: 'M', + Employed: true, + DOB: '1614775793', + Education: 'Science', + Married: 'Y', + 'Customer Type': 'Prime', + graduate: true, + msg_push: true, + msgSms: true, + msgemail: true, + msgwhatsapp: false, + custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', + custom_mappings: '{"Office":"Trastkiv","Country":"Russia"}', + address: + '{"city":"kolkata","country":"India","postalCode":789223,"state":"WB","street":""}', }, - "identity": "anon_id" - } - ] + identity: 'anon_id', + }, + ], }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + params: { + destination: 'clevertap', }, - "files": {}, - "params": { - "destination": "clevertap" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 200, - "body": { - "output": { - "status": 200, - "message": "Request Processed Successfully", - "destinationResponse": { - "response": { - "status": "success", - "processed": 1, - "unprocessed": [] + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + destinationResponse: { + response: { + status: 'success', + processed: 1, + unprocessed: [], }, - "status": 200 - } - } - } - } - } + status: 200, + }, + }, + }, + }, + }, }, { - "name": "clevertap", - "description": "Test 1", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "d": [ + name: 'clevertap', + description: 'Test 1', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + d: [ { - "identity": "anon-id-new", - "type": "event", - "evtName": "Web Page Viewed: Rudder", - "evtData": { - "title": "Home", - "path": "/" - } - } - ] - } + identity: 'anon-id-new', + type: 'event', + evtName: 'Web Page Viewed: Rudder', + evtData: { + title: 'Home', + path: '/', + }, + }, + ], + }, + }, + type: 'REST', + files: {}, + method: 'POST', + headers: { + 'X-CleverTap-Account-Id': 'fakeId123', + 'X-CleverTap-Passcode': 'fakePasscode123', + 'Content-Type': 'application/json', }, - "type": "REST", - "files": {}, - "method": "POST", - "headers": { - "X-CleverTap-Account-Id": "fakeId123", - "X-CleverTap-Passcode": "fakePasscode123", - "Content-Type": "application/json" + version: '1', + endpoint: 'https://api.clevertap.com/1/upload/test2', + params: { + destination: 'clevertap', }, - "version": "1", - "endpoint": "https://api.clevertap.com/1/upload/test2", - "params": { - "destination": "clevertap" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 401, - "body": { - "output": { - "status": 401, - "message": "Request failed with status: 401", - "destinationResponse": { - "response": { - "status": "fail", - "error": "Invalid Credentials", - "code": 401 + output: { + response: { + status: 401, + body: { + output: { + status: 401, + message: 'Request failed with status: 401', + destinationResponse: { + response: { + status: 'fail', + error: 'Invalid Credentials', + code: 401, }, - "status": 401 + status: 401, }, - "statTags": { - "destType": "CLEVERTAP", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } + statTags: { + destType: 'CLEVERTAP', + errorCategory: 'network', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + }, + }, + }, + }, + }, }, { - "name": "clevertap", - "description": "Test 2", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "d": [ + name: 'clevertap', + description: 'Test 2', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + d: [ { - "identity": "anon-id-new", - "type": "event", - "evtData": { - "title": "Home", - "path": "/" - } - } - ] - } + identity: 'anon-id-new', + type: 'event', + evtData: { + title: 'Home', + path: '/', + }, + }, + ], + }, + }, + type: 'REST', + files: {}, + method: 'POST', + headers: { + 'X-CleverTap-Account-Id': '476550467', + 'X-CleverTap-Passcode': + 'fbee74a147828e2932c701d19dc1f2dcfa4ac0048be3aa3a88d427090a59dc1c0fa002f1', + 'Content-Type': 'application/json', }, - "type": "REST", - "files": {}, - "method": "POST", - "headers": { - "X-CleverTap-Account-Id": "476550467", - "X-CleverTap-Passcode": "fbee74a147828e2932c701d19dc1f2dcfa4ac0048be3aa3a88d427090a59dc1c0fa002f1", - "Content-Type": "application/json" + version: '1', + endpoint: 'https://api.clevertap.com/1/upload/test3', + params: { + destination: 'clevertap', }, - "version": "1", - "endpoint": "https://api.clevertap.com/1/upload/test3", - "params": { - "destination": "clevertap" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 400, - "body": { - "output": { - "status": 400, - "message": "Request failed with status: 200", - "destinationResponse": { - "response": { - "status": "fail", - "processed": 0, - "unprocessed": [] + output: { + response: { + status: 400, + body: { + output: { + status: 400, + message: 'Request failed with status: 200', + destinationResponse: { + response: { + status: 'fail', + processed: 0, + unprocessed: [], }, - "status": 200 + status: 200, }, - "statTags": { - "destType": "CLEVERTAP", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } - } -] + statTags: { + destType: 'CLEVERTAP', + errorCategory: 'network', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + }, + }, + }, + }, + }, + }, +]; + +export const data = [...oldV0TestCases, ...V1BusinessTestScenarion]; diff --git a/test/integrations/destinations/clevertap/network.ts b/test/integrations/destinations/clevertap/network.ts index c4eb23ee398..9122ba11293 100644 --- a/test/integrations/destinations/clevertap/network.ts +++ b/test/integrations/destinations/clevertap/network.ts @@ -65,7 +65,8 @@ const dataDeliveryMocksData = [ method: 'POST', }, httpRes: { - data: { status: 'fail', error: 'Invalid Credentials', code: 401 }, status: 401 + data: { status: 'fail', error: 'Invalid Credentials', code: 401 }, + status: 401, }, }, { @@ -86,6 +87,35 @@ const dataDeliveryMocksData = [ }, httpRes: { data: { status: 'fail', processed: 0, unprocessed: [] }, status: 200 }, }, + { + httpReq: { + url: 'https://api.clevertap.com/1/upload/test4', + method: 'POST', + }, + httpRes: { + data: { + status: 'partial', + processed: 2, + unprocessed: [ + { + status: 'fail', + code: 509, + error: + 'Event Name is incorrect. ErrorCode: 509 - Event name is mandatory. Skipped record number : 2', + record: { + evtData: { + name: 1234, + revenue: 4.99, + }, + type: 'event', + identity: 'user123', + }, + }, + ], + }, + status: 200, + }, + }, ]; const deleteNwData = [ { diff --git a/test/integrations/destinations/clevertap/processor/data.ts b/test/integrations/destinations/clevertap/processor/data.ts index d79ebaa8da5..1d7bdd7e782 100644 --- a/test/integrations/destinations/clevertap/processor/data.ts +++ b/test/integrations/destinations/clevertap/processor/data.ts @@ -52,6 +52,7 @@ export const data = [ state: 'WB', street: '', }, + 'category-unsubscribe': { email: ['Marketing', 'Transactional'] }, }, integrations: { All: true, @@ -98,10 +99,135 @@ export const data = [ msgSms: true, msgemail: true, msgwhatsapp: false, + custom_mappings: '{"Office":"Trastkiv","Country":"Russia"}', custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', + address: + '{"city":"kolkata","country":"India","postalCode":789223,"state":"WB","street":""}', + 'category-unsubscribe': { email: ['Marketing', 'Transactional'] }, + }, + identity: 'anon_id', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'clevertap', + description: 'Should not load email from externalId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + passcode: 'sample_passcode', + accountId: '476550467', + trackAnonymous: true, + enableObjectIdMapping: false, + }, + }, + message: { + channel: 'web', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + type: 'identify', + traits: { + anonymousId: 'anon_id', + name: 'James Doe', + phone: '92374162212', + gender: 'M', + employed: true, + birthday: '1614775793', + education: 'Science', + graduate: true, + married: true, + customerType: 'Prime', + msg_push: true, + msgSms: true, + msgemail: true, + msgwhatsapp: false, + custom_tags: ['Test_User', 'Interested_User', 'DIY_Hobby'], + custom_mappings: { + Office: 'Trastkiv', + Country: 'Russia', + }, + address: { + city: 'kolkata', + country: 'India', + postalCode: 789223, + state: 'WB', + street: '', + }, + 'category-unsubscribe': { email: ['Marketing', 'Transactional'] }, + }, + context: { + externalId: [{ type: 'someId', id: 'someID' }], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.clevertap.com/1/upload', + headers: { + 'X-CleverTap-Account-Id': '476550467', + 'X-CleverTap-Passcode': 'sample_passcode', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + d: [ + { + type: 'profile', + profileData: { + Name: 'James Doe', + Phone: '92374162212', + Gender: 'M', + Employed: true, + DOB: '1614775793', + Education: 'Science', + Married: true, + 'Customer Type': 'Prime', + graduate: true, + msg_push: true, + msgSms: true, + msgemail: true, + msgwhatsapp: false, custom_mappings: '{"Office":"Trastkiv","Country":"Russia"}', + custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', address: '{"city":"kolkata","country":"India","postalCode":789223,"state":"WB","street":""}', + 'category-unsubscribe': { email: ['Marketing', 'Transactional'] }, }, identity: 'anon_id', }, @@ -242,8 +368,8 @@ export const data = [ msgSms: true, msgemail: true, msgwhatsapp: false, - custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', custom_mappings: '{"Office":"Trastkiv","Country":"Russia"}', + custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', address: '{"city":"kolkata","country":"India","postalCode":789223,"state":"WB","street":""}', }, @@ -968,8 +1094,8 @@ export const data = [ msgSms: true, msgemail: true, msgwhatsapp: false, - custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', custom_mappings: '{"Office":"Trastkiv","Country":"Russia"}', + custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', address: '{"city":"kolkata","country":"India","postalCode":789223,"state":"WB","street":""}', }, @@ -1111,8 +1237,8 @@ export const data = [ msgSms: true, msgemail: true, msgwhatsapp: false, - custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', custom_mappings: '{"Office":"Trastkiv","Country":"Russia"}', + custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', address: '{"city":"kolkata","country":"India","postalCode":789223,"state":"WB","street":""}', }, @@ -1692,8 +1818,8 @@ export const data = [ msgSms: true, msgemail: true, msgwhatsapp: false, - custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', custom_mappings: '{"Office":"Trastkiv","Country":"Russia"}', + custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', address: '{"city":"kolkata","country":"India","postalCode":789223,"state":"WB","street":""}', }, @@ -2077,8 +2203,8 @@ export const data = [ msgSms: true, msgemail: true, msgwhatsapp: false, - custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', custom_mappings: '{"Office":"Trastkiv","Country":"Russia"}', + custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', address: '{"city":"kolkata","country":"India","postalCode":789223,"state":"WB","street":""}', first_name: 'John', @@ -2230,8 +2356,8 @@ export const data = [ msgSms: true, msgemail: true, msgwhatsapp: false, - custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', custom_mappings: '{"Office":"Trastkiv","Country":"Russia"}', + custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', address: '{"city":"kolkata","country":"India","postalCode":789223,"state":"WB","street":""}', first_name: 'John', diff --git a/test/integrations/destinations/clevertap/router/data.ts b/test/integrations/destinations/clevertap/router/data.ts index 4f1723a7da4..5f25bbe83e7 100644 --- a/test/integrations/destinations/clevertap/router/data.ts +++ b/test/integrations/destinations/clevertap/router/data.ts @@ -162,10 +162,10 @@ export const data = [ msgSms: true, msgemail: true, msgwhatsapp: false, - custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', - custom_mappings: '{"Office":"Trastkiv","Country":"Russia"}', address: '{"city":"kolkata","country":"India","postalCode":789223,"state":"WB","street":""}', + custom_mappings: '{"Office":"Trastkiv","Country":"Russia"}', + custom_tags: '["Test_User","Interested_User","DIY_Hobby"]', }, objectId: 'anon_id', }, diff --git a/test/integrations/destinations/clickup/network.ts b/test/integrations/destinations/clickup/network.ts index 1a26209923e..2cb7cde34fc 100644 --- a/test/integrations/destinations/clickup/network.ts +++ b/test/integrations/destinations/clickup/network.ts @@ -1,247 +1,247 @@ export const networkCallsData = [ - { - httpReq: { - url: 'https://api.clickup.com/api/v2/list/correctListId123/field', - method: 'GET', - }, - httpRes: { - data: { - "fields": [ - { - "id": "19d3ac4e-2b1e-4569-b33e-ff86c7d94d6e", - "name": "Labels", - "type": "labels", - "type_config": { - "options": [ - { - "id": "32c81c1c-cf53-4829-92f5-0f0270d27a45", - "label": "Option 1", - "color": {} - }, - { - "id": "7e24f329-9dd9-4e68-b426-2c70af6f9347", - "label": "Option 2", - "color": {} - } - ] - }, - "date_created": "1661964865880", - "hide_from_guests": false, - "required": false - }, - { - "id": "22eaffee-ffec-4c3b-bdae-56e69d55eecd", - "name": "Payment Status", - "type": "drop_down", - "type_config": { - "default": 0, - "placeholder": {}, - "new_drop_down": true, - "options": [ - { - "id": "e109e36b-a052-4a31-af16-25da7324990f", - "name": "Sent Request", - "color": "#FF7FAB", - "orderindex": 0 - }, - { - "id": "3a3b4512-2896-44f7-8075-2ff37777fe24", - "name": "Quote sent", - "color": "#EA80FC", - "orderindex": 1 - }, - { - "id": "7afcb6fb-cec8-41d8-bf0c-039a9db28460", - "name": "Pending", - "color": "#ff7800", - "orderindex": 2 - }, - { - "id": "890ecf28-bdd4-4f53-92cc-bc4edb696fcd", - "name": "Payment Recieved", - "color": "#2ecd6f", - "orderindex": 3 - }, - { - "id": "e89f7dd7-fd24-4b32-ac4d-f174d8ca914f", - "name": "n/a", - "color": "#b5bcc2", - "orderindex": 4 - } - ] - }, - "date_created": "1660124553414", - "hide_from_guests": false, - "required": {} - }, - { - "id": "4b7a29be-e261-4340-8f3f-e6de838473e5", - "name": "Plan", - "type": "drop_down", - "type_config": { - "default": 0, - "placeholder": {}, - "new_drop_down": true, - "options": [ - { - "id": "4b9366a7-2592-4b7a-909a-ed4af705e27c", - "name": "Unlimited", - "color": "#02BCD4", - "orderindex": 0 - }, - { - "id": "c5032049-8c05-44e9-a000-3a071d457b8f", - "name": "Business", - "color": "#1bbc9c", - "orderindex": 1 - }, - { - "id": "9fb08801-1130-4650-8e2e-28578344ff3c", - "name": "Enterprise", - "color": "#2ecd6f", - "orderindex": 2 - } - ] - }, - "date_created": "1660124553414", - "hide_from_guests": false, - "required": {} - }, - { - "id": "4bfebc00-9d4a-40d1-aef8-5a87b610186c", - "name": "Contact Title", - "type": "text", - "type_config": {}, - "date_created": "1660124553414", - "hide_from_guests": false, - "required": {} - }, - { - "id": "666f74bf-6d87-41f3-8735-ccf0efe066dd", - "name": "Date", - "type": "date", - "type_config": {}, - "date_created": "1662379321069", - "hide_from_guests": false, - "required": false - }, - { - "id": "a5f5044a-cbad-4caf-bcbb-4cd32bd8db7c", - "name": "Industry", - "type": "drop_down", - "type_config": { - "default": 0, - "placeholder": {}, - "options": [ - { - "id": "75173398-257f-42b6-8bae-4cf767fa99ab", - "name": "Engineering", - "color": "#04A9F4", - "orderindex": 0 - }, - { - "id": "c7f9b6f5-cd98-4609-af10-68a8710cc1bf", - "name": "Retail", - "color": "#ff7800", - "orderindex": 1 - }, - { - "id": "dbe84940-b4e8-4a29-8491-e1aa5f2be4e2", - "name": "Hospitality", - "color": "#2ecd6f", - "orderindex": 2 - } - ] - }, - "date_created": "1660124553414", - "hide_from_guests": false, - "required": {} - }, - { - "id": "b01b32fd-94d3-43e6-9f31-2c855ff169cd", - "name": "Url", - "type": "url", - "type_config": {}, - "date_created": "1661970432587", - "hide_from_guests": false, - "required": false - }, - { - "id": "c9b83d91-b979-4b34-b4bd-88bf9cf2b9a6", - "name": "Phone Number", - "type": "phone", - "type_config": {}, - "date_created": "1661970795061", - "hide_from_guests": false, - "required": false - }, - { - "id": "d0201829-ddcd-4b97-b71f-0f9e672488f2", - "name": "Account Size", - "type": "number", - "type_config": {}, - "date_created": "1660124553414", - "hide_from_guests": false, - "required": {} - }, - { - "id": "ea6c1e48-2abf-4328-b228-79c213e147c8", - "name": "Location", - "type": "location", - "type_config": {}, - "date_created": "1662229589329", - "hide_from_guests": false, - "required": false - }, - { - "id": "ebe825fb-92de-41ce-a29c-25018da039b4", - "name": "Email", - "type": "email", - "type_config": {}, - "date_created": "1660124553414", - "hide_from_guests": false, - "required": {} - }, - { - "id": "f431cda3-a575-4a05-ba8d-583d9b6cb2df", - "name": "Rating", - "type": "emoji", - "type_config": { - "count": 5, - "code_point": "2b50" - }, - "date_created": "1661963909454", - "hide_from_guests": false, - "required": false - }, - { - "id": "ffbe4f03-cbc3-4077-8fea-9e5d08b4dceb", - "name": "Money In INR", - "type": "currency", - "type_config": { - "default": {}, - "precision": 2, - "currency_type": "INR" - }, - "date_created": "1661428276019", - "hide_from_guests": false, - "required": false - } - ] - }, - status: 200 - }, + { + httpReq: { + url: 'https://api.clickup.com/api/v2/list/correctListId123/field', + method: 'GET', }, - { - httpReq: { - url: 'https://api.clickup.com/api/v2/list/correctListId456/field', - method: 'GET', - }, - httpRes: { - data: { - "fields": [] + httpRes: { + data: { + fields: [ + { + id: '19d3ac4e-2b1e-4569-b33e-ff86c7d94d6e', + name: 'Labels', + type: 'labels', + type_config: { + options: [ + { + id: '32c81c1c-cf53-4829-92f5-0f0270d27a45', + label: 'Option 1', + color: {}, + }, + { + id: '7e24f329-9dd9-4e68-b426-2c70af6f9347', + label: 'Option 2', + color: {}, + }, + ], + }, + date_created: '1661964865880', + hide_from_guests: false, + required: false, + }, + { + id: '22eaffee-ffec-4c3b-bdae-56e69d55eecd', + name: 'Payment Status', + type: 'drop_down', + type_config: { + default: 0, + placeholder: {}, + new_drop_down: true, + options: [ + { + id: 'e109e36b-a052-4a31-af16-25da7324990f', + name: 'Sent Request', + color: '#FF7FAB', + orderindex: 0, + }, + { + id: '3a3b4512-2896-44f7-8075-2ff37777fe24', + name: 'Quote sent', + color: '#EA80FC', + orderindex: 1, + }, + { + id: '7afcb6fb-cec8-41d8-bf0c-039a9db28460', + name: 'Pending', + color: '#ff7800', + orderindex: 2, + }, + { + id: '890ecf28-bdd4-4f53-92cc-bc4edb696fcd', + name: 'Payment Recieved', + color: '#2ecd6f', + orderindex: 3, + }, + { + id: 'e89f7dd7-fd24-4b32-ac4d-f174d8ca914f', + name: 'n/a', + color: '#b5bcc2', + orderindex: 4, + }, + ], + }, + date_created: '1660124553414', + hide_from_guests: false, + required: {}, + }, + { + id: '4b7a29be-e261-4340-8f3f-e6de838473e5', + name: 'Plan', + type: 'drop_down', + type_config: { + default: 0, + placeholder: {}, + new_drop_down: true, + options: [ + { + id: '4b9366a7-2592-4b7a-909a-ed4af705e27c', + name: 'Unlimited', + color: '#02BCD4', + orderindex: 0, + }, + { + id: 'c5032049-8c05-44e9-a000-3a071d457b8f', + name: 'Business', + color: '#1bbc9c', + orderindex: 1, + }, + { + id: '9fb08801-1130-4650-8e2e-28578344ff3c', + name: 'Enterprise', + color: '#2ecd6f', + orderindex: 2, + }, + ], + }, + date_created: '1660124553414', + hide_from_guests: false, + required: {}, + }, + { + id: '4bfebc00-9d4a-40d1-aef8-5a87b610186c', + name: 'Contact Title', + type: 'text', + type_config: {}, + date_created: '1660124553414', + hide_from_guests: false, + required: {}, + }, + { + id: '666f74bf-6d87-41f3-8735-ccf0efe066dd', + name: 'Date', + type: 'date', + type_config: {}, + date_created: '1662379321069', + hide_from_guests: false, + required: false, + }, + { + id: 'a5f5044a-cbad-4caf-bcbb-4cd32bd8db7c', + name: 'Industry', + type: 'drop_down', + type_config: { + default: 0, + placeholder: {}, + options: [ + { + id: '75173398-257f-42b6-8bae-4cf767fa99ab', + name: 'Engineering', + color: '#04A9F4', + orderindex: 0, + }, + { + id: 'c7f9b6f5-cd98-4609-af10-68a8710cc1bf', + name: 'Retail', + color: '#ff7800', + orderindex: 1, + }, + { + id: 'dbe84940-b4e8-4a29-8491-e1aa5f2be4e2', + name: 'Hospitality', + color: '#2ecd6f', + orderindex: 2, + }, + ], + }, + date_created: '1660124553414', + hide_from_guests: false, + required: {}, + }, + { + id: 'b01b32fd-94d3-43e6-9f31-2c855ff169cd', + name: 'Url', + type: 'url', + type_config: {}, + date_created: '1661970432587', + hide_from_guests: false, + required: false, + }, + { + id: 'c9b83d91-b979-4b34-b4bd-88bf9cf2b9a6', + name: 'Phone Number', + type: 'phone', + type_config: {}, + date_created: '1661970795061', + hide_from_guests: false, + required: false, + }, + { + id: 'd0201829-ddcd-4b97-b71f-0f9e672488f2', + name: 'Account Size', + type: 'number', + type_config: {}, + date_created: '1660124553414', + hide_from_guests: false, + required: {}, + }, + { + id: 'ea6c1e48-2abf-4328-b228-79c213e147c8', + name: 'Location', + type: 'location', + type_config: {}, + date_created: '1662229589329', + hide_from_guests: false, + required: false, + }, + { + id: 'ebe825fb-92de-41ce-a29c-25018da039b4', + name: 'Email', + type: 'email', + type_config: {}, + date_created: '1660124553414', + hide_from_guests: false, + required: {}, + }, + { + id: 'f431cda3-a575-4a05-ba8d-583d9b6cb2df', + name: 'Rating', + type: 'emoji', + type_config: { + count: 5, + code_point: '2b50', }, - status: 200 - }, - } + date_created: '1661963909454', + hide_from_guests: false, + required: false, + }, + { + id: 'ffbe4f03-cbc3-4077-8fea-9e5d08b4dceb', + name: 'Money In INR', + type: 'currency', + type_config: { + default: {}, + precision: 2, + currency_type: 'INR', + }, + date_created: '1661428276019', + hide_from_guests: false, + required: false, + }, + ], + }, + status: 200, + }, + }, + { + httpReq: { + url: 'https://api.clickup.com/api/v2/list/correctListId456/field', + method: 'GET', + }, + httpRes: { + data: { + fields: [], + }, + status: 200, + }, + }, ]; diff --git a/test/integrations/destinations/clickup/processor/data.ts b/test/integrations/destinations/clickup/processor/data.ts index 4a79df28627..686bf670e2e 100644 --- a/test/integrations/destinations/clickup/processor/data.ts +++ b/test/integrations/destinations/clickup/processor/data.ts @@ -1,829 +1,818 @@ export const data = [ - { - "name": "clickup", - "description": "Invalid priority", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiToken": "pk_123", - "listId": "correctListId123" - }, - "ID": "clickup-1234" - }, - "message": { - "type": "track", - "event": "Product Viewed", - "properties": { - "priority": 0 - }, - "context": {}, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Invalid value specified for priority. Value must be Integer and in range \"[1,4]\"", - "statTags": { - "destType": "CLICKUP", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "clickup", - "description": "Custom field: Invalid phone number", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiToken": "pk_123", - "listId": "correctListId123", - "keyToCustomFieldName": [ - { - "from": "phone", - "to": "Phone Number" - } - ] - }, - "ID": "clickup-1234" - }, - "message": { - "type": "track", - "event": "Product Viewed", - "properties": { - "phone": "9999999999" - }, - "context": {}, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "The provided phone number is invalid", - "statTags": { - "destType": "CLICKUP", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "clickup", - "description": "Custom field: Invalid email", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiToken": "pk_123", - "listId": "correctListId123", - "keyToCustomFieldName": [ - { - "from": "email", - "to": "Email" - } - ] - }, - "ID": "clickup-1234" - }, - "message": { - "type": "track", - "event": "Product Viewed", - "properties": { - "email": "test.com" - }, - "context": {}, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "The provided email is invalid", - "statTags": { - "destType": "CLICKUP", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "clickup", - "description": "Custom field: Invalid url", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiToken": "pk_123", - "listId": "correctListId123", - "keyToCustomFieldName": [ - { - "from": "url", - "to": "Url" - } - ] - }, - "ID": "clickup-1234" - }, - "message": { - "type": "track", - "event": "Product Viewed", - "properties": { - "url": "www.test.com" - }, - "context": {}, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "The provided url is invalid", - "statTags": { - "destType": "CLICKUP", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "clickup", - "description": "Custom field: Invalid location latitude", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiToken": "pk_123", - "listId": "correctListId123", - "keyToCustomFieldName": [ - { - "from": "location", - "to": "Location" - } - ] - }, - "ID": "clickup-1234" - }, - "message": { - "type": "track", - "event": "Product Viewed", - "properties": { - "location": { - "lat": -100, - "lng": 124, - "formattedAddress": "Gold Coast QLD, Australia" - } - }, - "context": {}, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Invalid value specified for latitude. Latitude must be in range \"[-90, 90]\"", - "statTags": { - "destType": "CLICKUP", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "clickup", - "description": "Custom field: Invalid rating", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiToken": "pk_123", - "listId": "correctListId123", - "keyToCustomFieldName": [ - { - "from": "rating", - "to": "Rating" - } - ] - }, - "ID": "clickup-1234" - }, - "message": { - "type": "track", - "event": "Product Viewed", - "properties": { - "rating": "7" - }, - "context": {}, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Invalid value specified for rating. Value must be in range \"[0,5]\"", - "statTags": { - "destType": "CLICKUP", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "clickup", - "description": "Creating task with valid custom fields values", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiToken": "pk_123", - "listId": "correctListId123", - "keyToCustomFieldName": [ - { - "from": "industry", - "to": "Industry" - }, - { - "from": "Payment Status", - "to": "Payment Status" - }, - { - "from": "labelKey", - "to": "Labels" - }, - { - "from": "locationKey", - "to": "Location" - }, - { - "from": "phone", - "to": "Phone Number" - }, - { - "from": "email", - "to": "Email" - }, - { - "from": "url", - "to": "Url" - }, - { - "from": "rating", - "to": "Rating" - }, - { - "from": "plan", - "to": "Plan" - }, - { - "from": "contactTitle", - "to": "Contact Title" - }, - { - "from": "date", - "to": "Date" - } - ] - }, - "ID": "clickup-1234" - }, - "message": { - "type": "track", - "event": "Product Viewed", - "properties": { - "description": "Creating task with valid custom fields values", - "tags": [ - "testing", - "custom fields" - ], - "timeEstimate": 10800000, - "status": "Ready", - "priority": 1, - "dueDate": "2022-02-25T13:39:21.032Z", - "includeDueDateTime": true, - "startDate": "2022-01-20T13:39:21.032Z", - "includeStartDateTime": "true", - "notifyAll": false, - "industry": "Retail", - "Payment Status": "Pending", - "labelKey": [ - "option 1", - "option 2", - "option 3" - ], - "locationKey": { - "lat": -20, - "lng": 124, - "formattedAddress": "Gold Coast QLD, Australia" - }, - "phone": "+12233445567", - "email": "test123@example.com", - "url": "https://www.rudderstack.com/", - "rating": 3, - "plan": "Business", - "contactTitle": "VP of Operations", - "date": "2022-02-25T13:39:21.032Z" - }, - "context": {}, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.clickup.com/api/v2/list/correctListId123/task", - "headers": { - "Content-Type": "application/json", - "Authorization": "pk_123" - }, - "params": {}, - "body": { - "JSON": { - "name": "Product Viewed", - "description": "Creating task with valid custom fields values", - "tags": [ - "testing", - "custom fields" - ], - "time_estimate": 10800000, - "status": "Ready", - "priority": 1, - "due_date": 1645796361032, - "due_date_time": true, - "start_date": 1642685961032, - "start_date_time": "true", - "notify_all": false, - "custom_fields": [ - { - "id": "a5f5044a-cbad-4caf-bcbb-4cd32bd8db7c", - "value": "c7f9b6f5-cd98-4609-af10-68a8710cc1bf" - }, - { - "id": "22eaffee-ffec-4c3b-bdae-56e69d55eecd", - "value": "7afcb6fb-cec8-41d8-bf0c-039a9db28460" - }, - { - "id": "19d3ac4e-2b1e-4569-b33e-ff86c7d94d6e", - "value": [ - "32c81c1c-cf53-4829-92f5-0f0270d27a45", - "7e24f329-9dd9-4e68-b426-2c70af6f9347" - ] - }, - { - "id": "ea6c1e48-2abf-4328-b228-79c213e147c8", - "value": { - "location": { - "lat": -20, - "lng": 124 - }, - "formatted_address": "Gold Coast QLD, Australia" - } - }, - { - "id": "c9b83d91-b979-4b34-b4bd-88bf9cf2b9a6", - "value": "+12233445567" - }, - { - "id": "ebe825fb-92de-41ce-a29c-25018da039b4", - "value": "test123@example.com" - }, - { - "id": "b01b32fd-94d3-43e6-9f31-2c855ff169cd", - "value": "https://www.rudderstack.com/" - }, - { - "id": "f431cda3-a575-4a05-ba8d-583d9b6cb2df", - "value": 3 - }, - { - "id": "4b7a29be-e261-4340-8f3f-e6de838473e5", - "value": "c5032049-8c05-44e9-a000-3a071d457b8f" - }, - { - "id": "4bfebc00-9d4a-40d1-aef8-5a87b610186c", - "value": "VP of Operations" - }, - { - "id": "666f74bf-6d87-41f3-8735-ccf0efe066dd", - "value": 1645796361032 - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "clickup", - "description": "Creating task with assignees", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiToken": "pk_123", - "listId": "correctListId123" - }, - "ID": "clickup-1234" - }, - "message": { - "type": "track", - "event": "Product Viewed", - "properties": { - "taskName": "Transformer Testing" - }, - "context": { - "externalId": [ - { - "type": "clickUpAssigneeId", - "id": 61205104 - }, - { - "type": "clickUpAssigneeId", - "id": 61217234 - }, - { - "type": "clickUpAssigneeId", - "id": 61228575 - } - ] - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.clickup.com/api/v2/list/correctListId123/task", - "headers": { - "Content-Type": "application/json", - "Authorization": "pk_123" - }, - "params": {}, - "body": { - "JSON": { - "name": "Transformer Testing", - "assignees": [ - 61205104, - 61217234, - 61228575 - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "clickup", - "description": "Event filtering : Sending non whitelisted event when some events are whitelisted", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiToken": "pk_123", - "listId": "correctListId123", - "whitelistedEvents": [ - { - "eventName": "Anonymous Page Visit" - }, - { - "eventName": "Product Viewed" - }, - { - "eventName": "" - } - ] - }, - "ID": "clickup-1234" - }, - "message": { - "type": "track", - "event": "Credit Card Added", - "context": {}, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "The event was discarded as it was not allow listed in the destination configuration", - "statTags": { - "destType": "CLICKUP", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "clickup", - "description": "Event filtering : No event is whitelisted", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiToken": "pk_123", - "listId": "correctListId123", - "whitelistedEvents": [ - { - "eventName": "" - }, - { - "eventName": "" - }, - { - "eventName": "" - } - ] - }, - "ID": "clickup-1234" - }, - "message": { - "type": "track", - "event": "Credit Card Added", - "context": {}, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "The event was discarded as it was not allow listed in the destination configuration", - "statTags": { - "destType": "CLICKUP", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "clickup", - "description": "Creating task using listId from externalId array", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiToken": "pk_123", - "listId": "correctListId123" - }, - "ID": "clickup-1234" - }, - "message": { - "type": "track", - "event": "anonymous page visit", - "context": { - "externalId": [ - { - "type": "clickUpListId", - "id": "correctListId456" - } - ] - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.clickup.com/api/v2/list/correctListId456/task", - "headers": { - "Content-Type": "application/json", - "Authorization": "pk_123" - }, - "params": {}, - "body": { - "JSON": { - "name": "anonymous page visit" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - } -] + { + name: 'clickup', + description: 'Invalid priority', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiToken: 'pk_123', + listId: 'correctListId123', + }, + ID: 'clickup-1234', + }, + message: { + type: 'track', + event: 'Product Viewed', + properties: { + priority: 0, + }, + context: {}, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Invalid value specified for priority. Value must be Integer and in range "[1,4]"', + statTags: { + destType: 'CLICKUP', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'clickup', + description: 'Custom field: Invalid phone number', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiToken: 'pk_123', + listId: 'correctListId123', + keyToCustomFieldName: [ + { + from: 'phone', + to: 'Phone Number', + }, + ], + }, + ID: 'clickup-1234', + }, + message: { + type: 'track', + event: 'Product Viewed', + properties: { + phone: '9999999999', + }, + context: {}, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'The provided phone number is invalid', + statTags: { + destType: 'CLICKUP', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'clickup', + description: 'Custom field: Invalid email', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiToken: 'pk_123', + listId: 'correctListId123', + keyToCustomFieldName: [ + { + from: 'email', + to: 'Email', + }, + ], + }, + ID: 'clickup-1234', + }, + message: { + type: 'track', + event: 'Product Viewed', + properties: { + email: 'test.com', + }, + context: {}, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'The provided email is invalid', + statTags: { + destType: 'CLICKUP', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'clickup', + description: 'Custom field: Invalid url', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiToken: 'pk_123', + listId: 'correctListId123', + keyToCustomFieldName: [ + { + from: 'url', + to: 'Url', + }, + ], + }, + ID: 'clickup-1234', + }, + message: { + type: 'track', + event: 'Product Viewed', + properties: { + url: 'www.test.com', + }, + context: {}, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'The provided url is invalid', + statTags: { + destType: 'CLICKUP', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'clickup', + description: 'Custom field: Invalid location latitude', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiToken: 'pk_123', + listId: 'correctListId123', + keyToCustomFieldName: [ + { + from: 'location', + to: 'Location', + }, + ], + }, + ID: 'clickup-1234', + }, + message: { + type: 'track', + event: 'Product Viewed', + properties: { + location: { + lat: -100, + lng: 124, + formattedAddress: 'Gold Coast QLD, Australia', + }, + }, + context: {}, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Invalid value specified for latitude. Latitude must be in range "[-90, 90]"', + statTags: { + destType: 'CLICKUP', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'clickup', + description: 'Custom field: Invalid rating', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiToken: 'pk_123', + listId: 'correctListId123', + keyToCustomFieldName: [ + { + from: 'rating', + to: 'Rating', + }, + ], + }, + ID: 'clickup-1234', + }, + message: { + type: 'track', + event: 'Product Viewed', + properties: { + rating: '7', + }, + context: {}, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Invalid value specified for rating. Value must be in range "[0,5]"', + statTags: { + destType: 'CLICKUP', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'clickup', + description: 'Creating task with valid custom fields values', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiToken: 'pk_123', + listId: 'correctListId123', + keyToCustomFieldName: [ + { + from: 'industry', + to: 'Industry', + }, + { + from: 'Payment Status', + to: 'Payment Status', + }, + { + from: 'labelKey', + to: 'Labels', + }, + { + from: 'locationKey', + to: 'Location', + }, + { + from: 'phone', + to: 'Phone Number', + }, + { + from: 'email', + to: 'Email', + }, + { + from: 'url', + to: 'Url', + }, + { + from: 'rating', + to: 'Rating', + }, + { + from: 'plan', + to: 'Plan', + }, + { + from: 'contactTitle', + to: 'Contact Title', + }, + { + from: 'date', + to: 'Date', + }, + ], + }, + ID: 'clickup-1234', + }, + message: { + type: 'track', + event: 'Product Viewed', + properties: { + description: 'Creating task with valid custom fields values', + tags: ['testing', 'custom fields'], + timeEstimate: 10800000, + status: 'Ready', + priority: 1, + dueDate: '2022-02-25T13:39:21.032Z', + includeDueDateTime: true, + startDate: '2022-01-20T13:39:21.032Z', + includeStartDateTime: 'true', + notifyAll: false, + industry: 'Retail', + 'Payment Status': 'Pending', + labelKey: ['option 1', 'option 2', 'option 3'], + locationKey: { + lat: -20, + lng: 124, + formattedAddress: 'Gold Coast QLD, Australia', + }, + phone: '+12233445567', + email: 'test123@example.com', + url: 'https://www.rudderstack.com/', + rating: 3, + plan: 'Business', + contactTitle: 'VP of Operations', + date: '2022-02-25T13:39:21.032Z', + }, + context: {}, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.clickup.com/api/v2/list/correctListId123/task', + headers: { + 'Content-Type': 'application/json', + Authorization: 'pk_123', + }, + params: {}, + body: { + JSON: { + name: 'Product Viewed', + description: 'Creating task with valid custom fields values', + tags: ['testing', 'custom fields'], + time_estimate: 10800000, + status: 'Ready', + priority: 1, + due_date: 1645796361032, + due_date_time: true, + start_date: 1642685961032, + start_date_time: 'true', + notify_all: false, + custom_fields: [ + { + id: 'a5f5044a-cbad-4caf-bcbb-4cd32bd8db7c', + value: 'c7f9b6f5-cd98-4609-af10-68a8710cc1bf', + }, + { + id: '22eaffee-ffec-4c3b-bdae-56e69d55eecd', + value: '7afcb6fb-cec8-41d8-bf0c-039a9db28460', + }, + { + id: '19d3ac4e-2b1e-4569-b33e-ff86c7d94d6e', + value: [ + '32c81c1c-cf53-4829-92f5-0f0270d27a45', + '7e24f329-9dd9-4e68-b426-2c70af6f9347', + ], + }, + { + id: 'ea6c1e48-2abf-4328-b228-79c213e147c8', + value: { + location: { + lat: -20, + lng: 124, + }, + formatted_address: 'Gold Coast QLD, Australia', + }, + }, + { + id: 'c9b83d91-b979-4b34-b4bd-88bf9cf2b9a6', + value: '+12233445567', + }, + { + id: 'ebe825fb-92de-41ce-a29c-25018da039b4', + value: 'test123@example.com', + }, + { + id: 'b01b32fd-94d3-43e6-9f31-2c855ff169cd', + value: 'https://www.rudderstack.com/', + }, + { + id: 'f431cda3-a575-4a05-ba8d-583d9b6cb2df', + value: 3, + }, + { + id: '4b7a29be-e261-4340-8f3f-e6de838473e5', + value: 'c5032049-8c05-44e9-a000-3a071d457b8f', + }, + { + id: '4bfebc00-9d4a-40d1-aef8-5a87b610186c', + value: 'VP of Operations', + }, + { + id: '666f74bf-6d87-41f3-8735-ccf0efe066dd', + value: 1645796361032, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'clickup', + description: 'Creating task with assignees', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiToken: 'pk_123', + listId: 'correctListId123', + }, + ID: 'clickup-1234', + }, + message: { + type: 'track', + event: 'Product Viewed', + properties: { + taskName: 'Transformer Testing', + }, + context: { + externalId: [ + { + type: 'clickUpAssigneeId', + id: 61205104, + }, + { + type: 'clickUpAssigneeId', + id: 61217234, + }, + { + type: 'clickUpAssigneeId', + id: 61228575, + }, + ], + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.clickup.com/api/v2/list/correctListId123/task', + headers: { + 'Content-Type': 'application/json', + Authorization: 'pk_123', + }, + params: {}, + body: { + JSON: { + name: 'Transformer Testing', + assignees: [61205104, 61217234, 61228575], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'clickup', + description: 'Event filtering : Sending non whitelisted event when some events are whitelisted', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiToken: 'pk_123', + listId: 'correctListId123', + whitelistedEvents: [ + { + eventName: 'Anonymous Page Visit', + }, + { + eventName: 'Product Viewed', + }, + { + eventName: '', + }, + ], + }, + ID: 'clickup-1234', + }, + message: { + type: 'track', + event: 'Credit Card Added', + context: {}, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'The event was discarded as it was not allow listed in the destination configuration', + statTags: { + destType: 'CLICKUP', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'clickup', + description: 'Event filtering : No event is whitelisted', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiToken: 'pk_123', + listId: 'correctListId123', + whitelistedEvents: [ + { + eventName: '', + }, + { + eventName: '', + }, + { + eventName: '', + }, + ], + }, + ID: 'clickup-1234', + }, + message: { + type: 'track', + event: 'Credit Card Added', + context: {}, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'The event was discarded as it was not allow listed in the destination configuration', + statTags: { + destType: 'CLICKUP', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'clickup', + description: 'Creating task using listId from externalId array', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiToken: 'pk_123', + listId: 'correctListId123', + }, + ID: 'clickup-1234', + }, + message: { + type: 'track', + event: 'anonymous page visit', + context: { + externalId: [ + { + type: 'clickUpListId', + id: 'correctListId456', + }, + ], + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.clickup.com/api/v2/list/correctListId456/task', + headers: { + 'Content-Type': 'application/json', + Authorization: 'pk_123', + }, + params: {}, + body: { + JSON: { + name: 'anonymous page visit', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/criteo_audience/dataDelivery/business.ts b/test/integrations/destinations/criteo_audience/dataDelivery/business.ts new file mode 100644 index 00000000000..f30bf73d7a9 --- /dev/null +++ b/test/integrations/destinations/criteo_audience/dataDelivery/business.ts @@ -0,0 +1,255 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV1Payload, generateMetadata } from '../../../testUtils'; +export const headers = { + Authorization: 'Bearer success_access_token', + 'Content-Type': 'application/json', + Accept: 'application/json', +}; +export const params = { + destination: 'criteo_audience', +}; +const method = 'PATCH'; + +export const V1BusinessTestScenarion: ProxyV1TestData[] = [ + { + id: 'criteo_audience_business_0', + name: 'criteo_audience', + description: '[Business]:: Test for gum type audience with gumCallerId with success response', + successCriteria: 'Should return a 200 status code with a success message', + scenario: 'business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'remove', + identifierType: 'gum', + identifiers: ['sample_gum3'], + internalIdentifiers: false, + gumCallerId: '329739', + }, + }, + }, + params, + headers, + method, + endpoint: 'https://api.criteo.com/2022-10/audiences/34894/contactlist', + }, + [generateMetadata(1)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + response: [ + { + error: '""', + metadata: generateMetadata(1), + statusCode: 200, + }, + ], + }, + }, + }, + }, + }, + { + id: 'criteo_audience_business_1', + name: 'criteo_audience', + scenario: 'business', + description: '[Business]:: Test for email type audience to add users with success response', + successCriteria: 'Should return a 200 status code with a success message', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + method: 'POST', + body: generateProxyV1Payload( + { + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'email', + internalIdentifiers: false, + identifiers: [ + 'alex@email.com', + 'amy@email.com', + 'van@email.com', + 'alex@email.com', + 'amy@email.com', + 'van@email.com', + ], + }, + }, + }, + params, + headers, + method, + endpoint: 'https://api.criteo.com/2022-10/audiences/34894/contactlist', + }, + [generateMetadata(2)], + ), + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + response: [ + { + error: '""', + metadata: generateMetadata(2), + statusCode: 200, + }, + ], + }, + }, + }, + }, + }, + { + id: 'criteo_audience_business_2', + name: 'criteo_audience', + scenario: 'business', + description: '[Business]:: Test for mobile type audience to remove users with success response', + successCriteria: 'Should return a 200 status code with a success message', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + method: 'POST', + body: generateProxyV1Payload( + { + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'remove', + identifierType: 'madid', + internalIdentifiers: false, + identifiers: [ + 'sample_madid', + 'sample_madid_1', + 'sample_madid_2', + 'sample_madid_10', + 'sample_madid_13', + 'sample_madid_11', + 'sample_madid_12', + ], + }, + }, + }, + params, + headers, + method, + endpoint: 'https://api.criteo.com/2022-10/audiences/34893/contactlist', + }, + [generateMetadata(3)], + ), + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + response: [ + { + error: '""', + metadata: generateMetadata(3), + statusCode: 200, + }, + ], + }, + }, + }, + }, + }, + { + id: 'criteo_audience_business_3', + name: 'criteo_audience', + scenario: 'business', + description: '[Business]:: Test for mobile type audience where audienceId is invalid', + successCriteria: + 'Should return a 400 status code with an error audience-invalid. It should also have the invalid audienceId in the error message as follows: "Audience is invalid"', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + method: 'POST', + body: generateProxyV1Payload( + { + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, + }, + params, + headers, + method, + endpoint: 'https://api.criteo.com/2022-10/audiences/34896/contactlist', + }, + [generateMetadata(4)], + ), + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'AudienceId is Invalid. Please Provide Valid AudienceId', + response: [ + { + error: + '{"errors":[{"traceIdentifier":"80a1a0ba3981b04da847d05700752c77","type":"authorization","code":"audience-invalid"}]}', + metadata: generateMetadata(4), + statusCode: 400, + }, + ], + statTags: { + destType: 'CRITEO_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + meta: 'instrumentation', + module: 'destination', + }, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/criteo_audience/dataDelivery/data.ts b/test/integrations/destinations/criteo_audience/dataDelivery/data.ts index 162e5663659..c603ef66648 100644 --- a/test/integrations/destinations/criteo_audience/dataDelivery/data.ts +++ b/test/integrations/destinations/criteo_audience/dataDelivery/data.ts @@ -1,530 +1,541 @@ -export const data = [ +import { generateMetadata } from '../../../testUtils'; +import { V1BusinessTestScenarion } from './business'; +import { v1OauthScenarios } from './oauth'; +import { v1OtherScenarios } from './other'; + +const v0testCases = [ { - "name": "criteo_audience", - "description": "Test 0", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "PATCH", - "endpoint": "https://api.criteo.com/2022-10/audiences/34894/contactlist", - "headers": { - "Authorization": "Bearer success_access_token", - "Content-Type": "application/json", - "Accept": "application/json" + name: 'criteo_audience', + description: 'Test 0', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'PATCH', + endpoint: 'https://api.criteo.com/2022-10/audiences/34894/contactlist', + headers: { + Authorization: 'Bearer success_access_token', + 'Content-Type': 'application/json', + Accept: 'application/json', }, - "body": { - "JSON": { - "data": { - "type": "ContactlistAmendment", - "attributes": { - "operation": "remove", - "identifierType": "gum", - "identifiers": [ - "sample_gum3" - ], - "internalIdentifiers": false, - "gumCallerId": "329739" - } - } + body: { + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'remove', + identifierType: 'gum', + identifiers: ['sample_gum3'], + internalIdentifiers: false, + gumCallerId: '329739', + }, + }, }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + params: { + destination: 'criteo_audience', }, - "files": {}, - "params": { - "destination": "criteo_audience" - } + userId: '1234', + metadata: generateMetadata(1), + destinationConfig: {}, }, - "method": "POST" - } + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + destinationResponse: { + response: '', + status: 200, + }, + }, + }, + }, }, - "output": { - "response": { - "status": 200, - "body": { - "output": { - "status": 200, - "message": "Request Processed Successfully", - "destinationResponse": { - "response": "", - "status": 200 - } - } - } - } - } }, { - "name": "criteo_audience", - "description": "Test 1", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "PATCH", - "endpoint": "https://api.criteo.com/2022-10/audiences/3485/contactlist", - "headers": { - "Authorization": "Bearer success_access_token", - "Content-Type": "application/json", - "Accept": "application/json" + name: 'criteo_audience', + description: 'Test 1', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'PATCH', + endpoint: 'https://api.criteo.com/2022-10/audiences/3485/contactlist/expiredAccessToken', + headers: { + Authorization: 'Bearer success_access_token', + 'Content-Type': 'application/json', + Accept: 'application/json', }, - "body": { - "JSON": { - "data": { - "type": "ContactlistAmendment", - "attributes": { - "operation": "add", - "identifierType": "madid", - "identifiers": [ - "sample_madid", - "sample_madid_1", - "sample_madid_2" - ], - "internalIdentifiers": false - } - } + body: { + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + params: { + destination: 'criteo_audience', }, - "files": {}, - "params": { - "destination": "criteo_audience" - } + userId: '1234', + metadata: generateMetadata(2), + destinationConfig: {}, }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 401, - "body": { - "output": { - "status": 401, - "authErrorCategory": "REFRESH_TOKEN", - "destinationResponse": { - "errors": [ + output: { + response: { + status: 401, + body: { + output: { + status: 401, + authErrorCategory: 'REFRESH_TOKEN', + destinationResponse: { + errors: [ { - "traceIdentifier": "80a1a0ba3981b04da847d05700752c77", - "type": "authorization", - "code": "authorization-token-expired", - "instance": "/2022-10/audiences/123/contactlist", - "title": "The authorization token has expired" - } - ] + traceIdentifier: '80a1a0ba3981b04da847d05700752c77', + type: 'authorization', + code: 'authorization-token-expired', + instance: '/2022-10/audiences/123/contactlist', + title: 'The authorization token has expired', + }, + ], }, - "message": "The authorization token has expired during criteo_audience response transformation", - "statTags": { - "destType": "CRITEO_AUDIENCE", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } + message: + 'The authorization token has expired during criteo_audience response transformation', + statTags: { + destType: 'CRITEO_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + }, + }, + }, + }, + }, }, { - "name": "criteo_audience", - "description": "Test 2", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "PATCH", - "endpoint": "https://api.criteo.com/2022-10/audiences/34895/contactlist", - "headers": { - "Authorization": "Bearer success_access_token", - "Content-Type": "application/json", - "Accept": "application/json" + name: 'criteo_audience', + description: 'Test 2', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'PATCH', + endpoint: 'https://api.criteo.com/2022-10/audiences/34895/contactlist/invalidAccessToken', + headers: { + Authorization: 'Bearer success_access_token', + 'Content-Type': 'application/json', + Accept: 'application/json', }, - "body": { - "JSON": { - "data": { - "type": "ContactlistAmendment", - "attributes": { - "operation": "add", - "identifierType": "madid", - "identifiers": [ - "sample_madid", - "sample_madid_1", - "sample_madid_2" - ], - "internalIdentifiers": false - } - } + body: { + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} + JSON_ARRAY: {}, + XML: {}, + FORM: {}, }, - "files": {}, - "params": { - "destination": "criteo_audience" - } + files: {}, + params: { + destination: 'criteo_audience', + }, + userId: '1234', + metadata: generateMetadata(3), + destinationConfig: {}, }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 401, - "body": { - "output": { - "status": 401, - "authErrorCategory": "REFRESH_TOKEN", - "destinationResponse": { - "errors": [ + output: { + response: { + status: 401, + body: { + output: { + status: 401, + authErrorCategory: 'REFRESH_TOKEN', + destinationResponse: { + errors: [ { - "traceIdentifier": "80a1a0ba3981b04da847d05700752c77", - "type": "authorization", - "code": "authorization-token-invalid", - "instance": "/2022-10/audiences/123/contactlist", - "title": "The authorization header is invalid" - } - ] + traceIdentifier: '80a1a0ba3981b04da847d05700752c77', + type: 'authorization', + code: 'authorization-token-invalid', + instance: '/2022-10/audiences/123/contactlist', + title: 'The authorization header is invalid', + }, + ], + }, + message: + 'The authorization header is invalid during criteo_audience response transformation', + statTags: { + destType: 'CRITEO_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', }, - "message": "The authorization header is invalid during criteo_audience response transformation", - "statTags": { - "destType": "CRITEO_AUDIENCE", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } + }, + }, + }, + }, }, { - "name": "criteo_audience", - "description": "Test 3", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "PATCH", - "endpoint": "https://api.criteo.com/2022-10/audiences/34896/contactlist", - "headers": { - "Authorization": "Bearer success_access_token", - "Content-Type": "application/json", - "Accept": "application/json" + name: 'criteo_audience', + description: 'Test 3', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'PATCH', + endpoint: 'https://api.criteo.com/2022-10/audiences/34896/contactlist', + headers: { + Authorization: 'Bearer success_access_token', + 'Content-Type': 'application/json', + Accept: 'application/json', }, - "body": { - "JSON": { - "data": { - "type": "ContactlistAmendment", - "attributes": { - "operation": "add", - "identifierType": "madid", - "identifiers": [ - "sample_madid", - "sample_madid_1", - "sample_madid_2" - ], - "internalIdentifiers": false - } - } + body: { + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + params: { + destination: 'criteo_audience', }, - "files": {}, - "params": { - "destination": "criteo_audience" - } + userId: '1234', + metadata: generateMetadata(4), + destinationConfig: {}, }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 400, - "body": { - "output": { - "message": "AudienceId is Invalid. Please Provide Valid AudienceId", - "destinationResponse": { - "response": { - "errors": [ + output: { + response: { + status: 400, + body: { + output: { + message: 'AudienceId is Invalid. Please Provide Valid AudienceId', + destinationResponse: { + response: { + errors: [ { - "code": "audience-invalid", - "traceIdentifier": "80a1a0ba3981b04da847d05700752c77", - "type": "authorization" - } - ] + code: 'audience-invalid', + traceIdentifier: '80a1a0ba3981b04da847d05700752c77', + type: 'authorization', + }, + ], }, - "status": 404 + status: 404, }, - "statTags": { - "destType": "CRITEO_AUDIENCE", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "meta": "instrumentation", - "module": "destination" + statTags: { + destType: 'CRITEO_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + meta: 'instrumentation', + module: 'destination', }, - "status": 400 - } - } - } - } + status: 400, + }, + }, + }, + }, }, { - "name": "criteo_audience", - "description": "Test 4", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "PATCH", - "endpoint": "https://api.criteo.com/2022-10/audiences/34897/contactlist", - "headers": { - "Authorization": "Bearer success_access_token", - "Content-Type": "application/json", - "Accept": "application/json" + name: 'criteo_audience', + description: 'Test 4', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'PATCH', + endpoint: 'https://api.criteo.com/2022-10/audiences/34897/contactlist', + headers: { + Authorization: 'Bearer success_access_token', + 'Content-Type': 'application/json', + Accept: 'application/json', }, - "body": { - "JSON": { - "data": { - "type": "ContactlistAmendment", - "attributes": { - "operation": "add", - "identifierType": "madid", - "identifiers": [ - "sample_madid", - "sample_madid_1", - "sample_madid_2" - ], - "internalIdentifiers": false - } - } + body: { + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + params: { + destination: 'criteo_audience', }, - "files": {}, - "params": { - "destination": "criteo_audience" - } + userId: '1234', + metadata: generateMetadata(5), + destinationConfig: {}, }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 500, - "body": { - "output": { - "destinationResponse": { - "response": { - "errors": [ + output: { + response: { + status: 500, + body: { + output: { + destinationResponse: { + response: { + errors: [ { - "code": "audience-invalid", - "traceIdentifier": "80a1a0ba3981b04da847d05700752c77", - "type": "authorization" - } - ] + code: 'audience-invalid', + traceIdentifier: '80a1a0ba3981b04da847d05700752c77', + type: 'authorization', + }, + ], }, - "status": 503 + status: 503, }, - "message": "Request Failed: during criteo_audience response transformation (Retryable)", - "statTags": { - "destType": "CRITEO_AUDIENCE", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "feature": "dataDelivery", - "implementation": "native", - "errorType": "retryable", - "module": "destination" + message: 'Request Failed: during criteo_audience response transformation (Retryable)', + statTags: { + destType: 'CRITEO_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + feature: 'dataDelivery', + implementation: 'native', + errorType: 'retryable', + module: 'destination', }, - "status": 500 - } - } - } - } + status: 500, + }, + }, + }, + }, }, { - "name": "criteo_audience", - "description": "Test 5", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "PATCH", - "endpoint": "https://api.criteo.com/2022-10/audiences/34898/contactlist", - "headers": { - "Authorization": "Bearer success_access_token", - "Content-Type": "application/json", - "Accept": "application/json" + name: 'criteo_audience', + description: 'Test 5', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'PATCH', + endpoint: 'https://api.criteo.com/2022-10/audiences/34898/contactlist', + headers: { + Authorization: 'Bearer success_access_token', + 'Content-Type': 'application/json', + Accept: 'application/json', }, - "body": { - "JSON": { - "data": { - "type": "ContactlistAmendment", - "attributes": { - "operation": "add", - "identifierType": "madid", - "identifiers": [ - "sample_madid", - "sample_madid_1", - "sample_madid_2" - ], - "internalIdentifiers": false - } - } + body: { + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + params: { + destination: 'criteo_audience', }, - "files": {}, - "params": { - "destination": "criteo_audience" - } + userId: '1234', + metadata: generateMetadata(6), + destinationConfig: {}, }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 429, - "body": { - "output": { - "destinationResponse": { - "response": {}, - "status": 429 + output: { + response: { + status: 429, + body: { + output: { + destinationResponse: { + response: {}, + status: 429, }, - "message": "Request Failed: during criteo_audience response transformation - due to Request Limit exceeded, (Throttled)", - "statTags": { - "destType": "CRITEO_AUDIENCE", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "throttled", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" + message: + 'Request Failed: during criteo_audience response transformation - due to Request Limit exceeded, (Throttled)', + statTags: { + destType: 'CRITEO_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'throttled', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', }, - "status": 429 - } - } - } - } + status: 429, + }, + }, + }, + }, }, { - "name": "criteo_audience", - "description": "Test 6", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "PATCH", - "endpoint": "https://api.criteo.com/2022-10/audiences/34899/contactlist", - "headers": { - "Authorization": "Bearer success_access_token", - "Content-Type": "application/json", - "Accept": "application/json" + name: 'criteo_audience', + description: 'Test 6', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'PATCH', + endpoint: 'https://api.criteo.com/2022-10/audiences/34899/contactlist', + headers: { + Authorization: 'Bearer success_access_token', + 'Content-Type': 'application/json', + Accept: 'application/json', }, - "body": { - "JSON": { - "data": { - "type": "ContactlistAmendment", - "attributes": { - "operation": "add", - "identifierType": "madid", - "identifiers": [ - "sample_madid", - "sample_madid_1", - "sample_madid_2" - ], - "internalIdentifiers": false - } - } + body: { + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + params: { + destination: 'criteo_audience', }, - "files": {}, - "params": { - "destination": "criteo_audience" - } + userId: '1234', + metadata: generateMetadata(7), + destinationConfig: {}, }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 400, - "body": { - "output": { - "destinationResponse": { - "response": { - "message": "unknown error" + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: { + response: { + message: 'unknown error', }, - "status": 410 + status: 410, }, - "message": "Request Failed: during criteo_audience response transformation with status \"410\" due to \"{\"message\":\"unknown error\"}\", (Aborted) ", - "statTags": { - "destType": "CRITEO_AUDIENCE", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" + message: + 'Request Failed: during criteo_audience response transformation with status "410" due to "{"message":"unknown error"}", (Aborted) ', + statTags: { + destType: 'CRITEO_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', }, - "status": 400 - } - } - } - } - } -] + status: 400, + }, + }, + }, + }, + }, +]; + +export const data = [ + ...v0testCases, + ...V1BusinessTestScenarion, + ...v1OauthScenarios, + ...v1OtherScenarios, +]; diff --git a/test/integrations/destinations/criteo_audience/dataDelivery/oauth.ts b/test/integrations/destinations/criteo_audience/dataDelivery/oauth.ts new file mode 100644 index 00000000000..982397f7c33 --- /dev/null +++ b/test/integrations/destinations/criteo_audience/dataDelivery/oauth.ts @@ -0,0 +1,133 @@ +import { params, headers } from './business'; +import { generateProxyV1Payload, generateMetadata } from '../../../testUtils'; + +const commonStatTags = { + destType: 'CRITEO_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', +}; + +export const v1OauthScenarios = [ + { + id: 'criteo_audience_oauth_0', + name: 'criteo_audience', + description: '[OAUTH]:: Test expired access token', + successCriteria: 'Should return a 401 status code with authErrorCategory as REFRESH_TOKEN', + scenario: 'oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, + }, + params, + headers, + method: 'PATCH', + endpoint: + 'https://api.criteo.com/2022-10/audiences/3485/contactlist/expiredAccessToken', + }, + [generateMetadata(1)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 401, + body: { + output: { + status: 401, + authErrorCategory: 'REFRESH_TOKEN', + response: [ + { + error: + 'The authorization token has expired during criteo_audience response transformation', + metadata: generateMetadata(1), + statusCode: 401, + }, + ], + message: + 'The authorization token has expired during criteo_audience response transformation', + statTags: commonStatTags, + }, + }, + }, + }, + }, + { + id: 'criteo_audience_oauth_1', + name: 'criteo_audience', + description: '[OAUTH]:: Test invalid access token', + successCriteria: + 'We should get a 401 status code with errorCode authorization-token-invalid. As we need to refresh the token for these conditions, authErrorCategory should be REFRESH_TOKEN', + scenario: 'oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, + }, + params, + headers, + method: 'PATCH', + endpoint: + 'https://api.criteo.com/2022-10/audiences/34895/contactlist/invalidAccessToken', + }, + [generateMetadata(2)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 401, + body: { + output: { + status: 401, + authErrorCategory: 'REFRESH_TOKEN', + response: [ + { + error: + 'The authorization header is invalid during criteo_audience response transformation', + metadata: generateMetadata(2), + statusCode: 401, + }, + ], + statTags: commonStatTags, + message: + 'The authorization header is invalid during criteo_audience response transformation', + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/criteo_audience/dataDelivery/other.ts b/test/integrations/destinations/criteo_audience/dataDelivery/other.ts new file mode 100644 index 00000000000..145be62528a --- /dev/null +++ b/test/integrations/destinations/criteo_audience/dataDelivery/other.ts @@ -0,0 +1,197 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { params, headers } from './business'; +import { generateProxyV1Payload, generateMetadata } from '../../../testUtils'; + +export const v1OtherScenarios: ProxyV1TestData[] = [ + { + id: 'criteo_audience_other_0', + name: 'criteo_audience', + description: '[Other]:: Test for checking service unavailable scenario', + successCriteria: 'Should return a 500 status code with', + scenario: 'other', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers, + params, + method: 'PATCH', + endpoint: 'https://random_test_url/test_for_internal_server_error', + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, + }, + }, + [generateMetadata(1)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 500, + response: [ + { + error: '""', + metadata: generateMetadata(1), + statusCode: 500, + }, + ], + message: 'Request Failed: during criteo_audience response transformation (Retryable)', + statTags: { + destType: 'CRITEO_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + feature: 'dataDelivery', + implementation: 'native', + errorType: 'retryable', + module: 'destination', + }, + }, + }, + }, + }, + }, + { + id: 'criteo_audience_other_1', + name: 'criteo_audience', + description: '[Other]:: Test for checking throttling scenario', + successCriteria: 'Should return a 429 status code', + scenario: 'other', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers, + params, + method: 'PATCH', + endpoint: 'https://random_test_url/test_for_too_many_requests', + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, + }, + }, + [generateMetadata(2)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 429, + response: [ + { + error: '{}', + metadata: generateMetadata(2), + statusCode: 429, + }, + ], + message: + 'Request Failed: during criteo_audience response transformation - due to Request Limit exceeded, (Throttled)', + statTags: { + destType: 'CRITEO_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + feature: 'dataDelivery', + implementation: 'native', + errorType: 'throttled', + module: 'destination', + }, + }, + }, + }, + }, + }, + { + id: 'criteo_audience_other_2', + name: 'criteo_audience', + description: '[Other]:: Test for checking unknown error scenario', + successCriteria: 'Should return a 410 status code and abort the event', + scenario: 'other', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers, + params, + method: 'PATCH', + JSON: { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, + }, + endpoint: 'https://api.criteo.com/2022-10/audiences/34899/contactlist', + }, + [generateMetadata(3)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + response: [ + { + error: '{"message":"unknown error"}', + metadata: generateMetadata(3), + statusCode: 400, + }, + ], + message: + 'Request Failed: during criteo_audience response transformation with status "410" due to "{"message":"unknown error"}", (Aborted) ', + statTags: { + destType: 'CRITEO_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + }, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/criteo_audience/network.ts b/test/integrations/destinations/criteo_audience/network.ts index 959e8a21127..7ccf649e2a0 100644 --- a/test/integrations/destinations/criteo_audience/network.ts +++ b/test/integrations/destinations/criteo_audience/network.ts @@ -1,3 +1,23 @@ +const headers = { + Authorization: 'Bearer success_access_token', + 'Content-Type': 'application/json', + Accept: 'application/json', + 'User-Agent': 'RudderLabs', +}; +const params = { destination: 'criteo_audience' }; +const method = 'PATCH'; +const commonData = { + data: { + type: 'ContactlistAmendment', + attributes: { + operation: 'add', + identifierType: 'madid', + identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + internalIdentifiers: false, + }, + }, +}; + export const networkCallsData = [ { httpReq: { @@ -14,117 +34,74 @@ export const networkCallsData = [ }, }, }, - params: { destination: 'criteo_audience' }, - headers: { - Authorization: 'Bearer success_access_token', - 'Content-Type': 'application/json', - Accept: 'application/json', - 'User-Agent': 'RudderLabs', - }, - method: 'PATCH', + params, + headers, + method, }, httpRes: { status: 200 }, }, { httpReq: { - url: 'https://api.criteo.com/2022-10/audiences/3485/contactlist', + url: 'https://api.criteo.com/2022-10/audiences/34894/contactlist', data: { data: { type: 'ContactlistAmendment', attributes: { operation: 'add', - identifierType: 'madid', - identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], + identifierType: 'email', internalIdentifiers: false, + identifiers: [ + 'alex@email.com', + 'amy@email.com', + 'van@email.com', + 'alex@email.com', + 'amy@email.com', + 'van@email.com', + ], }, }, }, - params: { destination: 'criteo_audience' }, - headers: { - Authorization: 'Bearer success_access_token', - 'Content-Type': 'application/json', - Accept: 'application/json', - 'User-Agent': 'RudderLabs', - }, - method: 'PATCH', - }, - httpRes: { - code: '400', - data: { - errors: [ - { - traceIdentifier: '80a1a0ba3981b04da847d05700752c77', - type: 'authorization', - code: 'authorization-token-expired', - instance: '/2022-10/audiences/123/contactlist', - title: 'The authorization token has expired', - }, - ], - }, - status: 401, + params, + headers, + method, }, + httpRes: { status: 200 }, }, { httpReq: { - url: 'https://api.criteo.com/2022-10/audiences/34895/contactlist', + url: 'https://api.criteo.com/2022-10/audiences/34893/contactlist', data: { data: { type: 'ContactlistAmendment', attributes: { - operation: 'add', + operation: 'remove', identifierType: 'madid', - identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], internalIdentifiers: false, + identifiers: [ + 'sample_madid', + 'sample_madid_1', + 'sample_madid_2', + 'sample_madid_10', + 'sample_madid_13', + 'sample_madid_11', + 'sample_madid_12', + ], }, }, }, - params: { destination: 'criteo_audience' }, - headers: { - Authorization: 'Bearer success_access_token', - 'Content-Type': 'application/json', - Accept: 'application/json', - 'User-Agent': 'RudderLabs', - }, - method: 'PATCH', - }, - httpRes: { - code: '400', - data: { - errors: [ - { - traceIdentifier: '80a1a0ba3981b04da847d05700752c77', - type: 'authorization', - code: 'authorization-token-invalid', - instance: '/2022-10/audiences/123/contactlist', - title: 'The authorization header is invalid', - }, - ], - }, - status: 401, + params, + headers, + method, }, + httpRes: { status: 200 }, }, { httpReq: { url: 'https://api.criteo.com/2022-10/audiences/34896/contactlist', - data: { - data: { - type: 'ContactlistAmendment', - attributes: { - operation: 'add', - identifierType: 'madid', - identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], - internalIdentifiers: false, - }, - }, - }, - params: { destination: 'criteo_audience' }, - headers: { - Authorization: 'Bearer success_access_token', - 'Content-Type': 'application/json', - Accept: 'application/json', - 'User-Agent': 'RudderLabs', - }, - method: 'PATCH', + data: commonData, + params, + headers, + method, }, httpRes: { code: '400', @@ -143,25 +120,10 @@ export const networkCallsData = [ { httpReq: { url: 'https://api.criteo.com/2022-10/audiences/34897/contactlist', - data: { - data: { - type: 'ContactlistAmendment', - attributes: { - operation: 'add', - identifierType: 'madid', - identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], - internalIdentifiers: false, - }, - }, - }, - params: { destination: 'criteo_audience' }, - headers: { - Authorization: 'Bearer success_access_token', - 'Content-Type': 'application/json', - Accept: 'application/json', - 'User-Agent': 'RudderLabs', - }, - method: 'PATCH', + data: commonData, + params, + headers, + method, }, httpRes: { code: '500', @@ -180,50 +142,20 @@ export const networkCallsData = [ { httpReq: { url: 'https://api.criteo.com/2022-10/audiences/34898/contactlist', - data: { - data: { - type: 'ContactlistAmendment', - attributes: { - operation: 'add', - identifierType: 'madid', - identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], - internalIdentifiers: false, - }, - }, - }, - params: { destination: 'criteo_audience' }, - headers: { - Authorization: 'Bearer success_access_token', - 'Content-Type': 'application/json', - Accept: 'application/json', - 'User-Agent': 'RudderLabs', - }, - method: 'PATCH', + data: commonData, + params, + headers, + method, }, httpRes: { code: '429', data: {}, status: 429 }, }, { httpReq: { url: 'https://api.criteo.com/2022-10/audiences/34899/contactlist', - data: { - data: { - type: 'ContactlistAmendment', - attributes: { - operation: 'add', - identifierType: 'madid', - identifiers: ['sample_madid', 'sample_madid_1', 'sample_madid_2'], - internalIdentifiers: false, - }, - }, - }, - params: { destination: 'criteo_audience' }, - headers: { - Authorization: 'Bearer success_access_token', - 'Content-Type': 'application/json', - Accept: 'application/json', - 'User-Agent': 'RudderLabs', - }, - method: 'PATCH', + data: commonData, + params, + headers, + method, }, httpRes: { code: '400', data: { message: 'unknown error' }, status: 410 }, }, diff --git a/test/integrations/destinations/custify/deleteUsers/data.ts b/test/integrations/destinations/custify/deleteUsers/data.ts new file mode 100644 index 00000000000..22a120770a1 --- /dev/null +++ b/test/integrations/destinations/custify/deleteUsers/data.ts @@ -0,0 +1,158 @@ +const destType = 'custify'; +const commonData = { + name: destType, + feature: 'userDeletion', + module: 'destination', + version: 'v0', +}; + +export const data = [ + { + description: 'Test 0: should fail when config is not being sent', + input: { + request: { + body: [ + { + destType: destType.toUpperCase(), + userAttributes: [ + { + userId: 'rudder1', + }, + ], + }, + ], + }, + }, + output: { + response: { + status: 400, + body: [ + { + statusCode: 400, + error: 'Config for deletion not present', + }, + ], + }, + }, + }, + { + description: 'Test 1: should fail when apiKey is not present in config', + input: { + request: { + body: [ + { + destType: destType.toUpperCase(), + userAttributes: [ + { + userId: 'rudder2', + }, + ], + config: { + apiToken: 'dummyApiKey', + }, + }, + ], + }, + }, + output: { + response: { + status: 400, + body: [ + { + statusCode: 400, + error: 'api key for deletion not present', + }, + ], + }, + }, + }, + + { + description: 'Test 2: should pass when one of the users is not present in destination', + input: { + request: { + body: [ + { + destType: destType.toUpperCase(), + userAttributes: [ + { + userId: 'rudder1', + }, + { + userId: 'rudder2', + }, + ], + config: { + apiKey: 'dummyApiKey', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [{ statusCode: 200, status: 'successful' }], + }, + }, + }, + + { + description: + 'Test 3: should fail when one of the users is returning with 4xx(not 404) from destination', + input: { + request: { + body: [ + { + destType: destType.toUpperCase(), + userAttributes: [ + { + userId: 'rudder1', + }, + { + userId: 'rudder3', + }, + ], + config: { + apiKey: 'dummyApiKey', + }, + }, + ], + }, + }, + output: { + response: { + status: 400, + body: [{ statusCode: 400, error: '{"error":"User: rudder3 has a problem"}' }], + }, + }, + }, + + { + description: 'Test 4: should fail when one of the userAttributes does not contain `userId`', + input: { + request: { + body: [ + { + destType: destType.toUpperCase(), + userAttributes: [ + { + userId: 'rudder1', + }, + {}, + ], + config: { + apiKey: 'dummyApiKey', + }, + }, + ], + }, + }, + output: { + response: { + status: 400, + body: [{ statusCode: 400, error: 'User id for deletion not present' }], + }, + }, + }, +].map((props) => ({ ...commonData, ...props })); diff --git a/test/integrations/destinations/custify/network.ts b/test/integrations/destinations/custify/network.ts index 4af6545f9fa..242f54c97b2 100644 --- a/test/integrations/destinations/custify/network.ts +++ b/test/integrations/destinations/custify/network.ts @@ -1,36 +1,85 @@ export const networkCallsData = [ - { - httpReq: { - url: 'https://api.custify.com/company', - method: 'POST', + { + httpReq: { + url: 'https://api.custify.com/company', + method: 'POST', + }, + httpRes: { + data: { + company_id: '6', + name: 'Pizzeria Presto', + signed_up_at: '2019-05-30T12:00:00.000Z', + size: 15, + website: 'www.pizzeriapresto.com', + industry: 'Restaurant', + plan: 'Platinum', + monthly_revenue: 1234567, + churned: false, + owners_csm: 'john.doe@mail.com', + owners_account: 'john.doe@mail.com', + parent_companies: [ + { + id: '5ec50c9829d3c17c7cf455f2', + }, + { + id: '5ec50c9829d3c17c7cf457f2', + }, + ], + custom_attributes: { + restaurants: 5, + custom: 'template', }, - httpRes: { - data: { - "company_id": "6", - "name": "Pizzeria Presto", - "signed_up_at": "2019-05-30T12:00:00.000Z", - "size": 15, - "website": "www.pizzeriapresto.com", - "industry": "Restaurant", - "plan": "Platinum", - "monthly_revenue": 1234567, - "churned": false, - "owners_csm": "john.doe@mail.com", - "owners_account": "john.doe@mail.com", - "parent_companies": [ - { - "id": "5ec50c9829d3c17c7cf455f2" - }, - { - "id": "5ec50c9829d3c17c7cf457f2" - } - ], - "custom_attributes": { - "restaurants": 5, - "custom": "template" - } - }, - status: 200 - }, - } + }, + status: 200, + }, + }, + + { + httpReq: { + method: 'delete', + url: 'https://api.custify.com/people?user_id=rudder1', + headers: { + Authorization: 'Bearer dummyApiKey', + }, + }, + httpRes: { + data: { + msg: 'All users associated with rudder1 were successfully deleted', + code: 'Success', + params: null, + }, + status: 200, + }, + }, + { + httpReq: { + method: 'delete', + url: 'https://api.custify.com/people?user_id=rudder2', + headers: { + Authorization: 'Bearer dummyApiKey', + }, + }, + httpRes: { + data: { + error: 'User: rudder2 not found', + }, + status: 404, + }, + }, + + { + httpReq: { + method: 'delete', + url: 'https://api.custify.com/people?user_id=rudder3', + headers: { + Authorization: 'Bearer dummyApiKey', + }, + }, + httpRes: { + data: { + error: 'User: rudder3 has a problem', + }, + status: 400, + }, + }, ]; diff --git a/test/integrations/destinations/custify/processor/data.ts b/test/integrations/destinations/custify/processor/data.ts index 8b6fc934f4c..b5bd8bd753f 100644 --- a/test/integrations/destinations/custify/processor/data.ts +++ b/test/integrations/destinations/custify/processor/data.ts @@ -1,695 +1,672 @@ export const data = [ - { - "name": "custify", - "description": "Identify Call with all traits and adding to company", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "apiKey_key_test_001", - "sendAnonymousId": false - }, - "ID": "custify-1234" - }, - "message": { - "type": "identify", - "userId": "user_1234", - "context": { - "traits": { - "email": "user111@gmail.com", - "firstName": "New", - "lastName": "User", - "phone": 9830311522, - "sessionCount": 23, - "unsubscribedFromEmails": false, - "unsubscribedFromCalls": false, - "signed_up_at": "2022-04-27T13:56:13.012Z", - "custom_prop1": "custom_value1", - "custom_prop2": 123, - "custom_prop3": false, - "custom_prop4": { - "test": "test" - }, - "custom_prop5": [ - 1, - 3, - 4 - ], - "createdAt": "2022-04-27T13:56:13.012Z", - "company": { - "id": "company_123" - } - } - }, - "timestamp": "2022-04-27T13:56:13.012Z", - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.custify.com/people", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer apiKey_key_test_001", - "Accept": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "user_id": "user_1234", - "email": "user111@gmail.com", - "phone": 9830311522, - "session_count": 23, - "unsubscribed_from_emails": false, - "unsubscribed_from_calls": false, - "signed_up_at": "2022-04-27T13:56:13.012Z", - "custom_attributes": { - "firstName": "New", - "lastName": "User", - "sessionCount": 23, - "unsubscribedFromEmails": false, - "unsubscribedFromCalls": false, - "custom_prop1": "custom_value1", - "custom_prop2": 123, - "custom_prop3": false, - "createdAt": "2022-04-27T13:56:13.012Z" - }, - "name": "New User", - "companies": [ - { - "company_id": "company_123", - "remove": false - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "user_1234" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "custify", - "description": "Identify Call removing the user from company", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "apiKey_key_test_001", - "sendAnonymousId": false - }, - "ID": "custify-1234" - }, - "message": { - "type": "identify", - "userId": "user_1234", - "context": { - "traits": { - "email": "user111@gmail.com", - "firstName": "New", - "lastName": "User", - "phone": 9830311522, - "sessionCount": 23, - "unsubscribedFromEmails": false, - "unsubscribedFromCalls": false, - "signed_up_at": "2022-04-27T13:56:13.012Z", - "custom_prop1": "custom_value1", - "custom_prop2": 123, - "custom_prop3": false, - "custom_prop4": { - "test": "test" - }, - "custom_prop5": [ - 1, - 3, - 4 - ], - "createdAt": "2022-04-27T13:56:13.012Z", - "company": { - "id": "company_123", - "remove": true - } - } - }, - "timestamp": "2022-04-27T13:56:13.012Z", - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.custify.com/people", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer apiKey_key_test_001", - "Accept": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "user_id": "user_1234", - "email": "user111@gmail.com", - "phone": 9830311522, - "session_count": 23, - "unsubscribed_from_emails": false, - "unsubscribed_from_calls": false, - "signed_up_at": "2022-04-27T13:56:13.012Z", - "custom_attributes": { - "firstName": "New", - "lastName": "User", - "sessionCount": 23, - "unsubscribedFromEmails": false, - "unsubscribedFromCalls": false, - "custom_prop1": "custom_value1", - "custom_prop2": 123, - "custom_prop3": false, - "createdAt": "2022-04-27T13:56:13.012Z" - }, - "name": "New User", - "companies": [ - { - "company_id": "company_123", - "remove": true - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "user_1234" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "custify", - "description": "Identify Call without userId and email and anoymousId", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "apiKey_key_test_001", - "sendAnonymousId": false - }, - "ID": "custify-1234" - }, - "message": { - "type": "identify", - "context": { - "traits": { - "firstName": "New", - "lastName": "User", - "phone": 9830311522, - "sessionCount": 23, - "unsubscribedFromEmails": false, - "unsubscribedFromCalls": false, - "signed_up_at": "2022-04-27T13:56:13.012Z", - "custom_prop1": "custom_value1", - "custom_prop2": 123, - "custom_prop3": false, - "custom_prop4": { - "test": "test" - }, - "custom_prop5": [ - 1, - 3, - 4 - ], - "createdAt": "2022-04-27T13:56:13.012Z", - "company": { - "id": "company_123", - "remove": true - } - } - }, - "timestamp": "2022-04-27T13:56:13.012Z", - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Email or userId is mandatory", - "statTags": { - "destType": "CUSTIFY", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "custify", - "description": "Identify Call without userId and email and sendAnonymous is false", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "apiKey_key_test_001", - "sendAnonymousId": false - }, - "ID": "custify-1234" - }, - "message": { - "type": "identify", - "context": { - "traits": { - "firstName": "New", - "lastName": "User", - "phone": 9830311522, - "sessionCount": 23, - "unsubscribedFromEmails": false, - "unsubscribedFromCalls": false, - "signed_up_at": "2022-04-27T13:56:13.012Z", - "custom_prop1": "custom_value1", - "custom_prop2": 123, - "custom_prop3": false, - "custom_prop4": { - "test": "test" - }, - "custom_prop5": [ - 1, - 3, - 4 - ], - "createdAt": "2022-04-27T13:56:13.012Z", - "company": { - "id": "company_123", - "remove": true - } - } - }, - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "timestamp": "2022-04-27T13:56:13.012Z", - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Email or userId is mandatory", - "statTags": { - "destType": "CUSTIFY", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "custify", - "description": "Identify Call without userId and email and sendAnonymous is true", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "apiKey_key_test_001", - "sendAnonymousId": true - }, - "ID": "custify-1234" - }, - "message": { - "type": "identify", - "context": { - "traits": { - "firstName": "New", - "lastName": "User", - "phone": 9830311522, - "sessionCount": 23, - "unsubscribedFromEmails": false, - "unsubscribedFromCalls": false, - "signed_up_at": "2022-04-27T13:56:13.012Z", - "custom_prop1": "custom_value1", - "custom_prop2": 123, - "custom_prop3": false, - "custom_prop4": { - "test": "test" - }, - "custom_prop5": [ - 1, - 3, - 4 - ], - "createdAt": "2022-04-27T13:56:13.012Z", - "company": { - "id": "company_123", - "remove": true - } - } - }, - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "timestamp": "2022-04-27T13:56:13.012Z", - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.custify.com/people", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer apiKey_key_test_001", - "Accept": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "phone": 9830311522, - "session_count": 23, - "unsubscribed_from_emails": false, - "unsubscribed_from_calls": false, - "signed_up_at": "2022-04-27T13:56:13.012Z", - "custom_attributes": { - "firstName": "New", - "lastName": "User", - "sessionCount": 23, - "unsubscribedFromEmails": false, - "unsubscribedFromCalls": false, - "custom_prop1": "custom_value1", - "custom_prop2": 123, - "custom_prop3": false, - "createdAt": "2022-04-27T13:56:13.012Z" - }, - "user_id": "bf412108-0357-4330-b119-7305e767823c", - "name": "New User", - "companies": [ - { - "company_id": "company_123", - "remove": true - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "bf412108-0357-4330-b119-7305e767823c" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "custify", - "description": "Track call with all properties", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "apiKey_key_test_001", - "sendAnonymousId": false - }, - "ID": "custify-1234" - }, - "message": { - "type": "track", - "event": "Order Completed Version 2", - "sentAt": "2021-08-26T14:16:47.321Z", - "userId": "user_111", - "context": { - "library": { - "name": "analytics-node", - "version": "1.0.3" - }, - "traits": { - "email": "user111@gmail.com" - }, - "page": { - "url": "https://www.website.com/product/path" - } - }, - "rudderId": "70612f39-0607-45bb-8236-bf0995fde4fa", - "_metadata": { - "nodeVersion": "10.24.1" - }, - "messageId": "node-84952e4eb9c6debbda735c49d08a8b31-fcbfed6a-38cf-42c5-881c-f590f59311b1", - "properties": { - "product": "Cube", - "revenue": 9002, - "organization_id": "company_123" - }, - "originalTimestamp": "2021-08-26T14:16:47.317Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.custify.com/event", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer apiKey_key_test_001", - "Accept": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "user_id": "user_111", - "email": "user111@gmail.com", - "name": "Order Completed Version 2", - "created_at": "2021-08-26T14:16:47.317Z", - "company_id": "company_123", - "metadata": { - "product": "Cube", - "revenue": 9002, - "organization_id": "company_123", - "user_id": "user_111" - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "user_111" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "custify", - "description": "Group call with all fields success scenario", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "apiKey_key_test_001", - "sendAnonymousId": false - }, - "ID": "custify-1234" - }, - "message": { - "type": "group", - "userId": "user_111", - "groupId": "company_222", - "traits": { - "name": "Absolute Company", - "industry": " Absolute", - "employees": 121, - "size": 100, - "website": "www.rudder.com", - "plan": "GOLD", - "monthly_revenue": 8000, - "churned": false, - "test_att1": "test_att_val1" - }, - "context": { - "traits": { - "firstName": "Absolute", - "lastName": "User", - "phone": 9830311522, - "session_count": 23, - "signed_up_at": "2022-04-27T13:56:13.012Z", - "custom_prop1": "custom_value1", - "custom_prop2": 123, - "custom_prop3": false, - "custom_prop4": { - "test": "test" - }, - "custom_prop5": [ - 1, - 3, - 4 - ], - "createdAt": "2022-04-27T13:56:13.012Z" - }, - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-01-21T00:21:34.208Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.custify.com/people", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer apiKey_key_test_001", - "Accept": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "user_id": "user_111", - "phone": 9830311522, - "signed_up_at": "2020-01-21T00:21:34.208Z", - "custom_attributes": { - "firstName": "Absolute", - "lastName": "User", - "custom_prop1": "custom_value1", - "custom_prop2": 123, - "custom_prop3": false, - "createdAt": "2022-04-27T13:56:13.012Z" - }, - "name": "Absolute User", - "companies": [ - { - "company_id": "company_222", - "remove": false - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "user_111" - }, - "statusCode": 200 - } - ] - } - } - } -] + { + name: 'custify', + description: 'Identify Call with all traits and adding to company', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'apiKey_key_test_001', + sendAnonymousId: false, + }, + ID: 'custify-1234', + }, + message: { + type: 'identify', + userId: 'user_1234', + context: { + traits: { + email: 'user111@gmail.com', + firstName: 'New', + lastName: 'User', + phone: 9830311522, + sessionCount: 23, + unsubscribedFromEmails: false, + unsubscribedFromCalls: false, + signed_up_at: '2022-04-27T13:56:13.012Z', + custom_prop1: 'custom_value1', + custom_prop2: 123, + custom_prop3: false, + custom_prop4: { + test: 'test', + }, + custom_prop5: [1, 3, 4], + createdAt: '2022-04-27T13:56:13.012Z', + company: { + id: 'company_123', + }, + }, + }, + timestamp: '2022-04-27T13:56:13.012Z', + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.custify.com/people', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer apiKey_key_test_001', + Accept: 'application/json', + }, + params: {}, + body: { + JSON: { + user_id: 'user_1234', + email: 'user111@gmail.com', + phone: 9830311522, + session_count: 23, + unsubscribed_from_emails: false, + unsubscribed_from_calls: false, + signed_up_at: '2022-04-27T13:56:13.012Z', + custom_attributes: { + firstName: 'New', + lastName: 'User', + sessionCount: 23, + unsubscribedFromEmails: false, + unsubscribedFromCalls: false, + custom_prop1: 'custom_value1', + custom_prop2: 123, + custom_prop3: false, + createdAt: '2022-04-27T13:56:13.012Z', + }, + name: 'New User', + companies: [ + { + company_id: 'company_123', + remove: false, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: 'user_1234', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'custify', + description: 'Identify Call removing the user from company', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'apiKey_key_test_001', + sendAnonymousId: false, + }, + ID: 'custify-1234', + }, + message: { + type: 'identify', + userId: 'user_1234', + context: { + traits: { + email: 'user111@gmail.com', + firstName: 'New', + lastName: 'User', + phone: 9830311522, + sessionCount: 23, + unsubscribedFromEmails: false, + unsubscribedFromCalls: false, + signed_up_at: '2022-04-27T13:56:13.012Z', + custom_prop1: 'custom_value1', + custom_prop2: 123, + custom_prop3: false, + custom_prop4: { + test: 'test', + }, + custom_prop5: [1, 3, 4], + createdAt: '2022-04-27T13:56:13.012Z', + company: { + id: 'company_123', + remove: true, + }, + }, + }, + timestamp: '2022-04-27T13:56:13.012Z', + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.custify.com/people', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer apiKey_key_test_001', + Accept: 'application/json', + }, + params: {}, + body: { + JSON: { + user_id: 'user_1234', + email: 'user111@gmail.com', + phone: 9830311522, + session_count: 23, + unsubscribed_from_emails: false, + unsubscribed_from_calls: false, + signed_up_at: '2022-04-27T13:56:13.012Z', + custom_attributes: { + firstName: 'New', + lastName: 'User', + sessionCount: 23, + unsubscribedFromEmails: false, + unsubscribedFromCalls: false, + custom_prop1: 'custom_value1', + custom_prop2: 123, + custom_prop3: false, + createdAt: '2022-04-27T13:56:13.012Z', + }, + name: 'New User', + companies: [ + { + company_id: 'company_123', + remove: true, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: 'user_1234', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'custify', + description: 'Identify Call without userId and email and anoymousId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'apiKey_key_test_001', + sendAnonymousId: false, + }, + ID: 'custify-1234', + }, + message: { + type: 'identify', + context: { + traits: { + firstName: 'New', + lastName: 'User', + phone: 9830311522, + sessionCount: 23, + unsubscribedFromEmails: false, + unsubscribedFromCalls: false, + signed_up_at: '2022-04-27T13:56:13.012Z', + custom_prop1: 'custom_value1', + custom_prop2: 123, + custom_prop3: false, + custom_prop4: { + test: 'test', + }, + custom_prop5: [1, 3, 4], + createdAt: '2022-04-27T13:56:13.012Z', + company: { + id: 'company_123', + remove: true, + }, + }, + }, + timestamp: '2022-04-27T13:56:13.012Z', + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Email or userId is mandatory', + statTags: { + destType: 'CUSTIFY', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'custify', + description: 'Identify Call without userId and email and sendAnonymous is false', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'apiKey_key_test_001', + sendAnonymousId: false, + }, + ID: 'custify-1234', + }, + message: { + type: 'identify', + context: { + traits: { + firstName: 'New', + lastName: 'User', + phone: 9830311522, + sessionCount: 23, + unsubscribedFromEmails: false, + unsubscribedFromCalls: false, + signed_up_at: '2022-04-27T13:56:13.012Z', + custom_prop1: 'custom_value1', + custom_prop2: 123, + custom_prop3: false, + custom_prop4: { + test: 'test', + }, + custom_prop5: [1, 3, 4], + createdAt: '2022-04-27T13:56:13.012Z', + company: { + id: 'company_123', + remove: true, + }, + }, + }, + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + timestamp: '2022-04-27T13:56:13.012Z', + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Email or userId is mandatory', + statTags: { + destType: 'CUSTIFY', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'custify', + description: 'Identify Call without userId and email and sendAnonymous is true', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'apiKey_key_test_001', + sendAnonymousId: true, + }, + ID: 'custify-1234', + }, + message: { + type: 'identify', + context: { + traits: { + firstName: 'New', + lastName: 'User', + phone: 9830311522, + sessionCount: 23, + unsubscribedFromEmails: false, + unsubscribedFromCalls: false, + signed_up_at: '2022-04-27T13:56:13.012Z', + custom_prop1: 'custom_value1', + custom_prop2: 123, + custom_prop3: false, + custom_prop4: { + test: 'test', + }, + custom_prop5: [1, 3, 4], + createdAt: '2022-04-27T13:56:13.012Z', + company: { + id: 'company_123', + remove: true, + }, + }, + }, + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + timestamp: '2022-04-27T13:56:13.012Z', + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.custify.com/people', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer apiKey_key_test_001', + Accept: 'application/json', + }, + params: {}, + body: { + JSON: { + phone: 9830311522, + session_count: 23, + unsubscribed_from_emails: false, + unsubscribed_from_calls: false, + signed_up_at: '2022-04-27T13:56:13.012Z', + custom_attributes: { + firstName: 'New', + lastName: 'User', + sessionCount: 23, + unsubscribedFromEmails: false, + unsubscribedFromCalls: false, + custom_prop1: 'custom_value1', + custom_prop2: 123, + custom_prop3: false, + createdAt: '2022-04-27T13:56:13.012Z', + }, + user_id: 'bf412108-0357-4330-b119-7305e767823c', + name: 'New User', + companies: [ + { + company_id: 'company_123', + remove: true, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: 'bf412108-0357-4330-b119-7305e767823c', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'custify', + description: 'Track call with all properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'apiKey_key_test_001', + sendAnonymousId: false, + }, + ID: 'custify-1234', + }, + message: { + type: 'track', + event: 'Order Completed Version 2', + sentAt: '2021-08-26T14:16:47.321Z', + userId: 'user_111', + context: { + library: { + name: 'analytics-node', + version: '1.0.3', + }, + traits: { + email: 'user111@gmail.com', + }, + page: { + url: 'https://www.website.com/product/path', + }, + }, + rudderId: '70612f39-0607-45bb-8236-bf0995fde4fa', + _metadata: { + nodeVersion: '10.24.1', + }, + messageId: + 'node-84952e4eb9c6debbda735c49d08a8b31-fcbfed6a-38cf-42c5-881c-f590f59311b1', + properties: { + product: 'Cube', + revenue: 9002, + organization_id: 'company_123', + }, + originalTimestamp: '2021-08-26T14:16:47.317Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.custify.com/event', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer apiKey_key_test_001', + Accept: 'application/json', + }, + params: {}, + body: { + JSON: { + user_id: 'user_111', + email: 'user111@gmail.com', + name: 'Order Completed Version 2', + created_at: '2021-08-26T14:16:47.317Z', + company_id: 'company_123', + metadata: { + product: 'Cube', + revenue: 9002, + organization_id: 'company_123', + user_id: 'user_111', + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: 'user_111', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'custify', + description: 'Group call with all fields success scenario', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'apiKey_key_test_001', + sendAnonymousId: false, + }, + ID: 'custify-1234', + }, + message: { + type: 'group', + userId: 'user_111', + groupId: 'company_222', + traits: { + name: 'Absolute Company', + industry: ' Absolute', + employees: 121, + size: 100, + website: 'www.rudder.com', + plan: 'GOLD', + monthly_revenue: 8000, + churned: false, + test_att1: 'test_att_val1', + }, + context: { + traits: { + firstName: 'Absolute', + lastName: 'User', + phone: 9830311522, + session_count: 23, + signed_up_at: '2022-04-27T13:56:13.012Z', + custom_prop1: 'custom_value1', + custom_prop2: 123, + custom_prop3: false, + custom_prop4: { + test: 'test', + }, + custom_prop5: [1, 3, 4], + createdAt: '2022-04-27T13:56:13.012Z', + }, + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-01-21T00:21:34.208Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.custify.com/people', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer apiKey_key_test_001', + Accept: 'application/json', + }, + params: {}, + body: { + JSON: { + user_id: 'user_111', + phone: 9830311522, + signed_up_at: '2020-01-21T00:21:34.208Z', + custom_attributes: { + firstName: 'Absolute', + lastName: 'User', + custom_prop1: 'custom_value1', + custom_prop2: 123, + custom_prop3: false, + createdAt: '2022-04-27T13:56:13.012Z', + }, + name: 'Absolute User', + companies: [ + { + company_id: 'company_222', + remove: false, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: 'user_111', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/delighted/network.ts b/test/integrations/destinations/delighted/network.ts index 15b0a414e6b..d9896a25e81 100644 --- a/test/integrations/destinations/delighted/network.ts +++ b/test/integrations/destinations/delighted/network.ts @@ -1,30 +1,30 @@ export const networkCallsData = [ - { - httpReq: { - url: 'https://api.delighted.com/v1/people.json', - method: 'GET', - headers: { Authorization: `Basic ZHVtbXlBcGlLZXk=` }, - params: { - email: "identified_user@email.com" - } - }, - httpRes: { - data: ["user data"], - status: 200 - }, + { + httpReq: { + url: 'https://api.delighted.com/v1/people.json', + method: 'GET', + headers: { Authorization: `Basic ZHVtbXlBcGlLZXk=` }, + params: { + email: 'identified_user@email.com', + }, }, - { - httpReq: { - url: 'https://api.delighted.com/v1/people.json', - method: 'GET', - headers: { Authorization: `Basic ZHVtbXlBcGlLZXlmb3JmYWlsdXJl` }, - params: { - email: "unidentified_user@email.com" - } - }, - httpRes: { - data: [], - status: 200 - }, - } + httpRes: { + data: ['user data'], + status: 200, + }, + }, + { + httpReq: { + url: 'https://api.delighted.com/v1/people.json', + method: 'GET', + headers: { Authorization: `Basic ZHVtbXlBcGlLZXlmb3JmYWlsdXJl` }, + params: { + email: 'unidentified_user@email.com', + }, + }, + httpRes: { + data: [], + status: 200, + }, + }, ]; diff --git a/test/integrations/destinations/delighted/processor/data.ts b/test/integrations/destinations/delighted/processor/data.ts index 3596d7ef80d..7a5ad7de9d4 100644 --- a/test/integrations/destinations/delighted/processor/data.ts +++ b/test/integrations/destinations/delighted/processor/data.ts @@ -1,937 +1,947 @@ export const data = [ - { - "name": "delighted", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "channel": "email", - "delay": 0, - "eventNamesSettings": [ - { - "event": "" - } - ] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "identify", - "userId": "abc@123.com", - "traits": { - "firstName": "James", - "lastName": "Doe", - "phone": "+91237416221", - "last_sent_at": "1626698350" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.delighted.com/v1/people.json", - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "email": "abc@123.com", - "send": false, - "channel": "email", - "delay": 0, - "name": "James Doe", - "phone_number": "+91237416221", - "last_sent_at": "1626698350" - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "delighted", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "channel": "email", - "delay": 0, - "eventNamesSettings": [ - { - "event": "" - } - ] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "alias", - "previousId": "123@abc.com", - "userId": "abc@123.com", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "email": "123@abc.com", - "email_update": "abc@123.com" - } - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "version": "1", - "endpoint": "https://api.delighted.com/v1/people.json", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "delighted", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "channel": "email", - "delay": 0, - "eventNamesSettings": [ - { - "event": "Product Reviewed" - } - ] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "userId": "identified_user@email.com", - "event": "Product Reviewed", - "properties": { - "review_id": "12345", - "product_id": "123", - "rating": 3, - "review_body": "Average product, expected much more." - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "properties": { - "review_id": "12345", - "product_id": "123", - "rating": 3, - "review_body": "Average product, expected much more." - }, - "send": true, - "channel": "email", - "delay": 0, - "email": "identified_user@email.com" - } - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "version": "1", - "endpoint": "https://api.delighted.com/v1/people.json", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "delighted", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKeyforfailure", - "channel": "email", - "delay": 0, - "eventNamesSettings": [ - { - "event": "Product Reviewed" - } - ] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "userId": "unidentified_user@email.com", - "event": "Product Reviewed", - "properties": { - "review_id": "12345", - "product_id": "123", - "rating": 3, - "review_body": "Average product, expected much more." - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "user unidentified_user@email.com doesn't exist", - "statTags": { - "destType": "DELIGHTED", - "errorCategory": "network", - "errorType": "aborted", - "feature": "processor", - "implementation": "native", - "meta": "instrumentation", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "delighted", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "channel": "email", - "delay": 0, - "eventNamesSettings": [ - { - "event": "" - } - ] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "userId": "identified_user@email.com", - "event": "Product Reviewed", - "properties": { - "review_id": "12345", - "product_id": "123", - "rating": 3, - "review_body": "Average product, expected much more." - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Event is not configured on your Rudderstack Dashboard", - "statTags": { - "destType": "DELIGHTED", - "errorCategory": "dataValidation", - "errorType": "configuration", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "delighted", - "description": "Test 5", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "channel": "email", - "delay": 0, - "eventNamesSettings": [ - { - "event": "Product Reviewed" - } - ] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "anonymousId": "identified_user@email.com", - "event": "Product Reviewed", - "properties": { - "review_id": "12345", - "product_id": "123", - "rating": 3, - "review_body": "Average product, expected much more." - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "userId is required.", - "statTags": { - "destType": "DELIGHTED", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "delighted", - "description": "Test 6", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "channel": "email", - "delay": 0, - "eventNamesSettings": [ - { - "event": "" - } - ] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "alias", - "previousId": "123@abc.com", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "userId is required.", - "statTags": { - "destType": "DELIGHTED", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "delighted", - "description": "Test 7", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "channel": "email", - "delay": 0, - "eventNamesSettings": [ - { - "event": "" - } - ] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "externalId": [ - { - "id": "sms", - "type": "delightedChannelType" - } - ], - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "alias", - "userId": "abc@123.com", - "previousId": "123@abc.com", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "User Id and Previous Id should be of same type i.e. phone/sms", - "statTags": { - "destType": "DELIGHTED", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "delighted", - "description": "Test 8", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "channel": "email", - "delay": 0, - "eventNamesSettings": [ - { - "event": "" - } - ] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "externalId": [ - { - "id": "sms", - "type": "delightedChannelType" - } - ], - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "identify", - "userId": "abc@123.com", - "traits": { - "firstName": "James", - "lastName": "Doe", - "phone": "+91237416221", - "last_sent_at": "1626698350" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Channel is set to sms. Enter correct phone number i.e. E.164", - "statTags": { - "destType": "DELIGHTED", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "delighted", - "description": "Test 9", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "channel": "email", - "delay": 0, - "eventNamesSettings": [ - { - "event": "" - } - ] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "externalId": [ - { - "id": "sms", - "type": "delightedChannelType" - } - ], - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "identify", - "userId": "+911234567890", - "traits": { - "firstName": "James", - "lastName": "Doe", - "last_sent_at": "1626698350" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.delighted.com/v1/people.json", - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "send": false, - "channel": "sms", - "delay": 0, - "name": "James Doe", - "phone_number": "+911234567890", - "last_sent_at": "1626698350" - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - } -] + { + name: 'delighted', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + channel: 'email', + delay: 0, + eventNamesSettings: [ + { + event: '', + }, + ], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'identify', + userId: 'abc@123.com', + traits: { + firstName: 'James', + lastName: 'Doe', + phone: '+91237416221', + last_sent_at: '1626698350', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.delighted.com/v1/people.json', + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + email: 'abc@123.com', + send: false, + channel: 'email', + delay: 0, + name: 'James Doe', + phone_number: '+91237416221', + last_sent_at: '1626698350', + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'delighted', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + channel: 'email', + delay: 0, + eventNamesSettings: [ + { + event: '', + }, + ], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'alias', + previousId: '123@abc.com', + userId: 'abc@123.com', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + email: '123@abc.com', + email_update: 'abc@123.com', + }, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + version: '1', + endpoint: 'https://api.delighted.com/v1/people.json', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'delighted', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + channel: 'email', + delay: 0, + eventNamesSettings: [ + { + event: 'Product Reviewed', + }, + ], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + userId: 'identified_user@email.com', + event: 'Product Reviewed', + properties: { + review_id: '12345', + product_id: '123', + rating: 3, + review_body: 'Average product, expected much more.', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + properties: { + review_id: '12345', + product_id: '123', + rating: 3, + review_body: 'Average product, expected much more.', + }, + send: true, + channel: 'email', + delay: 0, + email: 'identified_user@email.com', + }, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + version: '1', + endpoint: 'https://api.delighted.com/v1/people.json', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'delighted', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKeyforfailure', + channel: 'email', + delay: 0, + eventNamesSettings: [ + { + event: 'Product Reviewed', + }, + ], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + userId: 'unidentified_user@email.com', + event: 'Product Reviewed', + properties: { + review_id: '12345', + product_id: '123', + rating: 3, + review_body: 'Average product, expected much more.', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: "user unidentified_user@email.com doesn't exist", + statTags: { + destType: 'DELIGHTED', + errorCategory: 'network', + errorType: 'aborted', + feature: 'processor', + implementation: 'native', + meta: 'instrumentation', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'delighted', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + channel: 'email', + delay: 0, + eventNamesSettings: [ + { + event: '', + }, + ], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + userId: 'identified_user@email.com', + event: 'Product Reviewed', + properties: { + review_id: '12345', + product_id: '123', + rating: 3, + review_body: 'Average product, expected much more.', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Event is not configured on your Rudderstack Dashboard', + statTags: { + destType: 'DELIGHTED', + errorCategory: 'dataValidation', + errorType: 'configuration', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'delighted', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + channel: 'email', + delay: 0, + eventNamesSettings: [ + { + event: 'Product Reviewed', + }, + ], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + anonymousId: 'identified_user@email.com', + event: 'Product Reviewed', + properties: { + review_id: '12345', + product_id: '123', + rating: 3, + review_body: 'Average product, expected much more.', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'userId is required.', + statTags: { + destType: 'DELIGHTED', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'delighted', + description: 'Test 6', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + channel: 'email', + delay: 0, + eventNamesSettings: [ + { + event: '', + }, + ], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'alias', + previousId: '123@abc.com', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'userId is required.', + statTags: { + destType: 'DELIGHTED', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'delighted', + description: 'Test 7', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + channel: 'email', + delay: 0, + eventNamesSettings: [ + { + event: '', + }, + ], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + externalId: [ + { + id: 'sms', + type: 'delightedChannelType', + }, + ], + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'alias', + userId: 'abc@123.com', + previousId: '123@abc.com', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'User Id and Previous Id should be of same type i.e. phone/sms', + statTags: { + destType: 'DELIGHTED', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'delighted', + description: 'Test 8', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + channel: 'email', + delay: 0, + eventNamesSettings: [ + { + event: '', + }, + ], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + externalId: [ + { + id: 'sms', + type: 'delightedChannelType', + }, + ], + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'identify', + userId: 'abc@123.com', + traits: { + firstName: 'James', + lastName: 'Doe', + phone: '+91237416221', + last_sent_at: '1626698350', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Channel is set to sms. Enter correct phone number i.e. E.164', + statTags: { + destType: 'DELIGHTED', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'delighted', + description: 'Test 9', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + channel: 'email', + delay: 0, + eventNamesSettings: [ + { + event: '', + }, + ], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + externalId: [ + { + id: 'sms', + type: 'delightedChannelType', + }, + ], + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'identify', + userId: '+911234567890', + traits: { + firstName: 'James', + lastName: 'Doe', + last_sent_at: '1626698350', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.delighted.com/v1/people.json', + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + send: false, + channel: 'sms', + delay: 0, + name: 'James Doe', + phone_number: '+911234567890', + last_sent_at: '1626698350', + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/drip/processor/data.ts b/test/integrations/destinations/drip/processor/data.ts index 0159959d13b..1874f932fa1 100644 --- a/test/integrations/destinations/drip/processor/data.ts +++ b/test/integrations/destinations/drip/processor/data.ts @@ -1,1487 +1,1498 @@ export const data = [ - { - "name": "drip", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "accountId": "1809802", - "campaignId": "", - "enableUserCreation": true - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "identify", - "traits": { - "email": "test1@gmail.com", - "firstName": "James", - "lastName": "Doe", - "phone": "237416221", - "customFields": { - "filter1": "filterval1" - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getdrip.com/v2/1809802/subscribers", - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "subscribers": [ - { - "email": "test1@gmail.com", - "first_name": "James", - "last_name": "Doe", - "phone": "237416221", - "ip_address": "0.0.0.0", - "custom_fields": { - "filter1": "filterval1" - } - } - ] - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "drip", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "accountId": "1809802", - "campaignId": "", - "enableUserCreation": true - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "identify", - "traits": { - "email": "12324adfgs", - "firstName": "James", - "lastName": "Doe", - "phone": "237416221", - "customFields": { - "filter1": "filterval1" - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "dripId or email is required for the call", - "statTags": { - "destType": "DRIP", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "drip", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "accountId": "1809802", - "campaignId": "", - "enableUserCreation": true - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "identify", - "traits": { - "email": "test1@gmail.com", - "name": "James Doe", - "phone": "237416221", - "filter1": "filterval1", - "filter2": "filterval2" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getdrip.com/v2/1809802/subscribers", - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "subscribers": [ - { - "email": "test1@gmail.com", - "first_name": "James", - "last_name": "Doe", - "phone": "237416221", - "ip_address": "0.0.0.0", - "custom_fields": { - "filter1": "filterval1", - "filter2": "filterval2" - } - } - ] - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "drip", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "accountId": "1809802", - "campaignId": "915194776", - "enableUserCreation": true - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "identify", - "traits": { - "email": "test1@gmail.com", - "name": "James Doe", - "phone": "237416221", - "filter1": "filterval1", - "filter2": "filterval2", - "tags": [ - "tag1", - "tag2" - ], - "startingEmailIndex": 1 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getdrip.com/v2/1809802/campaigns/915194776/subscribers", - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "subscribers": [ - { - "email": "test1@gmail.com", - "starting_email_index": 1 - } - ] - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "drip", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "accountId": "1809802", - "campaignId": "915194776", - "enableUserCreation": true - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "event": "testing", - "properties": { - "email": "user1@gmail.com", - "customFields": { - "field1": "val1" - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getdrip.com/v2/1809802/events", - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "events": [ - { - "email": "user1@gmail.com", - "properties": { - "field1": "val1" - }, - "action": "testing", - "occurred_at": "2019-10-14T09:03:17.562Z" - } - ] - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "drip", - "description": "Test 5", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "accountId": "1809802", - "campaignId": "915194776", - "enableUserCreation": true - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "event": "", - "properties": { - "email": "user1@gmail.com", - "custom_fields": { - "field1": "val1" - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Event name is required", - "statTags": { - "destType": "DRIP", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "drip", - "description": "Test 6", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "accountId": "1809802", - "campaignId": "915194776", - "enableUserCreation": false - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "event": "testing", - "properties": { - "email": "identified_user@gmail.com", - "customFields": { - "field1": "val1" - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getdrip.com/v2/1809802/events", - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "events": [ - { - "email": "identified_user@gmail.com", - "properties": { - "field1": "val1" - }, - "action": "testing", - "occurred_at": "2019-10-14T09:03:17.562Z" - } - ] - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "drip", - "description": "Test 7", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "accountId": "1809802", - "campaignId": "915194776", - "enableUserCreation": false - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "event": "testing", - "properties": { - "email": "identified_user@gmail.com", - "field1": "val1" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getdrip.com/v2/1809802/events", - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "events": [ - { - "email": "identified_user@gmail.com", - "properties": { - "field1": "val1" - }, - "action": "testing", - "occurred_at": "2019-10-14T09:03:17.562Z" - } - ] - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "drip", - "description": "Test 8", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "accountId": "1809802", - "campaignId": "915194776", - "enableUserCreation": false - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "event": "testing", - "properties": { - "email": "unidentified_user@gmail.com", - "field1": "val1" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Error occurred while checking user : error response not found", - "statTags": { - "destType": "DRIP", - "errorCategory": "network", - "errorType": "aborted", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "drip", - "description": "Test 9", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "accountId": "1809802", - "campaignId": "915194776", - "enableUserCreation": false - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "event": "checkout started", - "properties": { - "email": "identified_user@gmail.com", - "field1": "val1", - "affiliation": "my_custom_order", - "order_id": "456445746" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getdrip.com/v3/1809802/shopper_activity/order", - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "action": "placed", - "email": "identified_user@gmail.com", - "occurred_at": "2019-10-14T09:03:17.562Z", - "order_id": "456445746", - "provider": "my_custom_order" - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "drip", - "description": "Test 10", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "accountId": "1809802", - "campaignId": "915194776", - "enableUserCreation": false - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "event": "checkout started", - "properties": { - "email": "identified_user@gmail.com", - "field1": "val1", - "affiliation": "my_custom_order", - "order_id": "456445746", - "products": [ - { - "name": "shirt", - "price": 11.16 - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getdrip.com/v3/1809802/shopper_activity/order", - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "action": "placed", - "email": "identified_user@gmail.com", - "occurred_at": "2019-10-14T09:03:17.562Z", - "order_id": "456445746", - "provider": "my_custom_order", - "items": [ - { - "name": "shirt", - "price": 11.16 - } - ] - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "drip", - "description": "Test 11", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "accountId": "1809802", - "campaignId": "915194776", - "enableUserCreation": false - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "event": "checkout", - "properties": { - "email": "identified_user@gmail.com", - "field1": "val1", - "customFields": { - "field2": "val2" - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getdrip.com/v2/1809802/events", - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "events": [ - { - "action": "checkout", - "email": "identified_user@gmail.com", - "occurred_at": "2019-10-14T09:03:17.562Z", - "properties": { - "field2": "val2" - } - } - ] - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "drip", - "description": "Test 12", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "accountId": "1809802", - "campaignId": "", - "enableUserCreation": true - } - }, - "message": { - "type": "identify", - "event": "identify", - "userId": "user@1", - "channel": "mobile", - "context": { - "os": { - "name": "Android", - "version": "13" - }, - "app": { - "name": "rudderstack", - "build": "5425", - "version": "2.4.1" - }, - "device": { - "id": "8b048b94cbec4fcf", - "name": "o1q", - "type": "Android", - "model": "SM-G991U", - "manufacturer": "samsung" - }, - "locale": "en-US", - "traits": { - "id": "ruddertest@gmail.com", - "email": "ruddertest@gmail.com", - "title": "Social Impact Program Manager", - "skills": [ - { - "id": 134, - "name": "Business Development", - "tagGroupId": 2, - "parentTagId": 134, - "huddleVisible": false, - "onboardVisible": false - }, - { - "id": 96, - "name": "Communications", - "tagGroupId": 2, - "parentTagId": 96, - "huddleVisible": true, - "onboardVisible": true - }, - { - "id": 489, - "name": "Construction", - "tagGroupId": 2, - "parentTagId": 489, - "huddleVisible": false, - "onboardVisible": false - }, - { - "id": 671, - "name": "Data Analysis", - "tagGroupId": 2, - "parentTagId": 671, - "huddleVisible": false, - "onboardVisible": false - }, - { - "id": 676, - "name": "Engineering: Mechanical", - "tagGroupId": 2, - "parentTagId": 676, - "huddleVisible": false, - "onboardVisible": false - }, - { - "id": 189, - "name": "Operations", - "tagGroupId": 2, - "parentTagId": 189, - "huddleVisible": true, - "onboardVisible": true - }, - { - "id": 194, - "name": "Product Management", - "tagGroupId": 2, - "parentTagId": 194, - "huddleVisible": true, - "onboardVisible": true - }, - { - "id": 195, - "name": "Program Management", - "tagGroupId": 2, - "parentTagId": 195, - "huddleVisible": false, - "onboardVisible": false - }, - { - "id": 199, - "name": "R&D", - "tagGroupId": 2, - "parentTagId": 199, - "huddleVisible": false, - "onboardVisible": false - }, - { - "id": 102, - "name": "Sales", - "tagGroupId": 2, - "parentTagId": 102, - "huddleVisible": true, - "onboardVisible": true - } - ], - "userId": "ruddertest@gmail.com", - "address": "Chicago, IL, USA", - "industry": "Education", - "lastName": "test", - "lastname": "test", - "verified": false, - "firstName": "rudder", - "firstname": "rudder", - "interests": [ - { - "id": 649, - "name": "Adaptation", - "tagGroupId": 4, - "parentTagId": 745, - "huddleVisible": false, - "onboardVisible": false - }, - { - "id": 663, - "name": "Carbon removal and sequestration", - "tagGroupId": 4, - "parentTagId": 761, - "huddleVisible": false, - "onboardVisible": false - }, - { - "id": 664, - "name": "Clean Energy and Energy Efficiency", - "tagGroupId": 4, - "parentTagId": 259, - "huddleVisible": false, - "onboardVisible": false - }, - { - "id": 654, - "name": "Climate Science and Earth Systems", - "tagGroupId": 4, - "parentTagId": 744, - "huddleVisible": false, - "onboardVisible": false - }, - { - "id": 650, - "name": "Corporate Sustainability", - "tagGroupId": 4, - "parentTagId": 650, - "huddleVisible": false, - "onboardVisible": false - }, - { - "id": 651, - "name": "Finance & Risk", - "tagGroupId": 4, - "parentTagId": 651, - "huddleVisible": false, - "onboardVisible": false - }, - { - "id": 652, - "name": "Food and Agriculture", - "tagGroupId": 4, - "parentTagId": 652, - "huddleVisible": false, - "onboardVisible": false - }, - { - "id": 665, - "name": "Transport", - "tagGroupId": 4, - "parentTagId": 665, - "huddleVisible": false, - "onboardVisible": false - } - ], - "isDeleted": false, - "anonymousId": "8b048b94cbec4fcf", - "jobFunction": "Program manager", - "reminderType": 1, - "jobPreferences": { - "motivationStr": "I am looking for a job in climate change.,I want to learn about climate change.,I’d like to connect with other climate enthusiasts.", - "searchUrgency": "As soon as possible", - "maxCompensation": 0, - "minCompensation": 0 - }, - "visibilityType": "public", - "Linkedin-Signin": true, - "hubbleOnboarded": false, - "sharePreference": false, - "notificationType": 0, - "shortDescription": "Social Impact Program Manager", - "jobProfileComplete": false, - "noOfMonthExperience": 0, - "onboarding_completed": "Yes" - }, - "library": { - "name": "com.rudderstack.android.sdk.core", - "version": "1.8.1" - }, - "timezone": "America/Chicago", - "sessionId": 1681096824, - "userAgent": "Dalvik/2.1.0 (Linux; U; Android 13; SM-G991U Build/TP1A.220624.014)" - }, - "rudderId": "f701966c-5568-4500-92ba-4e9023c8fe31", - "messageId": "77b53247-177f-4ca3-a6b4-aa7558fec280", - "request_ip": "75.209.176.135", - "anonymousId": "8b048b94cbec4fcf", - "integrations": { - "All": true - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getdrip.com/v2/1809802/subscribers", - "headers": { - "Authorization": "Basic ZHVtbXlBcGlLZXk=", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "subscribers": [ - { - "email": "ruddertest@gmail.com", - "user_id": "user@1", - "address1": "Chicago, IL, USA", - "last_name": "test", - "first_name": "rudder", - "custom_fields": { - "title": "Social Impact Program Manager", - "industry": "Education", - "verified": false, - "isDeleted": false, - "jobFunction": "Program manager", - "reminderType": 1, - "jobPreferences": { - "motivationStr": "I am looking for a job in climate change.,I want to learn about climate change.,I’d like to connect with other climate enthusiasts.", - "searchUrgency": "As soon as possible", - "maxCompensation": 0, - "minCompensation": 0 - }, - "visibilityType": "public", - "hubbleOnboarded": false, - "sharePreference": false, - "notificationType": 0, - "shortDescription": "Social Impact Program Manager", - "jobProfileComplete": false, - "noOfMonthExperience": 0, - "onboarding_completed": "Yes" - } - } - ] - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - } -] + { + name: 'drip', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + accountId: '1809802', + campaignId: '', + enableUserCreation: true, + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'identify', + traits: { + email: 'test1@gmail.com', + firstName: 'James', + lastName: 'Doe', + phone: '237416221', + customFields: { + filter1: 'filterval1', + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getdrip.com/v2/1809802/subscribers', + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + subscribers: [ + { + email: 'test1@gmail.com', + first_name: 'James', + last_name: 'Doe', + phone: '237416221', + ip_address: '0.0.0.0', + custom_fields: { + filter1: 'filterval1', + }, + }, + ], + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'drip', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + accountId: '1809802', + campaignId: '', + enableUserCreation: true, + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'identify', + traits: { + email: '12324adfgs', + firstName: 'James', + lastName: 'Doe', + phone: '237416221', + customFields: { + filter1: 'filterval1', + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'dripId or email is required for the call', + statTags: { + destType: 'DRIP', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'drip', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + accountId: '1809802', + campaignId: '', + enableUserCreation: true, + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'identify', + traits: { + email: 'test1@gmail.com', + name: 'James Doe', + phone: '237416221', + filter1: 'filterval1', + filter2: 'filterval2', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getdrip.com/v2/1809802/subscribers', + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + subscribers: [ + { + email: 'test1@gmail.com', + first_name: 'James', + last_name: 'Doe', + phone: '237416221', + ip_address: '0.0.0.0', + custom_fields: { + filter1: 'filterval1', + filter2: 'filterval2', + }, + }, + ], + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'drip', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + accountId: '1809802', + campaignId: '915194776', + enableUserCreation: true, + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'identify', + traits: { + email: 'test1@gmail.com', + name: 'James Doe', + phone: '237416221', + filter1: 'filterval1', + filter2: 'filterval2', + tags: ['tag1', 'tag2'], + startingEmailIndex: 1, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getdrip.com/v2/1809802/campaigns/915194776/subscribers', + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + subscribers: [ + { + email: 'test1@gmail.com', + starting_email_index: 1, + }, + ], + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'drip', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + accountId: '1809802', + campaignId: '915194776', + enableUserCreation: true, + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + event: 'testing', + properties: { + email: 'user1@gmail.com', + customFields: { + field1: 'val1', + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getdrip.com/v2/1809802/events', + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + events: [ + { + email: 'user1@gmail.com', + properties: { + field1: 'val1', + }, + action: 'testing', + occurred_at: '2019-10-14T09:03:17.562Z', + }, + ], + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'drip', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + accountId: '1809802', + campaignId: '915194776', + enableUserCreation: true, + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + event: '', + properties: { + email: 'user1@gmail.com', + custom_fields: { + field1: 'val1', + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Event name is required', + statTags: { + destType: 'DRIP', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'drip', + description: 'Test 6', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + accountId: '1809802', + campaignId: '915194776', + enableUserCreation: false, + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + event: 'testing', + properties: { + email: 'identified_user@gmail.com', + customFields: { + field1: 'val1', + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getdrip.com/v2/1809802/events', + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + events: [ + { + email: 'identified_user@gmail.com', + properties: { + field1: 'val1', + }, + action: 'testing', + occurred_at: '2019-10-14T09:03:17.562Z', + }, + ], + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'drip', + description: 'Test 7', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + accountId: '1809802', + campaignId: '915194776', + enableUserCreation: false, + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + event: 'testing', + properties: { + email: 'identified_user@gmail.com', + field1: 'val1', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getdrip.com/v2/1809802/events', + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + events: [ + { + email: 'identified_user@gmail.com', + properties: { + field1: 'val1', + }, + action: 'testing', + occurred_at: '2019-10-14T09:03:17.562Z', + }, + ], + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'drip', + description: 'Test 8', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + accountId: '1809802', + campaignId: '915194776', + enableUserCreation: false, + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + event: 'testing', + properties: { + email: 'unidentified_user@gmail.com', + field1: 'val1', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Error occurred while checking user : error response not found', + statTags: { + destType: 'DRIP', + errorCategory: 'network', + errorType: 'aborted', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'drip', + description: 'Test 9', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + accountId: '1809802', + campaignId: '915194776', + enableUserCreation: false, + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + event: 'checkout started', + properties: { + email: 'identified_user@gmail.com', + field1: 'val1', + affiliation: 'my_custom_order', + order_id: '456445746', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getdrip.com/v3/1809802/shopper_activity/order', + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + action: 'placed', + email: 'identified_user@gmail.com', + occurred_at: '2019-10-14T09:03:17.562Z', + order_id: '456445746', + provider: 'my_custom_order', + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'drip', + description: 'Test 10', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + accountId: '1809802', + campaignId: '915194776', + enableUserCreation: false, + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + event: 'checkout started', + properties: { + email: 'identified_user@gmail.com', + field1: 'val1', + affiliation: 'my_custom_order', + order_id: '456445746', + products: [ + { + name: 'shirt', + price: 11.16, + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getdrip.com/v3/1809802/shopper_activity/order', + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + action: 'placed', + email: 'identified_user@gmail.com', + occurred_at: '2019-10-14T09:03:17.562Z', + order_id: '456445746', + provider: 'my_custom_order', + items: [ + { + name: 'shirt', + price: 11.16, + }, + ], + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'drip', + description: 'Test 11', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + accountId: '1809802', + campaignId: '915194776', + enableUserCreation: false, + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + event: 'checkout', + properties: { + email: 'identified_user@gmail.com', + field1: 'val1', + customFields: { + field2: 'val2', + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getdrip.com/v2/1809802/events', + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + events: [ + { + action: 'checkout', + email: 'identified_user@gmail.com', + occurred_at: '2019-10-14T09:03:17.562Z', + properties: { + field2: 'val2', + }, + }, + ], + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'drip', + description: 'Test 12', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + accountId: '1809802', + campaignId: '', + enableUserCreation: true, + }, + }, + message: { + type: 'identify', + event: 'identify', + userId: 'user@1', + channel: 'mobile', + context: { + os: { + name: 'Android', + version: '13', + }, + app: { + name: 'rudderstack', + build: '5425', + version: '2.4.1', + }, + device: { + id: '8b048b94cbec4fcf', + name: 'o1q', + type: 'Android', + model: 'SM-G991U', + manufacturer: 'samsung', + }, + locale: 'en-US', + traits: { + id: 'ruddertest@gmail.com', + email: 'ruddertest@gmail.com', + title: 'Social Impact Program Manager', + skills: [ + { + id: 134, + name: 'Business Development', + tagGroupId: 2, + parentTagId: 134, + huddleVisible: false, + onboardVisible: false, + }, + { + id: 96, + name: 'Communications', + tagGroupId: 2, + parentTagId: 96, + huddleVisible: true, + onboardVisible: true, + }, + { + id: 489, + name: 'Construction', + tagGroupId: 2, + parentTagId: 489, + huddleVisible: false, + onboardVisible: false, + }, + { + id: 671, + name: 'Data Analysis', + tagGroupId: 2, + parentTagId: 671, + huddleVisible: false, + onboardVisible: false, + }, + { + id: 676, + name: 'Engineering: Mechanical', + tagGroupId: 2, + parentTagId: 676, + huddleVisible: false, + onboardVisible: false, + }, + { + id: 189, + name: 'Operations', + tagGroupId: 2, + parentTagId: 189, + huddleVisible: true, + onboardVisible: true, + }, + { + id: 194, + name: 'Product Management', + tagGroupId: 2, + parentTagId: 194, + huddleVisible: true, + onboardVisible: true, + }, + { + id: 195, + name: 'Program Management', + tagGroupId: 2, + parentTagId: 195, + huddleVisible: false, + onboardVisible: false, + }, + { + id: 199, + name: 'R&D', + tagGroupId: 2, + parentTagId: 199, + huddleVisible: false, + onboardVisible: false, + }, + { + id: 102, + name: 'Sales', + tagGroupId: 2, + parentTagId: 102, + huddleVisible: true, + onboardVisible: true, + }, + ], + userId: 'ruddertest@gmail.com', + address: 'Chicago, IL, USA', + industry: 'Education', + lastName: 'test', + lastname: 'test', + verified: false, + firstName: 'rudder', + firstname: 'rudder', + interests: [ + { + id: 649, + name: 'Adaptation', + tagGroupId: 4, + parentTagId: 745, + huddleVisible: false, + onboardVisible: false, + }, + { + id: 663, + name: 'Carbon removal and sequestration', + tagGroupId: 4, + parentTagId: 761, + huddleVisible: false, + onboardVisible: false, + }, + { + id: 664, + name: 'Clean Energy and Energy Efficiency', + tagGroupId: 4, + parentTagId: 259, + huddleVisible: false, + onboardVisible: false, + }, + { + id: 654, + name: 'Climate Science and Earth Systems', + tagGroupId: 4, + parentTagId: 744, + huddleVisible: false, + onboardVisible: false, + }, + { + id: 650, + name: 'Corporate Sustainability', + tagGroupId: 4, + parentTagId: 650, + huddleVisible: false, + onboardVisible: false, + }, + { + id: 651, + name: 'Finance & Risk', + tagGroupId: 4, + parentTagId: 651, + huddleVisible: false, + onboardVisible: false, + }, + { + id: 652, + name: 'Food and Agriculture', + tagGroupId: 4, + parentTagId: 652, + huddleVisible: false, + onboardVisible: false, + }, + { + id: 665, + name: 'Transport', + tagGroupId: 4, + parentTagId: 665, + huddleVisible: false, + onboardVisible: false, + }, + ], + isDeleted: false, + anonymousId: '8b048b94cbec4fcf', + jobFunction: 'Program manager', + reminderType: 1, + jobPreferences: { + motivationStr: + 'I am looking for a job in climate change.,I want to learn about climate change.,I’d like to connect with other climate enthusiasts.', + searchUrgency: 'As soon as possible', + maxCompensation: 0, + minCompensation: 0, + }, + visibilityType: 'public', + 'Linkedin-Signin': true, + hubbleOnboarded: false, + sharePreference: false, + notificationType: 0, + shortDescription: 'Social Impact Program Manager', + jobProfileComplete: false, + noOfMonthExperience: 0, + onboarding_completed: 'Yes', + }, + library: { + name: 'com.rudderstack.android.sdk.core', + version: '1.8.1', + }, + timezone: 'America/Chicago', + sessionId: 1681096824, + userAgent: 'Dalvik/2.1.0 (Linux; U; Android 13; SM-G991U Build/TP1A.220624.014)', + }, + rudderId: 'f701966c-5568-4500-92ba-4e9023c8fe31', + messageId: '77b53247-177f-4ca3-a6b4-aa7558fec280', + request_ip: '75.209.176.135', + anonymousId: '8b048b94cbec4fcf', + integrations: { + All: true, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getdrip.com/v2/1809802/subscribers', + headers: { + Authorization: 'Basic ZHVtbXlBcGlLZXk=', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + subscribers: [ + { + email: 'ruddertest@gmail.com', + user_id: 'user@1', + address1: 'Chicago, IL, USA', + last_name: 'test', + first_name: 'rudder', + custom_fields: { + title: 'Social Impact Program Manager', + industry: 'Education', + verified: false, + isDeleted: false, + jobFunction: 'Program manager', + reminderType: 1, + jobPreferences: { + motivationStr: + 'I am looking for a job in climate change.,I want to learn about climate change.,I’d like to connect with other climate enthusiasts.', + searchUrgency: 'As soon as possible', + maxCompensation: 0, + minCompensation: 0, + }, + visibilityType: 'public', + hubbleOnboarded: false, + sharePreference: false, + notificationType: 0, + shortDescription: 'Social Impact Program Manager', + jobProfileComplete: false, + noOfMonthExperience: 0, + onboarding_completed: 'Yes', + }, + }, + ], + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/facebook_conversions/processor/data.ts b/test/integrations/destinations/facebook_conversions/processor/data.ts index beb7eb32aa0..6eb90942a77 100644 --- a/test/integrations/destinations/facebook_conversions/processor/data.ts +++ b/test/integrations/destinations/facebook_conversions/processor/data.ts @@ -1434,4 +1434,104 @@ export const data = [ }, mockFns: defaultMockFns, }, + { + name: 'facebook_conversions', + description: 'Track event with standard event order completed with content_type in properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + channel: 'web', + context: { + traits: { + email: ' aBc@gmail.com ', + address: { + zip: 1234, + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'order completed', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + content_type: 'product_group', + revenue: 400, + additional_bet_index: 0, + products: [ + { + product_id: 1234, + quantity: 5, + price: 55, + }, + ], + }, + timestamp: '2023-11-12T15:46:51.693229+05:30', + type: 'track', + }, + destination: { + Config: { + limitedDataUsage: true, + blacklistPiiProperties: [ + { + blacklistPiiProperties: '', + blacklistPiiHash: false, + }, + ], + accessToken: '09876', + datasetId: 'dummyID', + eventsToEvents: [ + { + from: '', + to: '', + }, + ], + removeExternalId: true, + actionSource: 'website', + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://graph.facebook.com/v18.0/dummyID/events?access_token=09876', + headers: {}, + params: {}, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: { + data: [ + '{"user_data":{"em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08","zp":"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4"},"event_name":"Purchase","event_time":1699784211,"action_source":"website","custom_data":{"content_type":"product_group","revenue":400,"additional_bet_index":0,"products":[{"product_id":1234,"quantity":5,"price":55}],"content_ids":[1234],"contents":[{"id":1234,"quantity":5,"item_price":55}],"currency":"USD","value":400,"num_items":1}}', + ], + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + mockFns: defaultMockFns, + }, ]; diff --git a/test/integrations/destinations/facebook_pixel/dataDelivery/business.ts b/test/integrations/destinations/facebook_pixel/dataDelivery/business.ts new file mode 100644 index 00000000000..9ac709978d6 --- /dev/null +++ b/test/integrations/destinations/facebook_pixel/dataDelivery/business.ts @@ -0,0 +1,258 @@ +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; +import { ProxyV1TestData } from '../../../testTypes'; +import { VERSION } from '../../../../../src/v0/destinations/facebook_pixel/config'; + +export const testFormData = { + data: [ + '{"user_data":{"external_id":"c58f05b5e3cc4796f3181cf07349d306547c00b20841a175b179c6860e6a34ab","client_ip_address":"32.122.223.26","client_user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1"},"event_name":"Checkout Step Viewed","event_time":1654772112,"event_source_url":"https://www.my.kaiser.com/checkout","event_id":"4f002656-a7b2-4c17-b9bd-8caa5a29190a","custom_data":{"checkout_id":"26SF29B","site":"www.my.kaiser.com","step":1}}', + ], +}; +export const statTags = { + destType: 'FACEBOOK_PIXEL', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', +}; +export const testScenariosForV1API: ProxyV1TestData[] = [ + { + id: 'facebook_pixel_v1_scenario_1', + name: 'facebook_pixel', + description: 'app event fails due to access token error', + successCriteria: 'Should return 400 with invalid access token error', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_access_token`, + FORM: testFormData, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'Invalid OAuth 2.0 access token', + statTags: { + ...statTags, + errorCategory: 'dataValidation', + errorType: 'configuration', + meta: 'accessTokenExpired', + }, + response: [ + { + error: 'Invalid OAuth 2.0 access token', + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'facebook_pixel_v1_scenario_2', + name: 'facebook_pixel', + description: 'app event sent successfully', + successCriteria: 'Should return 200', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=my_access_token`, + params: { + destination: 'facebook_pixel', + }, + FORM: testFormData, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + response: [ + { + error: '{"events_received":1,"fbtrace_id":"facebook_trace_id"}', + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'facebook_pixel_v1_scenario_3', + name: 'facebook_pixel', + description: 'app event fails due to invalid timestamp', + successCriteria: 'Should return 400 with invalid timestamp error', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_timestamp_correct_access_token`, + FORM: testFormData, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'Event Timestamp Too Old', + statTags, + response: [ + { + error: 'Event Timestamp Too Old', + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'facebook_pixel_v1_scenario_4', + name: 'facebook_pixel', + description: 'app event fails due to missing permissions', + successCriteria: 'Should return 400 with missing permissions error', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_account_id_valid_access_token`, + FORM: testFormData, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: + "Object with ID 'PIXEL_ID' / 'DATASET_ID' / 'AUDIENCE_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", + statTags, + response: [ + { + error: + "Object with ID 'PIXEL_ID' / 'DATASET_ID' / 'AUDIENCE_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'facebook_pixel_v1_scenario_5', + name: 'facebook_pixel', + description: 'app event fails due to invalid parameter', + successCriteria: 'Should return 400 with Invalid parameter error', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=not_found_access_token`, + FORM: testFormData, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'Invalid Parameter', + statTags, + response: [ + { + error: 'Invalid Parameter', + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'facebook_pixel_v1_scenario_6', + name: 'facebook_pixel', + description: 'app event fails due to invalid parameter', + successCriteria: 'Should return 400 with Invalid parameter error', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234570/events?access_token=valid_access_token`, + FORM: testFormData, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'Invalid Parameter', + statTags, + response: [ + { + error: 'Invalid Parameter', + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/facebook_pixel/dataDelivery/data.ts b/test/integrations/destinations/facebook_pixel/dataDelivery/data.ts index eb9ce344e0a..dcc633e1a85 100644 --- a/test/integrations/destinations/facebook_pixel/dataDelivery/data.ts +++ b/test/integrations/destinations/facebook_pixel/dataDelivery/data.ts @@ -1,6 +1,15 @@ import { VERSION } from '../../../../../src/v0/destinations/facebook_pixel/config'; +import { testScenariosForV1API, testFormData, statTags as baseStatTags } from './business'; +import { otherScenariosV1 } from './other'; +import { oauthScenariosV1 } from './oauth'; -export const data = [ +const statTags = { + ...baseStatTags, + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', +}; + +export const v0TestData = [ { name: 'facebook_pixel', description: 'Test 0', @@ -12,11 +21,7 @@ export const data = [ body: { body: { XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"c58f05b5e3cc4796f3181cf07349d306547c00b20841a175b179c6860e6a34ab","client_ip_address":"32.122.223.26","client_user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1"},"event_name":"Checkout Step Viewed","event_time":1654773112,"event_source_url":"https://www.my.kaiser.com/checkout","event_id":"4f002656-a7b2-4c17-b9bd-8caa5a29190a","custom_data":{"checkout_id":"26SF29B","site":"www.my.kaiser.com","step":1}}', - ], - }, + FORM: testFormData, JSON: {}, JSON_ARRAY: {}, }, @@ -43,22 +48,18 @@ export const data = [ message: 'Invalid OAuth 2.0 access token', destinationResponse: { error: { - message: 'The access token could not be decrypted', - type: 'OAuthException', code: 190, fbtrace_id: 'fbpixel_trace_id', + message: 'The access token could not be decrypted', + type: 'OAuthException', }, status: 500, }, statTags: { - destType: 'FACEBOOK_PIXEL', - errorCategory: 'network', - destinationId: 'Non-determininable', - workspaceId: 'Non-determininable', - errorType: 'aborted', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', + ...statTags, + errorCategory: 'dataValidation', + errorType: 'configuration', + meta: 'accessTokenExpired', }, }, }, @@ -76,11 +77,7 @@ export const data = [ body: { body: { XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"c58f05b5e3cc4796f3181cf07349d306547c00b20841a175b179c6860e6a34ab","client_ip_address":"32.122.223.26","client_user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1"},"event_name":"Checkout Step Viewed","event_time":1654773112,"event_source_url":"https://www.my.kaiser.com/checkout","event_id":"4f002656-a7b2-4c17-b9bd-8caa5a29190a","custom_data":{"checkout_id":"26SF29B","site":"www.my.kaiser.com","step":1}}', - ], - }, + FORM: testFormData, JSON: {}, JSON_ARRAY: {}, }, @@ -125,11 +122,7 @@ export const data = [ body: { body: { XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"c58f05b5e3cc4796f3181cf07349d306547c00b20841a175b179c6860e6a34ab","client_ip_address":"32.122.223.26","client_user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1"},"event_name":"Checkout Step Viewed","event_time":1654772112,"event_source_url":"https://www.my.kaiser.com/checkout","event_id":"4f002656-a7b2-4c17-b9bd-8caa5a29190a","custom_data":{"checkout_id":"26SF29B","site":"www.my.kaiser.com","step":1}}', - ], - }, + FORM: testFormData, JSON: {}, JSON_ARRAY: {}, }, @@ -168,16 +161,7 @@ export const data = [ }, status: 400, }, - statTags: { - destType: 'FACEBOOK_PIXEL', - errorCategory: 'network', - destinationId: 'Non-determininable', - workspaceId: 'Non-determininable', - errorType: 'aborted', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', - }, + statTags, }, }, }, @@ -194,11 +178,7 @@ export const data = [ body: { body: { XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"c58f05b5e3cc4796f3181cf07349d306547c00b20841a175b179c6860e6a34ab","client_ip_address":"32.122.223.26","client_user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1"},"event_name":"Checkout Step Viewed","event_time":1654772112,"event_source_url":"https://www.my.kaiser.com/checkout","event_id":"4f002656-a7b2-4c17-b9bd-8caa5a29190a","custom_data":{"checkout_id":"26SF29B","site":"www.my.kaiser.com","step":1}}', - ], - }, + FORM: testFormData, JSON: {}, JSON_ARRAY: {}, }, @@ -233,14 +213,8 @@ export const data = [ status: 500, }, statTags: { - destType: 'FACEBOOK_PIXEL', - errorCategory: 'network', - destinationId: 'Non-determininable', - workspaceId: 'Non-determininable', + ...statTags, errorType: 'throttled', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', }, }, }, @@ -258,11 +232,7 @@ export const data = [ body: { body: { XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"c58f05b5e3cc4796f3181cf07349d306547c00b20841a175b179c6860e6a34ab","client_ip_address":"32.122.223.26","client_user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1"},"event_name":"Checkout Step Viewed","event_time":1654772112,"event_source_url":"https://www.my.kaiser.com/checkout","event_id":"4f002656-a7b2-4c17-b9bd-8caa5a29190a","custom_data":{"checkout_id":"26SF29B","site":"www.my.kaiser.com","step":1}}', - ], - }, + FORM: testFormData, JSON: {}, JSON_ARRAY: {}, }, @@ -299,16 +269,7 @@ export const data = [ }, status: 400, }, - statTags: { - destType: 'FACEBOOK_PIXEL', - errorCategory: 'network', - destinationId: 'Non-determininable', - workspaceId: 'Non-determininable', - errorType: 'aborted', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', - }, + statTags, }, }, }, @@ -325,11 +286,7 @@ export const data = [ body: { body: { XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"d58f05b5e3cc4796f3181cf07349d306547c00b20841a175b179c6860e6a34ab","client_ip_address":"32.122.223.26","client_user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1"},"event_name":"Checkout Step Viewed","event_time":1654772112,"event_source_url":"https://www.my.kaiser.com/checkout","event_id":"4f002656-a7b2-4c17-b9bd-8caa5a29190a","custom_data":{"checkout_id":"26SF29B","site":"www.my.kaiser.com","step":1}}', - ], - }, + FORM: testFormData, JSON: {}, JSON_ARRAY: {}, }, @@ -364,16 +321,7 @@ export const data = [ }, status: 404, }, - statTags: { - destType: 'FACEBOOK_PIXEL', - errorCategory: 'network', - destinationId: 'Non-determininable', - workspaceId: 'Non-determininable', - errorType: 'aborted', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', - }, + statTags, }, }, }, @@ -390,11 +338,7 @@ export const data = [ body: { body: { XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"c58f05b5e3cc4796f3181cf07349d306547c00b20841a175b179c6860e6a34ab","client_ip_address":"32.122.223.26","client_user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1"},"event_name":"Checkout Step Viewed","event_time":1654772112,"event_source_url":"https://www.my.kaiser.com/checkout","event_id":"4f002656-a7b2-4c17-b9bd-8caa5a29190a","custom_data":{"checkout_id":"26SF29B","site":"www.my.kaiser.com","step":1}}', - ], - }, + FORM: testFormData, JSON: {}, JSON_ARRAY: {}, }, @@ -429,16 +373,7 @@ export const data = [ }, status: 400, }, - statTags: { - destType: 'FACEBOOK_PIXEL', - errorCategory: 'network', - destinationId: 'Non-determininable', - workspaceId: 'Non-determininable', - errorType: 'aborted', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', - }, + statTags, }, }, }, @@ -455,11 +390,7 @@ export const data = [ body: { body: { XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"c58f05b5e3cc4796f3181cf07349d306547c00b20841a175b179c6860e6a34ab","client_ip_address":"32.122.223.26","client_user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1"},"event_name":"Checkout Step Viewed","event_time":1654772112,"event_source_url":"https://www.my.kaiser.com/checkout","event_id":"4f002656-a7b2-4c17-b9bd-8caa5a29190a","custom_data":{"checkout_id":"26SF29B","site":"www.my.kaiser.com","step":1}}', - ], - }, + FORM: testFormData, JSON: {}, JSON_ARRAY: {}, }, @@ -494,16 +425,7 @@ export const data = [ }, status: 500, }, - statTags: { - destType: 'FACEBOOK_PIXEL', - errorCategory: 'network', - destinationId: 'Non-determininable', - workspaceId: 'Non-determininable', - errorType: 'aborted', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', - }, + statTags, }, }, }, @@ -520,11 +442,7 @@ export const data = [ body: { body: { XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"c58f05b5e3cc4796f3181cf07349d306547c00b20841a175b179c6860e6a34ab","client_ip_address":"32.122.223.26","client_user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Mobile/15E148 Safari/604.1"},"event_name":"Checkout Step Viewed","event_time":1654772112,"event_source_url":"https://www.my.kaiser.com/checkout","event_id":"4f002656-a7b2-4c17-b9bd-8caa5a29190a","custom_data":{"checkout_id":"26SF29B","site":"www.my.kaiser.com","step":1}}', - ], - }, + FORM: testFormData, JSON: {}, JSON_ARRAY: {}, }, @@ -560,14 +478,8 @@ export const data = [ status: 412, }, statTags: { - destType: 'FACEBOOK_PIXEL', - errorCategory: 'network', - destinationId: 'Non-determininable', - workspaceId: 'Non-determininable', + ...statTags, errorType: 'retryable', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', meta: 'unhandledStatusCode', }, }, @@ -576,3 +488,10 @@ export const data = [ }, }, ]; + +export const data = [ + ...v0TestData, + ...testScenariosForV1API, + ...otherScenariosV1, + ...oauthScenariosV1, +]; diff --git a/test/integrations/destinations/facebook_pixel/dataDelivery/oauth.ts b/test/integrations/destinations/facebook_pixel/dataDelivery/oauth.ts new file mode 100644 index 00000000000..c6d938c627b --- /dev/null +++ b/test/integrations/destinations/facebook_pixel/dataDelivery/oauth.ts @@ -0,0 +1,45 @@ +import { testFormData, statTags } from './business'; +import { generateProxyV1Payload, generateMetadata } from '../../../testUtils'; +import { ProxyV1TestData } from '../../../testTypes'; +import { VERSION } from '../../../../../src/v0/destinations/facebook_pixel/config'; + +export const oauthScenariosV1: ProxyV1TestData[] = [ + { + id: 'facebook_pixel_v1_oauth_scenario_1', + name: 'facebook_pixel', + description: 'app event fails due to missing permissions', + successCriteria: 'Should return 400 with missing permissions error', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234571/events?access_token=valid_access_token`, + FORM: testFormData, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'Capability or permissions issue.', + statTags, + response: [ + { + error: 'Capability or permissions issue.', + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/facebook_pixel/dataDelivery/other.ts b/test/integrations/destinations/facebook_pixel/dataDelivery/other.ts new file mode 100644 index 00000000000..e25cc8e07c4 --- /dev/null +++ b/test/integrations/destinations/facebook_pixel/dataDelivery/other.ts @@ -0,0 +1,93 @@ +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; +import { ProxyV1TestData } from '../../../testTypes'; +import { VERSION } from '../../../../../src/v0/destinations/facebook_pixel/config'; +import { testFormData, statTags } from './business'; + +export const otherScenariosV1: ProxyV1TestData[] = [ + { + id: 'facebook_pixel_v1_other_scenario_1', + name: 'facebook_pixel', + description: 'user update request is throttled due to too many calls', + successCriteria: 'Should return 429 with message there have been too many calls', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=throttled_valid_access_token`, + params: { + destination: 'facebook_pixel', + }, + FORM: testFormData, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 429, + message: 'API User Too Many Calls', + statTags: { + ...statTags, + errorType: 'throttled', + }, + response: [ + { + error: 'API User Too Many Calls', + statusCode: 429, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'facebook_pixel_v1_other_scenario_2', + name: 'facebook_pixel', + description: 'app event fails due to Unhandled random error', + successCriteria: 'Should return 500 with Unhandled random error', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234572/events?access_token=valid_access_token_unhandled_response`, + FORM: testFormData, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 500, + message: 'Unhandled random error', + statTags: { + ...statTags, + errorType: 'retryable', + meta: 'unhandledStatusCode', + }, + response: [ + { + error: 'Unhandled random error', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/facebook_pixel/network.ts b/test/integrations/destinations/facebook_pixel/network.ts index 05b3a05fd0b..a61fa44eab8 100644 --- a/test/integrations/destinations/facebook_pixel/network.ts +++ b/test/integrations/destinations/facebook_pixel/network.ts @@ -1,4 +1,4 @@ -import { data } from './dataDelivery/data'; +import { testFormData } from './dataDelivery/business'; import { getFormData } from '../../../../src/adapters/network'; import { VERSION } from '../../../../src/v0/destinations/facebook_pixel/config'; @@ -6,7 +6,7 @@ export const networkCallsData = [ { httpReq: { url: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_access_token`, - data: getFormData(data[0].input.request.body.body.FORM).toString(), + data: getFormData(testFormData).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, method: 'POST', @@ -26,7 +26,7 @@ export const networkCallsData = [ { httpReq: { url: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_timestamp_correct_access_token`, - data: getFormData(data[2].input.request.body.body.FORM).toString(), + data: getFormData(testFormData).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, method: 'POST', @@ -51,7 +51,7 @@ export const networkCallsData = [ { httpReq: { url: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=throttled_valid_access_token`, - data: getFormData(data[3].input.request.body.body.FORM).toString(), + data: getFormData(testFormData).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, method: 'POST', @@ -71,7 +71,7 @@ export const networkCallsData = [ { httpReq: { url: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_account_id_valid_access_token`, - data: getFormData(data[4].input.request.body.body.FORM).toString(), + data: getFormData(testFormData).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, method: 'POST', @@ -93,7 +93,7 @@ export const networkCallsData = [ { httpReq: { url: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=not_found_access_token`, - data: getFormData(data[5].input.request.body.body.FORM).toString(), + data: getFormData(testFormData).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, method: 'POST', @@ -114,7 +114,7 @@ export const networkCallsData = [ { httpReq: { url: `https://graph.facebook.com/${VERSION}/1234567891234570/events?access_token=valid_access_token`, - data: getFormData(data[6].input.request.body.body.FORM).toString(), + data: getFormData(testFormData).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, method: 'POST', @@ -135,7 +135,7 @@ export const networkCallsData = [ { httpReq: { url: `https://graph.facebook.com/${VERSION}/1234567891234571/events?access_token=valid_access_token`, - data: getFormData(data[7].input.request.body.body.FORM).toString(), + data: getFormData(testFormData).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, method: 'POST', @@ -156,7 +156,7 @@ export const networkCallsData = [ { httpReq: { url: `https://graph.facebook.com/${VERSION}/1234567891234572/events?access_token=valid_access_token_unhandled_response`, - data: getFormData(data[8].input.request.body.body.FORM).toString(), + data: getFormData(testFormData).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, method: 'POST', @@ -177,7 +177,7 @@ export const networkCallsData = [ { httpReq: { url: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=my_access_token`, - data: getFormData(data[1].input.request.body.body.FORM).toString(), + data: getFormData(testFormData).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, method: 'POST', diff --git a/test/integrations/destinations/facebook_pixel/processor/configLevelFeaturesTestData.ts b/test/integrations/destinations/facebook_pixel/processor/configLevelFeaturesTestData.ts new file mode 100644 index 00000000000..5a7beb41740 --- /dev/null +++ b/test/integrations/destinations/facebook_pixel/processor/configLevelFeaturesTestData.ts @@ -0,0 +1,766 @@ +import { VERSION } from '../../../../../src/v0/destinations/facebook_pixel/config'; +import { + overrideDestination, + generateTrackPayload, + generateMetadata, + transformResultBuilder, +} from '../../../testUtils'; +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; + +const commonDestination: Destination = { + ID: '12335', + Name: 'sample-destination', + DestinationDefinition: { + ID: '123', + Name: 'facebook_pixel', + DisplayName: 'Facebook Pixel', + Config: {}, + }, + WorkspaceID: '123', + Transformations: [], + Config: { + limitedDataUSage: true, + blacklistPiiProperties: [ + { + blacklistPiiProperties: '', + blacklistPiiHash: false, + }, + ], + accessToken: '09876', + pixelId: 'dummyPixelId', + eventsToEvents: [ + { + from: 'ABC Started', + to: 'InitiateCheckout', + }, + ], + eventCustomProperties: [ + { + eventCustomProperties: '', + }, + ], + valueFieldIdentifier: '', + advancedMapping: false, + whitelistPiiProperties: [ + { + whitelistPiiProperties: 'email', + }, + ], + categoryToContent: [ + { + from: 'clothing', + to: 'newClothing', + }, + ], + }, + Enabled: true, +}; + +const commonUserTraits = { + email: 'abc@gmail.com', + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + event_id: '12345', +}; + +// the below object has properties that are used as whitelist and blacklist properties in below test cases +const piiPropertiesForAllowDeny = { + email: 'abc@gmail.com', + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + event_id: '12345', + firstName: 'John', + lastName: 'Doe', + whitelistProp1: 'val1', + blacklistProp2: 'val2', + blacklistProp3: 'val3', + category: 'dummy', + quantity: 10, + value: 100, + product_id: '12345', +}; + +const commonPropertiesWithoutProductArray = { + category: 'dummy', + quantity: 10, + value: 100, + product_id: '12345', +}; + +const commonTimestamp = new Date('2023-10-14'); + +export const configLevelFeaturesTestData: ProcessorTestData[] = [ + { + id: 'facebook_pixel-config-test-1', + name: 'facebook_pixel', + description: + 'config feature : limitedDataUSage switched on. Ref:https://developers.facebook.com/docs/marketing-apis/data-processing-options/#supported-tools-and-apis ', + scenario: 'configuration', + successCriteria: 'Response should contain limitedDataUSage related fields', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'product list viewed', + properties: commonPropertiesWithoutProductArray, + context: { + traits: commonUserTraits, + dataProcessingOptions: ['val1', 'val2', 'val3'], + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'ViewContent', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + data_processing_options: 'val1', + data_processing_options_country: 'val2', + data_processing_options_state: 'val3', + custom_data: { + category: 'dummy', + quantity: 10, + value: 100, + product_id: '12345', + content_ids: ['dummy'], + content_type: 'product_group', + contents: [ + { + id: 'dummy', + quantity: 1, + }, + ], + content_category: 'dummy', + currency: 'USD', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-config-test-2', + name: 'facebook_pixel', + scenario: 'configuration', + description: + 'config feature : While categoryToContent mapping is filled up in UI, but category is passed with message.properties as well. message.properties.category should be given priority over categoryToContent mapping', + successCriteria: 'Response should contain category mapped to newClothing', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'product list viewed', + properties: { ...commonPropertiesWithoutProductArray, category: 'clothing' }, + context: { + traits: commonUserTraits, + dataProcessingOptions: ['val1', 'val2', 'val3'], + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'ViewContent', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + data_processing_options: 'val1', + data_processing_options_country: 'val2', + data_processing_options_state: 'val3', + custom_data: { + category: 'clothing', + quantity: 10, + value: 100, + product_id: '12345', + content_ids: ['clothing'], + content_type: 'newClothing', + contents: [ + { + id: 'clothing', + quantity: 1, + }, + ], + content_category: 'clothing', + currency: 'USD', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-config-test-3', + name: 'facebook_pixel', + description: + 'config feature : ContentCategoryMapping table is filled up, and category is passed with properties along with contentType via integrations object', + scenario: 'configuration', + successCriteria: 'contentType should be used from integrations object', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'product list viewed', + properties: { ...commonPropertiesWithoutProductArray, category: 'clothing' }, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + integrations: { + FacebookPixel: { + contentType: 'newClothingFromIntegrationObject', + }, + }, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'ViewContent', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + category: 'clothing', + quantity: 10, + value: 100, + product_id: '12345', + content_ids: ['clothing'], + content_type: 'newClothingFromIntegrationObject', + contents: [ + { + id: 'clothing', + quantity: 1, + }, + ], + content_category: 'clothing', + currency: 'USD', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-config-test-4', + name: 'facebook_pixel', + description: + 'config feature : Config mapped whiteList and blackListed properties with marked hashed within integrations object, along with default pii property email in the properties', + scenario: 'configuration', + successCriteria: + 'BlackListed properties should not be hashed and default pii property should be deleted from the properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'product list viewed', + properties: { ...piiPropertiesForAllowDeny }, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + integrations: { + FacebookPixel: { + hashed: true, + }, + }, + }), + metadata: generateMetadata(1), + destination: overrideDestination(commonDestination, { + whitelistPiiProperties: [ + { + whitelistPiiProperties: 'whitelistProp1', + }, + ], + blacklistPiiProperties: [ + { + blacklistPiiProperties: 'blacklistProp2', + }, + { + blacklistPiiProperties: 'blacklistProp3', + }, + ], + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: 'default-user-id', + em: 'abc@gmail.com', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'ViewContent', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + whitelistProp1: 'val1', + blacklistProp2: 'val2', + blacklistProp3: 'val3', + category: 'dummy', + quantity: 10, + value: 100, + product_id: '12345', + content_ids: ['dummy'], + content_type: 'product_group', + contents: [ + { + id: 'dummy', + quantity: 1, + }, + ], + content_category: 'dummy', + currency: 'USD', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-config-test-5', + name: 'facebook_pixel', + description: + 'config feature : Config mapped whiteList and blackListed properties without marked hashed within integrations object but marked hashed true from UI, along with default pii property email in the properties', + scenario: 'configuration', + successCriteria: + 'BlackListed properties should be hashed and default pii property should be deleted from the properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'product list viewed', + properties: { ...piiPropertiesForAllowDeny }, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: overrideDestination(commonDestination, { + whitelistPiiProperties: [ + { + whitelistPiiProperties: 'whitelistProp1', + }, + ], + blacklistPiiProperties: [ + { + blacklistPiiProperties: 'blacklistProp2', + blacklistPiiHash: true, + }, + { + blacklistPiiProperties: 'blacklistProp3', + blacklistPiiHash: true, + }, + ], + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'ViewContent', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + whitelistProp1: 'val1', + blacklistProp2: + '528e5290f8ff0eb0325f0472b9c1a9ef4fac0b02ff6094b64d9382af4a10444b', + blacklistProp3: + 'bac8d4414984861d5199b7a97699c728bee36c4084299b2ca905434cf65d8944', + category: 'dummy', + quantity: 10, + value: 100, + product_id: '12345', + content_ids: ['dummy'], + content_type: 'product_group', + contents: [ + { + id: 'dummy', + quantity: 1, + }, + ], + content_category: 'dummy', + currency: 'USD', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-config-test-6', + name: 'facebook_pixel', + description: + 'config feature : Config mapped whiteList and blackListed properties marked hashed within integrations object but marked hashed true from UI, along with default pii property email in the properties', + scenario: 'configuration', + successCriteria: + 'BlackListed properties should not be hashed again and default pii property should be deleted from the properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'product list viewed', + properties: { ...piiPropertiesForAllowDeny }, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + integrations: { + FacebookPixel: { + hashed: true, + }, + }, + }), + metadata: generateMetadata(1), + destination: overrideDestination(commonDestination, { + whitelistPiiProperties: [ + { + whitelistPiiProperties: 'whitelistProp1', + }, + ], + blacklistPiiProperties: [ + { + blacklistPiiProperties: 'blacklistProp2', + blacklistPiiHash: true, + }, + { + blacklistPiiProperties: 'blacklistProp3', + blacklistPiiHash: true, + }, + ], + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: 'default-user-id', + em: 'abc@gmail.com', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'ViewContent', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + whitelistProp1: 'val1', + blacklistProp2: 'val2', + blacklistProp3: 'val3', + category: 'dummy', + quantity: 10, + value: 100, + product_id: '12345', + content_ids: ['dummy'], + content_type: 'product_group', + contents: [ + { + id: 'dummy', + quantity: 1, + }, + ], + content_category: 'dummy', + currency: 'USD', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-config-test-7', + name: 'facebook_pixel', + description: + 'properties.content_type is given priority over populating it from categoryToContent mapping.', + scenario: 'configuration', + successCriteria: 'Response should contain content_type as product_group and not newClothing', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'product list viewed', + properties: { ...piiPropertiesForAllowDeny, content_type: 'product_group' }, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + integrations: { + FacebookPixel: { + hashed: true, + }, + }, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: 'default-user-id', + em: 'abc@gmail.com', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'ViewContent', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + email: 'abc@gmail.com', + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + whitelistProp1: 'val1', + blacklistProp2: 'val2', + blacklistProp3: 'val3', + category: 'dummy', + quantity: 10, + value: 100, + product_id: '12345', + content_type: 'product_group', + content_ids: ['dummy'], + contents: [ + { + id: 'dummy', + quantity: 1, + }, + ], + content_category: 'dummy', + currency: 'USD', + }, + }), + ], + }, + files: {}, + userId: '', + }), + metadata: generateMetadata(1), + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/facebook_pixel/processor/data.ts b/test/integrations/destinations/facebook_pixel/processor/data.ts index 557bc7066c3..6af7e3cd9ba 100644 --- a/test/integrations/destinations/facebook_pixel/processor/data.ts +++ b/test/integrations/destinations/facebook_pixel/processor/data.ts @@ -1,4 +1,9 @@ -import { VERSION } from '../../../../../src/v0/destinations/facebook_pixel/config'; +import { identifyTestData } from './identifyTestData'; +import { trackTestData } from './trackTestData'; +import { validationTestData } from './validationTestData'; +import { pageScreenTestData } from './pageScreenTestData'; +import { ecommTestData } from './ecommTestData'; +import { configLevelFeaturesTestData } from './configLevelFeaturesTestData'; export const mockFns = (_) => { // @ts-ignore @@ -6,6458 +11,10 @@ export const mockFns = (_) => { }; export const data = [ - { - name: 'facebook_pixel', - description: 'Test 0', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - channel: 'mobile', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: ' aBc@gmail.com ', - address: { - zip: 1234, - }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - }, - timestamp: '2023-10-14T00:00:00.693229+05:30', - type: 'track', - }, - destination: { - Config: { - limitedDataUsage: true, - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - removeExternalId: true, - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08","zp":"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4"},"event_name":"spin_result","event_time":1697221800,"action_source":"app","custom_data":{"additional_bet_index":0,"value":400}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 1', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: ' aBc@gmail.com ', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - }, - timestamp: '2023-10-14T15:46:51.693229+05:30', - type: 'group', - }, - destination: { - Config: { - limitedDataUsage: true, - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: 'Message type group not supported', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'FACEBOOK_PIXEL', - module: 'destination', - implementation: 'native', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 2', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - traits: { - name: 'Test', - }, - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - properties: { - plan: 'standard plan', - name: 'rudder test', - }, - type: 'identify', - messageId: '84e26acc-56a5-4835-8233-591137fca468', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '123456', - integrations: { - All: true, - }, - sentAt: '2019-10-14T09:03:22.563Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: - 'For identify events, "Advanced Mapping" configuration must be enabled on the RudderStack dashboard', - statTags: { - errorCategory: 'dataValidation', - errorType: 'configuration', - destType: 'FACEBOOK_PIXEL', - module: 'destination', - implementation: 'native', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 3', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - traits: { - name: 'Rudder Test', - email: 'abc@gmail.com', - firstname: 'Rudder', - lastname: 'Test', - phone: 9000000000, - gender: 'female', - }, - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - properties: { - plan: 'standard plan', - name: 'rudder test', - }, - type: 'identify', - messageId: '84e26acc-56a5-4835-8233-591137fca468', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '123456', - integrations: { - All: true, - }, - sentAt: '2019-10-14T09:03:22.563Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: true, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92","em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08","ph":"593a6d58f34eb5c3de4f47e38d1faaa7d389fafe332a85400b1e54498391c579","ge":"252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111","ln":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25","fn":"2c2ccf28d806f6f9a34b67aa874d2113b7ac1444f1a4092541b8b75b84771747","client_ip_address":"0.0.0.0","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"identify","event_time":1697278611,"event_id":"84e26acc-56a5-4835-8233-591137fca468","action_source":"website"}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 4', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - traits: { - name: 'Rudder Test', - email: 'abc@gmail.com', - phone: 9000000000, - address: { - postalCode: 1234, - }, - gender: 'female', - }, - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - properties: { - plan: 'standard plan', - name: 'rudder test', - }, - type: 'identify', - messageId: '84e26acc-56a5-4835-8233-591137fca468', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '123456', - integrations: { - All: true, - }, - sentAt: '2019-10-14T09:03:22.563Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: true, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92","em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08","ph":"593a6d58f34eb5c3de4f47e38d1faaa7d389fafe332a85400b1e54498391c579","ge":"252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111","zp":"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4","client_ip_address":"0.0.0.0","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36","fn":"2c2ccf28d806f6f9a34b67aa874d2113b7ac1444f1a4092541b8b75b84771747","ln":"532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25"},"event_name":"identify","event_time":1697278611,"event_id":"84e26acc-56a5-4835-8233-591137fca468","action_source":"website"}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 5', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: 'abc@gmail.com', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - email: 'abc@gmail.com', - }, - timestamp: '2023-10-14T15:46:51.693229+05:30', - type: 'track', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"6dc8118ec743f5f3b758939714193f547f4a674c68757fa80d7c9564dc093b0a","em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"},"event_name":"spin_result","event_time":1697278611,"action_source":"other","custom_data":{"additional_bet_index":0,"value":400}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 6', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: 'abc@gmail.com', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - email: 'abc@gmail.com', - }, - timestamp: '2023-10-14T15:46:51.693229+05:30', - type: 'track', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: 'email', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"6dc8118ec743f5f3b758939714193f547f4a674c68757fa80d7c9564dc093b0a","em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"},"event_name":"spin_result","event_time":1697278611,"action_source":"other","custom_data":{"additional_bet_index":0,"email":"abc@gmail.com","value":400}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 7', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: 'abc@gmail.com', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - email: 'abc@gmail.com', - phone: 9000000000, - }, - timestamp: '2023-10-14T15:46:51.693229+05:30', - type: 'track', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: 'phone', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: 'email', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"6dc8118ec743f5f3b758939714193f547f4a674c68757fa80d7c9564dc093b0a","em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"},"event_name":"spin_result","event_time":1697278611,"action_source":"other","custom_data":{"additional_bet_index":0,"email":"abc@gmail.com","value":400}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 8', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: 'abc@gmail.com', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - email: 'abc@gmail.com', - phone: 9000000000, - }, - timestamp: '2023-10-14T15:46:51.693229+05:30', - type: 'track', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: 'phone', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: 'email', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"6dc8118ec743f5f3b758939714193f547f4a674c68757fa80d7c9564dc093b0a","em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"},"event_name":"spin_result","event_time":1697278611,"action_source":"other","custom_data":{"additional_bet_index":0,"email":"abc@gmail.com","phone":"593a6d58f34eb5c3de4f47e38d1faaa7d389fafe332a85400b1e54498391c579","value":400}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 9', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'page', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - timestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - path: '/abc', - referrer: 'xyz', - search: 'def', - title: 'ghi', - url: 'jkl', - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: 'phone', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: 'email', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","client_ip_address":"0.0.0.0","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"Viewed page ApplicationLoaded","event_time":1697278611,"event_source_url":"jkl","event_id":"5e10d13a-bf9a-44bf-b884-43a9e591ea71","action_source":"website","custom_data":{"path":"/abc","referrer":"xyz","search":"def","title":"ghi","url":"jkl"}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 10', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'page', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - path: '/abc', - referrer: 'xyz', - search: 'def', - title: 'ghi', - url: 'jkl', - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: 'phone', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: 'email', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","client_ip_address":"0.0.0.0","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"Viewed a page","event_time":1697278611,"event_source_url":"jkl","event_id":"5e10d13a-bf9a-44bf-b884-43a9e591ea71","action_source":"website","custom_data":{"path":"/abc","referrer":"xyz","search":"def","title":"ghi","url":"jkl"}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 11', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'product list viewed', - properties: { - phone: 9000000000, - email: 'abc@gmail.com', - category: 'cat 1', - list_id: '1234', - filters: [ - { - type: 'department', - value: 'beauty', - }, - { - type: 'price', - value: 'under', - }, - ], - sorts: [ - { - type: 'price', - value: 'desc', - }, - ], - testDimension: true, - testMetric: true, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: 'phone', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: 'email', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"ViewContent","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"phone":"593a6d58f34eb5c3de4f47e38d1faaa7d389fafe332a85400b1e54498391c579","email":"abc@gmail.com","category":"cat 1","list_id":"1234","filters[0].type":"department","filters[0].value":"beauty","filters[1].type":"price","filters[1].value":"under","sorts[0].type":"price","sorts[0].value":"desc","testDimension":true,"testMetric":true,"content_ids":["cat 1"],"content_type":"product_group","contents":[{"id":"cat 1","quantity":1}],"content_category":"cat 1","value":0,"currency":"USD"}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 12', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'product list viewed', - properties: { - phone: 9000000000, - email: 'abc@gmail.com', - category: 'cat 1', - list_id: '1234', - filters: [ - { - type: 'department', - value: 'beauty', - }, - { - type: 'price', - value: 'under', - }, - ], - sorts: [ - { - type: 'price', - value: 'desc', - }, - ], - testDimension: true, - testMetric: true, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"ViewContent","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"category":"cat 1","list_id":"1234","filters[0].type":"department","filters[0].value":"beauty","filters[1].type":"price","filters[1].value":"under","sorts[0].type":"price","sorts[0].value":"desc","testDimension":true,"testMetric":true,"content_ids":["cat 1"],"content_type":"product_group","contents":[{"id":"cat 1","quantity":1}],"content_category":"cat 1","value":0,"currency":"USD"}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 13', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'product list viewed', - properties: { - email: 'abc@gmail.com', - quantity: 2, - category: 'cat 1', - list_id: '1234', - contentName: 'nutrition', - value: 18.9, - filters: [ - { - type: 'department', - value: 'beauty', - }, - { - type: 'price', - value: 'under', - }, - ], - sorts: [ - { - type: 'price', - value: 'desc', - }, - ], - products: [ - { - product_id: '507f1f77bcf86cd799439011', - productDimension: 'My Product Dimension', - productMetric: 'My Product Metric', - position: 10, - }, - { - product_id: '507f1f77bcf86cdef799439011', - productDimension: 'My Product Dimension1', - productMetric: 'My Product Metric1', - position: -10, - }, - ], - testDimension: true, - testMetric: true, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"ViewContent","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"quantity":2,"category":"cat 1","list_id":"1234","contentName":"nutrition","value":18.9,"filters[0].type":"department","filters[0].value":"beauty","filters[1].type":"price","filters[1].value":"under","sorts[0].type":"price","sorts[0].value":"desc","products[0].product_id":"507f1f77bcf86cd799439011","products[0].productDimension":"My Product Dimension","products[0].productMetric":"My Product Metric","products[0].position":10,"products[1].product_id":"507f1f77bcf86cdef799439011","products[1].productDimension":"My Product Dimension1","products[1].productMetric":"My Product Metric1","products[1].position":-10,"testDimension":true,"testMetric":true,"content_ids":["507f1f77bcf86cd799439011","507f1f77bcf86cdef799439011"],"content_type":"product","contents":[{"id":"507f1f77bcf86cd799439011","quantity":2},{"id":"507f1f77bcf86cdef799439011","quantity":2}],"content_category":"cat 1","content_name":"nutrition","currency":"USD"}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 14', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'my product list', - properties: { - email: 'abc@gmail.com', - quantity: 2, - category: 'cat 1', - list_id: '1234', - filters: [ - { - type: 'department', - value: 'beauty', - }, - { - type: 'price', - value: 'under', - }, - ], - sorts: [ - { - type: 'price', - value: 'desc', - }, - ], - products: [ - { - product_id: '507f1f77bcf86cd799439011', - productDimension: 'My Product Dimension', - productMetric: 'My Product Metric', - position: 10, - }, - { - product_id: '507f1f77bcf86cdef799439011', - productDimension: 'My Product Dimension1', - productMetric: 'My Product Metric1', - position: -10, - }, - ], - testDimension: true, - testMetric: true, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - removeExternalId: false, - eventsToEvents: [ - { - from: 'My product list', - to: 'ViewContent', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: 'list_id', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"ViewContent","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"quantity":2,"category":"cat 1","list_id":"1234","filters[0].type":"department","filters[0].value":"beauty","filters[1].type":"price","filters[1].value":"under","sorts[0].type":"price","sorts[0].value":"desc","products[0].product_id":"507f1f77bcf86cd799439011","products[0].productDimension":"My Product Dimension","products[0].productMetric":"My Product Metric","products[0].position":10,"products[1].product_id":"507f1f77bcf86cdef799439011","products[1].productDimension":"My Product Dimension1","products[1].productMetric":"My Product Metric1","products[1].position":-10,"testDimension":true,"testMetric":true,"content_ids":["507f1f77bcf86cd799439011","507f1f77bcf86cdef799439011"],"content_type":"product","contents":[{"id":"507f1f77bcf86cd799439011","quantity":2},{"id":"507f1f77bcf86cdef799439011","quantity":2}],"content_category":"cat 1","value":0,"currency":"USD"}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 15', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'product viewed', - properties: { - currency: 'CAD', - quantity: 1, - price: 24.75, - name: 'my product 1', - category: 'clothing', - sku: 'p-298', - testDimension: true, - testMetric: true, - position: 4.5, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - removeExternalId: true, - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"ViewContent","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"currency":"CAD","quantity":1,"price":24.75,"name":"my product 1","category":"clothing","sku":"p-298","testDimension":true,"testMetric":true,"position":4.5,"content_ids":["p-298"],"content_type":"product","content_name":"my product 1","content_category":"clothing","value":24.75,"contents":[{"id":"p-298","quantity":1,"item_price":24.75}]}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 16', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'product added', - properties: { - currency: 'CAD', - quantity: 1, - value: 24.75, - category: 'cat 1', - id: 'p-298', - testDimension: true, - testMetric: true, - position: 4.5, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - removeExternalId: false, - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.value', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"AddToCart","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"currency":"CAD","quantity":1,"value":24.75,"category":"cat 1","id":"p-298","testDimension":true,"testMetric":true,"position":4.5,"content_ids":["p-298"],"content_type":"product","content_name":"","content_category":"cat 1","contents":[{"id":"p-298","quantity":1}]}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 17', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'order completed', - properties: { - order_id: 'rudderstackorder1', - total: 99.99, - revenue: 12.24, - shipping: 13.99, - tax: 20.99, - currency: 'INR', - contentName: 'all about nutrition', - products: [ - { - quantity: 1, - price: 24.75, - name: 'my product', - sku: 'p-298', - }, - { - quantity: 3, - price: 24.75, - name: 'other product', - sku: 'p-299', - }, - ], - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","em":"1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"Purchase","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"order_id":"rudderstackorder1","total":99.99,"revenue":12.24,"shipping":13.99,"tax":20.99,"currency":"INR","contentName":"all about nutrition","products[0].quantity":1,"products[0].price":24.75,"products[0].name":"my product","products[0].sku":"p-298","products[1].quantity":3,"products[1].price":24.75,"products[1].name":"other product","products[1].sku":"p-299","content_ids":["p-298","p-299"],"content_type":"product","value":12.24,"contents":[{"id":"p-298","quantity":1,"item_price":24.75},{"id":"p-299","quantity":3,"item_price":24.75}],"num_items":2,"content_name":"all about nutrition"}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 18', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'checkout started', - properties: { - currency: 'CAD', - category: 'clothing', - contentName: 'abc', - products: [ - { - quantity: 1, - price: 24.75, - name: 'my product', - sku: 'p-298', - }, - { - quantity: 1, - price: 24.75, - name: 'my product 2', - sku: 'p-299', - }, - ], - step: 1, - paymentMethod: 'Visa', - testDimension: true, - testMetric: true, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: 'contentName', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","em":"1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"InitiateCheckout","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"currency":"CAD","category":"clothing","contentName":"abc","products[0].quantity":1,"products[0].price":24.75,"products[0].name":"my product","products[0].sku":"p-298","products[1].quantity":1,"products[1].price":24.75,"products[1].name":"my product 2","products[1].sku":"p-299","step":1,"paymentMethod":"Visa","testDimension":true,"testMetric":true,"content_category":"clothing","content_ids":["p-298","p-299"],"content_type":"product","value":0,"contents":[{"id":"p-298","quantity":1,"item_price":24.75},{"id":"p-299","quantity":1,"item_price":24.75}],"num_items":2}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 19', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - dataProcessingOptions: [['LDU'], 1, 1000], - fbc: 'fb.1.1554763741205.AbCdEfGhIjKlMnOpQrStUvWxYz1234567890', - fbp: 'fb.1.1554763741205.234567890', - fb_login_id: 'fb_id', - lead_id: 'lead_id', - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: 'abc@gmail.com', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - }, - timestamp: '2023-10-14T15:46:51.693229+05:30', - type: 'track', - }, - destination: { - Config: { - limitedDataUSage: true, - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"6dc8118ec743f5f3b758939714193f547f4a674c68757fa80d7c9564dc093b0a","em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08","fbc":"fb.1.1554763741205.AbCdEfGhIjKlMnOpQrStUvWxYz1234567890","fbp":"fb.1.1554763741205.234567890","lead_id":"lead_id","fb_login_id":"fb_id"},"event_name":"spin_result","event_time":1697278611,"action_source":"other","data_processing_options":["LDU"],"data_processing_options_country":1,"data_processing_options_state":1000,"custom_data":{"additional_bet_index":0,"value":400}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 20', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - dataProcessingOptions: [['LDU'], 1, 1000], - fbc: 'fb.1.1554763741205.AbCdEfGhIjKlMnOpQrStUvWxYz1234567890', - fbp: 'fb.1.1554763741205.234567890', - fb_login_id: 'fb_id', - lead_id: 'lead_id', - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: 'abc@gmail.com', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - }, - timestamp: '2023-10-14T15:46:51.693229+05:30', - type: 'track', - }, - destination: { - Config: { - limitedDataUSage: false, - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"6dc8118ec743f5f3b758939714193f547f4a674c68757fa80d7c9564dc093b0a","em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08","fbc":"fb.1.1554763741205.AbCdEfGhIjKlMnOpQrStUvWxYz1234567890","fbp":"fb.1.1554763741205.234567890","lead_id":"lead_id","fb_login_id":"fb_id"},"event_name":"spin_result","event_time":1697278611,"action_source":"other","custom_data":{"additional_bet_index":0,"value":400}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 21', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'products searched', - properties: { - product_id: 'p-298', - quantity: 2, - price: 18.9, - category: 'health', - value: 18.9, - query: 'HDMI cable', - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","em":"1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"Search","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"product_id":"p-298","quantity":2,"price":18.9,"category":"health","value":18.9,"query":"HDMI cable","content_ids":["p-298"],"content_category":"health","contents":[{"id":"p-298","quantity":2,"item_price":18.9}],"search_string":"HDMI cable","currency":"USD"}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 22', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'products searched', - properties: { - query: 'HDMI cable', - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - testDestination: true, - testEventCode: 'TEST1001', - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","em":"1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"Search","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"query":"HDMI cable","content_ids":[],"content_category":"","value":0,"contents":[],"search_string":"HDMI cable","currency":"USD"}}', - ], - test_event_code: 'TEST1001', - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 23', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'page', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - path: '/abc', - referrer: 'xyz', - search: 'def', - title: 'ghi', - url: 'jkl', - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - standardPageCall: true, - blacklistPiiProperties: [ - { - blacklistPiiProperties: 'phone', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: 'url', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: 'email', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","client_ip_address":"0.0.0.0","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"PageView","event_time":1697278611,"event_source_url":"jkl","event_id":"5e10d13a-bf9a-44bf-b884-43a9e591ea71","action_source":"website","custom_data":{"path":"/abc","referrer":"xyz","search":"def","title":"ghi","url":"jkl"}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 24', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: 'abc@gmail.com', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'track page', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - }, - timestamp: '2023-10-14T15:46:51.693229+05:30', - type: 'track', - }, - destination: { - Config: { - limitedDataUsage: true, - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: 'track page', - to: 'PageView', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: 'additional_bet_index', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"6dc8118ec743f5f3b758939714193f547f4a674c68757fa80d7c9564dc093b0a","em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"},"event_name":"PageView","event_time":1697278611,"action_source":"other","custom_data":{"revenue":400,"additional_bet_index":0}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 25', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'my product list', - properties: { - email: 'abc@gmail.com', - quantity: 2, - category: 'cat 1', - list_id: '1234', - filters: [ - { - type: 'department', - value: 'beauty', - }, - { - type: 'price', - value: 'under', - }, - ], - sorts: [ - { - type: 'price', - value: 'desc', - }, - ], - products: [ - { - product_id: '507f1f77bcf86cd799439011', - productDimension: 'My Product Dimension', - productMetric: 'My Product Metric', - position: 10, - }, - { - product_id: '507f1f77bcf86cdef799439011', - productDimension: 'My Product Dimension1', - productMetric: 'My Product Metric1', - position: -10, - }, - ], - testDimension: true, - testMetric: true, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: 'My product list', - to: 'Schedule', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: 'list_id', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"Schedule","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"quantity":2,"category":"cat 1","list_id":"1234","filters[0].type":"department","filters[0].value":"beauty","filters[1].type":"price","filters[1].value":"under","sorts[0].type":"price","sorts[0].value":"desc","products[0].product_id":"507f1f77bcf86cd799439011","products[0].productDimension":"My Product Dimension","products[0].productMetric":"My Product Metric","products[0].position":10,"products[1].product_id":"507f1f77bcf86cdef799439011","products[1].productDimension":"My Product Dimension1","products[1].productMetric":"My Product Metric1","products[1].position":-10,"testDimension":true,"testMetric":true}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 26', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: 'abc@gmail.com', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - }, - timestamp: '2023-10-14T15:46:51.693229+05:30', - type: 'track', - }, - destination: { - Config: { - limitedDataUsage: true, - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: "'event' is required", - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'FACEBOOK_PIXEL', - module: 'destination', - implementation: 'native', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 27', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'product added', - properties: { - currency: 'CAD', - quantity: 1, - value: '35.753', - category: 'cat 1', - id: 'p-298', - testDimension: true, - testMetric: true, - position: 4.5, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.value', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"AddToCart","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"currency":"CAD","quantity":1,"value":35.75,"category":"cat 1","id":"p-298","testDimension":true,"testMetric":true,"position":4.5,"content_ids":["p-298"],"content_type":"product","content_name":"","content_category":"cat 1","contents":[{"id":"p-298","quantity":1}]}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 28', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'product added', - properties: { - currency: 'CAD', - quantity: 1, - value: '35.7A3', - category: 'cat 1', - id: 'p-298', - testDimension: true, - testMetric: true, - position: 4.5, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.value', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"AddToCart","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"currency":"CAD","quantity":1,"value":35.7,"category":"cat 1","id":"p-298","testDimension":true,"testMetric":true,"position":4.5,"content_ids":["p-298"],"content_type":"product","content_name":"","content_category":"cat 1","contents":[{"id":"p-298","quantity":1}]}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 29', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'product added', - properties: { - currency: 'CAD', - quantity: 1, - value: 'ABC', - category: 'cat 1', - id: 'p-298', - testDimension: true, - testMetric: true, - position: 4.5, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.value', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: 'Revenue could not be converted to number', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'FACEBOOK_PIXEL', - module: 'destination', - implementation: 'native', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 30', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'order completed', - properties: { - category: ['clothing', 'fishing'], - order_id: 'rudderstackorder1', - total: 99.99, - revenue: 12.24, - shipping: 13.99, - tax: 20.99, - currency: 'INR', - products: [ - { - quantity: 1, - price: 24.75, - name: 'my product', - sku: 'p-298', - }, - { - quantity: 3, - price: 24.75, - name: 'other product', - sku: 'p-299', - }, - ], - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","em":"1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"Purchase","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"category[0]":"clothing","category[1]":"fishing","order_id":"rudderstackorder1","total":99.99,"revenue":12.24,"shipping":13.99,"tax":20.99,"currency":"INR","products[0].quantity":1,"products[0].price":24.75,"products[0].name":"my product","products[0].sku":"p-298","products[1].quantity":3,"products[1].price":24.75,"products[1].name":"other product","products[1].sku":"p-299","content_category":"clothing,fishing","content_ids":["p-298","p-299"],"content_type":"product","value":12.24,"contents":[{"id":"p-298","quantity":1,"item_price":24.75},{"id":"p-299","quantity":3,"item_price":24.75}],"num_items":2}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 31', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'order completed', - properties: { - category: 100, - order_id: 'rudderstackorder1', - total: 99.99, - revenue: 12.24, - shipping: 13.99, - tax: 20.99, - currency: 'INR', - products: [ - { - quantity: 1, - price: 24.75, - name: 'my product', - sku: 'p-298', - }, - { - quantity: 3, - price: 24.75, - name: 'other product', - sku: 'p-299', - }, - ], - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","em":"1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"Purchase","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"category":100,"order_id":"rudderstackorder1","total":99.99,"revenue":12.24,"shipping":13.99,"tax":20.99,"currency":"INR","products[0].quantity":1,"products[0].price":24.75,"products[0].name":"my product","products[0].sku":"p-298","products[1].quantity":3,"products[1].price":24.75,"products[1].name":"other product","products[1].sku":"p-299","content_category":"100","content_ids":["p-298","p-299"],"content_type":"product","value":12.24,"contents":[{"id":"p-298","quantity":1,"item_price":24.75},{"id":"p-299","quantity":3,"item_price":24.75}],"num_items":2}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 32', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'order completed', - properties: { - category: { - category1: '1', - }, - order_id: 'rudderstackorder1', - total: 99.99, - revenue: 12.24, - shipping: 13.99, - tax: 20.99, - currency: 'INR', - products: [ - { - quantity: 1, - price: 24.75, - name: 'my product', - sku: 'p-298', - }, - { - quantity: 3, - price: 24.75, - name: 'other product', - sku: 'p-299', - }, - ], - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: "'properties.category' must be either be a string or an array", - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'FACEBOOK_PIXEL', - module: 'destination', - implementation: 'native', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 33', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: 'abc@gmail.com', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - }, - timestamp: '2023-10-14T15:46:51.693229+05:30', - type: 'track', - }, - destination: { - Config: { - limitedDataUsage: true, - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: 'spin_result', - to: 'Schedule', - }, - { - to: 'Schedule', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"6dc8118ec743f5f3b758939714193f547f4a674c68757fa80d7c9564dc093b0a","em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"},"event_name":"Schedule","event_time":1697278611,"action_source":"other","custom_data":{"revenue":400,"additional_bet_index":0}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 34', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: 'abc@gmail.com', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - }, - timestamp: '2019-08-24T15:46:51.693229+05:30', - type: 'track', - }, - destination: { - Config: { - limitedDataUsage: true, - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: 'spin_result', - to: 'Schedule', - }, - { - to: 'Schedule', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: - 'Events must be sent within seven days of their occurrence or up to one minute in the future.', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'FACEBOOK_PIXEL', - module: 'destination', - implementation: 'native', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 35', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: 'abc@gmail.com', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - }, - originalTimestamp: '2019-04-16T15:50:51.693229+05:30', - type: 'track', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: 'validToken', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: true, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: - 'Events must be sent within seven days of their occurrence or up to one minute in the future.', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'FACEBOOK_PIXEL', - module: 'destination', - implementation: 'native', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 36', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'products searched', - properties: { - query: { - key1: 'HDMI cable', - }, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: "'query' should be in string format only", - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'FACEBOOK_PIXEL', - module: 'destination', - implementation: 'native', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 37', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'products searched', - properties: { - query: 50, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","em":"1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"Search","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"query":50,"content_ids":[],"content_category":"","value":0,"contents":[],"search_string":50,"currency":"USD"}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 38', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - page: { - url: 'https://theminimstory.com/collections/summer-of-pearls?utm_source=facebook&utm_medium=paidsocial&utm_campaign=carousel&utm_content=ad1-jul&fbclid=IwAR2SsDcjzd_TLZN-e93kxOeGBYO4pQ3AiyeXSheHW5emDeLw8uTvo6lTMPI', - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'checkout started', - properties: { - currency: 'CAD', - category: 'clothing', - products: [ - { - quantity: 1, - price: 24.75, - name: 'my product', - sku: 'p-298', - }, - { - quantity: 1, - price: 24.75, - name: 'my product 2', - sku: 'p-299', - }, - ], - step: 1, - paymentMethod: 'Visa', - testDimension: true, - testMetric: true, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","em":"1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36","fbc":"fb.1.1697278611693.IwAR2SsDcjzd_TLZN-e93kxOeGBYO4pQ3AiyeXSheHW5emDeLw8uTvo6lTMPI"},"event_name":"InitiateCheckout","event_time":1697278611,"event_source_url":"https://theminimstory.com/collections/summer-of-pearls?utm_source=facebook&utm_medium=paidsocial&utm_campaign=carousel&utm_content=ad1-jul&fbclid=IwAR2SsDcjzd_TLZN-e93kxOeGBYO4pQ3AiyeXSheHW5emDeLw8uTvo6lTMPI","event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"currency":"CAD","category":"clothing","products[0].quantity":1,"products[0].price":24.75,"products[0].name":"my product","products[0].sku":"p-298","products[1].quantity":1,"products[1].price":24.75,"products[1].name":"my product 2","products[1].sku":"p-299","step":1,"paymentMethod":"Visa","testDimension":true,"testMetric":true,"content_category":"clothing","content_ids":["p-298","p-299"],"content_type":"product","value":0,"contents":[{"id":"p-298","quantity":1,"item_price":24.75},{"id":"p-299","quantity":1,"item_price":24.75}],"num_items":2}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 39', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - page: { - url: 'https://theminimstory.com/collections/summer-of-pearls?utm_source=facebook&utm_medium=paidsocial&utm_campaign=carousel&utm_content=ad1-jul&fbclid=IwAR2SsDcjzd_TLZN-e93kxOeGBYO4pQ3AiyeXSheHW5emDeLw8uTvo6lTMPI', - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: { - name: 'checkout started', - }, - properties: { - currency: 'CAD', - category: 'clothing', - products: [ - { - quantity: 1, - price: 24.75, - name: 'my product', - sku: 'p-298', - }, - { - quantity: 1, - price: 24.75, - name: 'my product 2', - sku: 'p-299', - }, - ], - step: 1, - paymentMethod: 'Visa', - testDimension: true, - testMetric: true, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: 'event name should be string', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'FACEBOOK_PIXEL', - module: 'destination', - implementation: 'native', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 40', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - page: { - url: 'url in wrong format', - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'checkout started', - properties: { - currency: 'CAD', - category: 'clothing', - products: [ - { - quantity: 1, - price: 24.75, - name: 'my product', - sku: 'p-298', - }, - { - quantity: 1, - price: 24.75, - name: 'my product 2', - sku: 'p-299', - }, - ], - step: 1, - paymentMethod: 'Visa', - testDimension: true, - testMetric: true, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","em":"1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"InitiateCheckout","event_time":1697278611,"event_source_url":"url in wrong format","event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"currency":"CAD","category":"clothing","products[0].quantity":1,"products[0].price":24.75,"products[0].name":"my product","products[0].sku":"p-298","products[1].quantity":1,"products[1].price":24.75,"products[1].name":"my product 2","products[1].sku":"p-299","step":1,"paymentMethod":"Visa","testDimension":true,"testMetric":true,"content_category":"clothing","content_ids":["p-298","p-299"],"content_type":"product","value":0,"contents":[{"id":"p-298","quantity":1,"item_price":24.75},{"id":"p-299","quantity":1,"item_price":24.75}],"num_items":2}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 41', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'product viewed', - properties: { - currency: 'CAD', - quantity: 1, - price: 24.75, - name: 'my product 1', - category: 'clothing', - sku: 'p-298', - testDimension: true, - testMetric: true, - position: 4.5, - }, - integrations: { - All: true, - Facebook_Pixel: { - contentType: 'sending dedicated content type for this particular payload', - }, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - removeExternalId: true, - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"ViewContent","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"currency":"CAD","quantity":1,"price":24.75,"name":"my product 1","category":"clothing","sku":"p-298","testDimension":true,"testMetric":true,"position":4.5,"content_ids":["p-298"],"content_type":"sending dedicated content type for this particular payload","content_name":"my product 1","content_category":"clothing","value":24.75,"contents":[{"id":"p-298","quantity":1,"item_price":24.75}]}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 42', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'product viewed', - properties: { - currency: 'CAD', - quantity: 1, - price: 24.75, - value: 18.9, - name: 'my product 1', - category: 'clothing', - sku: 'p-298', - testDimension: true, - testMetric: true, - position: 4.5, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - removeExternalId: true, - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.value', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"ViewContent","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"currency":"CAD","quantity":1,"price":24.75,"value":18.9,"name":"my product 1","category":"clothing","sku":"p-298","testDimension":true,"testMetric":true,"position":4.5,"content_ids":["p-298"],"content_type":"product","content_name":"my product 1","content_category":"clothing","contents":[{"id":"p-298","quantity":1,"item_price":24.75}]}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 43', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'order completed', - properties: { - order_id: 'rudderstackorder1', - total: 99.99, - revenue: 12.24, - shipping: 13.99, - tax: 20.99, - currency: 'INR', - contentName: 'all about nutrition', - products: { - quantity: 1, - price: 24.75, - name: 'my product', - sku: 'p-298', - }, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: "'properties.products' is not sent as an Array", - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'FACEBOOK_PIXEL', - module: 'destination', - implementation: 'native', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 44', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'product list viewed', - properties: { - email: 'abc@gmail.com', - quantity: 2, - category: 'cat 1', - list_id: '1234', - contentName: 'nutrition', - value: 18.9, - products: [ - { - product_id: '507f1f77bcf86cd799439011', - productDimension: 'My Product Dimension', - productMetric: 'My Product Metric', - position: 10, - }, - [ - { - product_id: '507f1f77bcf86cdef799439011', - productDimension: 'My Product Dimension1', - productMetric: 'My Product Metric1', - position: -10, - }, - ], - ], - testDimension: true, - testMetric: true, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: "'properties.products[1]' is not an object", - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'FACEBOOK_PIXEL', - module: 'destination', - implementation: 'native', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 45', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'custom', - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - pixelId: 'dummyPixelId', - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: 'Access token not found. Aborting', - statTags: { - errorCategory: 'dataValidation', - errorType: 'configuration', - destType: 'FACEBOOK_PIXEL', - module: 'destination', - implementation: 'native', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 46', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'custom', - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: 'Pixel Id not found. Aborting', - statTags: { - errorCategory: 'dataValidation', - errorType: 'configuration', - destType: 'FACEBOOK_PIXEL', - module: 'destination', - implementation: 'native', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 47', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - metadata: { - jobId: 12, - }, - destination: { - secretConfig: {}, - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [], - limitedDataUSage: false, - accessToken: 'dummyAccessToken', - testDestination: false, - testEventCode: '', - standardPageCall: false, - blacklistedEvents: [], - whitelistedEvents: [], - eventFilteringOption: 'disable', - removeExternalId: false, - useUpdatedMapping: false, - oneTrustCookieCategories: [], - useNativeSDK: false, - eventDelivery: false, - eventDeliveryTS: 1686748039135, - }, - liveEventsConfig: { - eventDelivery: false, - eventDeliveryTS: 1686748039135, - }, - id: 'destId1', - workspaceId: 'wsp2', - transformations: [], - isConnectionEnabled: true, - isProcessorEnabled: true, - name: 'san-fb_pixel', - enabled: true, - deleted: false, - createdAt: '2023-06-06T13:36:08.579Z', - updatedAt: '2023-06-14T13:07:19.136Z', - revisionId: 'revId2', - secretVersion: 3, - }, - message: { - type: 'page', - sentAt: '2023-10-14T15:46:51.000Z', - userId: 'user@19', - channel: 'web', - context: { - os: { - name: '', - version: '', - }, - app: { - name: 'RudderLabs JavaScript SDK', - version: 'dev-snapshot', - namespace: 'com.rudderlabs.javascript', - }, - page: { - url: 'http://127.0.0.1:8888/', - path: '/', - title: 'Document', - search: '', - tab_url: 'http://127.0.0.1:8888/', - referrer: 'http://127.0.0.1:8888/', - initial_referrer: '$direct', - referring_domain: '127.0.0.1:8888', - initial_referring_domain: '', - }, - locale: 'en-GB', - screen: { - width: 1728, - height: 1117, - density: 2, - innerWidth: 547, - innerHeight: 915, - }, - traits: { - name: false, - source: 'rudderstack', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: 'dev-snapshot', - }, - campaign: {}, - sessionId: 1687769234506, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', - }, - rudderId: '6bbfd003-c074-4ee9-8674-c132ded9ff04', - timestamp: '2023-10-14T15:46:51.000Z', - properties: { - url: 'http://127.0.0.1:8888/', - path: '/', - title: 'Document', - search: '', - tab_url: 'http://127.0.0.1:8888/', - referrer: 'http://127.0.0.1:8888/', - initial_referrer: '$direct', - referring_domain: '127.0.0.1:8888', - initial_referring_domain: '', - }, - receivedAt: '2023-10-14T15:46:51.000Z', - request_ip: '49.206.54.243', - anonymousId: '700ab220-faad-4cdf-8484-63e4c6bce6fe', - integrations: { - All: true, - }, - originalTimestamp: '2023-10-14T15:46:51.000Z', - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=dummyAccessToken`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"72fd46c9ecb386f6747664a3e1d524294a3d7a2c8ae4aeb22b1e578b75093635","client_ip_address":"49.206.54.243","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"},"event_name":"PageView","event_time":1697298411,"event_source_url":"http://127.0.0.1:8888/","action_source":"website","custom_data":{"url":"http://127.0.0.1:8888/","path":"/","title":"Document","search":"","tab_url":"http://127.0.0.1:8888/","referrer":"http://127.0.0.1:8888/","initial_referrer":"$direct","referring_domain":"127.0.0.1:8888","initial_referring_domain":""}}', - ], - }, - }, - files: {}, - userId: '', - }, - metadata: { - jobId: 12, - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 48', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'test@rudderstack.com', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.0', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'track', - messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', - originalTimestamp: '2023-10-14T15:46:51.693229+05:30', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'order completed', - properties: { - category: ['clothing', 'fishing'], - order_id: 'rudderstackorder1', - total: 99.99, - revenue: 12.24, - shipping: 13.99, - tax: 20.99, - currency: 'INR', - products: [ - { - quantity: 1, - price: 24.75, - name: 'my product', - sku: 'p-298', - delivery_category: 'home_delivery', - }, - { - quantity: 3, - price: 24.75, - name: 'other product', - sku: 'p-299', - delivery_category: 'home_delivery', - }, - ], - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: true, - }, - ], - categoryToContent: [ - { - from: 'clothing', - to: 'product', - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - valueFieldIdentifier: 'properties.price', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","em":"1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd","client_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"},"event_name":"Purchase","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"category[0]":"clothing","category[1]":"fishing","order_id":"rudderstackorder1","total":99.99,"revenue":12.24,"shipping":13.99,"tax":20.99,"currency":"INR","products[0].quantity":1,"products[0].price":24.75,"products[0].name":"my product","products[0].sku":"p-298","products[0].delivery_category":"home_delivery","products[1].quantity":3,"products[1].price":24.75,"products[1].name":"other product","products[1].sku":"p-299","products[1].delivery_category":"home_delivery","content_category":"clothing,fishing","content_ids":["p-298","p-299"],"content_type":"product","value":12.24,"contents":[{"id":"p-298","quantity":1,"item_price":24.75,"delivery_category":"home_delivery"},{"id":"p-299","quantity":3,"item_price":24.75,"delivery_category":"home_delivery"}],"num_items":2}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 49', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - channel: 'mobile', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: ' aBc@gmail.com ', - address: { - zip: 1234, - }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - content_ids: ['prod1', 'prod2'], - }, - timestamp: '2023-10-14T00:00:00.693229+05:30', - type: 'track', - }, - destination: { - Config: { - limitedDataUsage: true, - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - removeExternalId: true, - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08","zp":"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4"},"event_name":"spin_result","event_time":1697221800,"action_source":"app","custom_data":{"additional_bet_index":0,"value":400,"content_ids":["prod1","prod2"]}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'facebook_pixel', - description: 'Test 50', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - channel: 'mobile', - destination_props: { - Fb: { - app_id: 'RudderFbApp', - }, - }, - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { - carrier: 'Banglalink', - }, - os: { - name: 'android', - version: '8.1.0', - }, - screen: { - height: '100', - density: 50, - }, - traits: { - email: ' aBc@gmail.com ', - address: { - zip: 1234, - }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { - All: true, - }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - revenue: 400, - additional_bet_index: 0, - contents: [ - { - id: 'prod1', - quantity: 5, - item_price: 55, - }, - ], - }, - timestamp: '2023-10-14T00:00:00.693229+05:30', - type: 'track', - }, - destination: { - Config: { - limitedDataUsage: true, - blacklistPiiProperties: [ - { - blacklistPiiProperties: '', - blacklistPiiHash: false, - }, - ], - accessToken: '09876', - pixelId: 'dummyPixelId', - eventsToEvents: [ - { - from: '', - to: '', - }, - ], - eventCustomProperties: [ - { - eventCustomProperties: '', - }, - ], - removeExternalId: true, - valueFieldIdentifier: '', - advancedMapping: false, - whitelistPiiProperties: [ - { - whitelistPiiProperties: '', - }, - ], - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, - headers: {}, - params: {}, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: { - data: [ - '{"user_data":{"em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08","zp":"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4"},"event_name":"spin_result","event_time":1697221800,"action_source":"app","custom_data":{"additional_bet_index":0,"value":400,"contents":[{"id":"prod1","quantity":5,"item_price":55}]}}', - ], - }, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, + ...identifyTestData, + ...trackTestData, + ...validationTestData, + ...pageScreenTestData, + ...ecommTestData, + ...configLevelFeaturesTestData, ].map((d) => ({ ...d, mockFns })); diff --git a/test/integrations/destinations/facebook_pixel/processor/ecommTestData.ts b/test/integrations/destinations/facebook_pixel/processor/ecommTestData.ts new file mode 100644 index 00000000000..5d429d297dc --- /dev/null +++ b/test/integrations/destinations/facebook_pixel/processor/ecommTestData.ts @@ -0,0 +1,1120 @@ +import { VERSION } from '../../../../../src/v0/destinations/facebook_pixel/config'; +import { generateTrackPayload, generateMetadata, transformResultBuilder } from '../../../testUtils'; +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; + +const commonDestination: Destination = { + ID: '12335', + Name: 'sample-destination', + DestinationDefinition: { + ID: '123', + Name: 'facebook_pixel', + DisplayName: 'Facebook Pixel', + Config: {}, + }, + WorkspaceID: '123', + Transformations: [], + Config: { + blacklistPiiProperties: [ + { + blacklistPiiProperties: '', + blacklistPiiHash: false, + }, + ], + accessToken: '09876', + pixelId: 'dummyPixelId', + eventsToEvents: [ + { + from: 'ABC Started', + to: 'InitiateCheckout', + }, + ], + eventCustomProperties: [ + { + eventCustomProperties: '', + }, + ], + valueFieldIdentifier: '', + advancedMapping: false, + whitelistPiiProperties: [ + { + whitelistPiiProperties: 'email', + }, + ], + }, + Enabled: true, +}; + +const commonUserTraits = { + email: 'abc@gmail.com', + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + event_id: '12345', +}; + +const commonPropertiesWithoutProductArray = { + category: 'dummy', + quantity: 10, + value: 100, + product_id: '12345', +}; + +const commonPropertiesWithProductArray = { + products: [ + { + product_id: '017c6f5d5cf86a4b22432066', + sku: '8732-98', + name: 'Just Another Game', + price: 22, + position: 2, + category: 'Games and Entertainment', + url: 'https://www.myecommercewebsite.com/product', + image_url: 'https://www.myecommercewebsite.com/product/path.jpg', + }, + { + product_id: '89ac6f5d5cf86a4b64eac145', + sku: '1267-01', + name: 'Wrestling Trump Cards', + price: 4, + position: 21, + category: 'Card Games', + }, + ], + category: 'dummy', + quantity: 10, + revenue: 100, + price: 50, + product_id: '12345', + order_id: '23456', +}; +const commonTimestamp = new Date('2023-10-14'); +const commonStatTags = { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'FACEBOOK_PIXEL', + module: 'destination', + implementation: 'native', + feature: 'processor', +}; + +export const ecommTestData: ProcessorTestData[] = [ + { + id: 'facebook_pixel-ecomm-test-1', + name: 'facebook_pixel', + description: + 'Track call : product list viewed event call with properties without product array', + scenario: 'ecommerce', + successCriteria: + 'It should be internally mapped to ViewContent, with necessary mapping from message.properties and should be sent to the destination', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'product list viewed', + properties: commonPropertiesWithoutProductArray, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'ViewContent', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + category: 'dummy', + quantity: 10, + value: 100, + product_id: '12345', + content_ids: ['dummy'], + content_type: 'product_group', + contents: [ + { + id: 'dummy', + quantity: 1, + }, + ], + content_category: 'dummy', + currency: 'USD', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-ecomm-test-2', + name: 'facebook_pixel', + description: 'Track call : product list viewed event call with properties with product array', + successCriteria: + 'It should be internally mapped to ViewContent, with necessary mapping from message.properties and from products array and should be sent to the destination', + scenario: 'ecommerce', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'product list viewed', + properties: commonPropertiesWithProductArray, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://graph.facebook.com/v18.0/dummyPixelId/events?access_token=09876', + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'ViewContent', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + 'products[0].product_id': '017c6f5d5cf86a4b22432066', + 'products[0].sku': '8732-98', + 'products[0].name': 'Just Another Game', + 'products[0].price': 22, + 'products[0].position': 2, + 'products[0].category': 'Games and Entertainment', + 'products[0].url': 'https://www.myecommercewebsite.com/product', + 'products[0].image_url': + 'https://www.myecommercewebsite.com/product/path.jpg', + 'products[1].product_id': '89ac6f5d5cf86a4b64eac145', + 'products[1].sku': '1267-01', + 'products[1].name': 'Wrestling Trump Cards', + 'products[1].price': 4, + 'products[1].position': 21, + 'products[1].category': 'Card Games', + category: 'dummy', + quantity: 10, + revenue: 100, + price: 50, + product_id: '12345', + order_id: '23456', + content_ids: ['017c6f5d5cf86a4b22432066', '89ac6f5d5cf86a4b64eac145'], + content_type: 'product', + contents: [ + { + id: '017c6f5d5cf86a4b22432066', + quantity: 10, + item_price: 22, + }, + { + id: '89ac6f5d5cf86a4b64eac145', + quantity: 10, + item_price: 4, + }, + ], + content_category: 'dummy', + value: 0, + currency: 'USD', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-ecomm-test-3', + name: 'facebook_pixel', + description: 'Track call : product viewed event call with properties without product array', + scenario: 'ecommerce', + successCriteria: + 'It should be internally mapped to ViewContent, with necessary mapping from message.properties and should be sent to the destination', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'product viewed', + properties: commonPropertiesWithoutProductArray, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'ViewContent', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + category: 'dummy', + quantity: 10, + value: 0, + product_id: '12345', + content_ids: ['12345'], + content_type: 'product', + content_name: '', + content_category: 'dummy', + currency: 'USD', + contents: [ + { + id: '12345', + quantity: 10, + }, + ], + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-ecomm-test-4', + name: 'facebook_pixel', + description: 'Track call : product added event call with properties without product array', + scenario: 'ecommerce', + successCriteria: + 'It should be internally mapped to AddToCart, with necessary mapping from message.properties and should be sent to the destination', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'product added', + properties: commonPropertiesWithoutProductArray, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'AddToCart', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + category: 'dummy', + quantity: 10, + value: 0, + product_id: '12345', + content_ids: ['12345'], + content_type: 'product', + content_name: '', + content_category: 'dummy', + currency: 'USD', + contents: [ + { + id: '12345', + quantity: 10, + }, + ], + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-ecomm-test-5', + name: 'facebook_pixel', + description: 'Track call : order completed event call with properties without product array', + scenario: 'ecommerce', + successCriteria: + 'It should be internally mapped to purchase, with necessary mapping from message.properties and should be sent to the destination', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'order completed', + properties: commonPropertiesWithoutProductArray, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'Purchase', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + category: 'dummy', + quantity: 10, + value: 0, + product_id: '12345', + content_category: 'dummy', + content_ids: [], + content_type: 'product', + currency: 'USD', + contents: [], + num_items: 0, + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-ecomm-test-6', + name: 'facebook_pixel', + description: 'Track call : order completed event call with properties with product array', + scenario: 'ecommerce', + successCriteria: + 'It should be internally mapped to purchase, with necessary mapping from message.properties and should be sent to the destination', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'order completed', + properties: commonPropertiesWithProductArray, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://graph.facebook.com/v18.0/dummyPixelId/events?access_token=09876', + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'Purchase', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + 'products[0].product_id': '017c6f5d5cf86a4b22432066', + 'products[0].sku': '8732-98', + 'products[0].name': 'Just Another Game', + 'products[0].price': 22, + 'products[0].position': 2, + 'products[0].category': 'Games and Entertainment', + 'products[0].url': 'https://www.myecommercewebsite.com/product', + 'products[0].image_url': + 'https://www.myecommercewebsite.com/product/path.jpg', + 'products[1].product_id': '89ac6f5d5cf86a4b64eac145', + 'products[1].sku': '1267-01', + 'products[1].name': 'Wrestling Trump Cards', + 'products[1].price': 4, + 'products[1].position': 21, + 'products[1].category': 'Card Games', + category: 'dummy', + quantity: 10, + revenue: 100, + price: 50, + product_id: '12345', + order_id: '23456', + content_category: 'dummy', + content_ids: ['017c6f5d5cf86a4b22432066', '89ac6f5d5cf86a4b64eac145'], + content_type: 'product', + currency: 'USD', + value: 100, + contents: [ + { + id: '017c6f5d5cf86a4b22432066', + quantity: 10, + item_price: 22, + }, + { + id: '89ac6f5d5cf86a4b64eac145', + quantity: 10, + item_price: 4, + }, + ], + num_items: 2, + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-ecomm-test-7', + name: 'facebook_pixel', + description: 'Track call : products searched event call with properties', + scenario: 'ecommerce', + successCriteria: + 'It should be internally mapped to Search, with necessary mapping from message.properties and should be sent to the destination', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'products searched', + properties: { ...commonPropertiesWithoutProductArray, query: 'dummy' }, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'Search', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + category: 'dummy', + quantity: 10, + value: 100, + product_id: '12345', + query: 'dummy', + content_ids: ['12345'], + content_category: 'dummy', + contents: [ + { + id: '12345', + quantity: 10, + }, + ], + search_string: 'dummy', + currency: 'USD', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-ecomm-test-8', + name: 'facebook_pixel', + description: + 'Track call : products searched event call with properties and unsupported query type', + scenario: 'ecommerce', + successCriteria: + 'Error : It should throw an error as the query is not a string or an array of strings', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'products searched', + properties: { ...commonPropertiesWithoutProductArray, query: ['dummy'] }, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: "'query' should be in string format only", + statTags: { + ...commonStatTags, + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-ecomm-test-9', + name: 'facebook_pixel', + description: 'Track call : checkout started event call with properties without product array', + scenario: 'ecommerce', + successCriteria: + 'It should be internally mapped to InitiateCheckout, with necessary mapping from message.properties and should be sent to the destination', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'checkout started', + properties: commonPropertiesWithoutProductArray, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'InitiateCheckout', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + category: 'dummy', + quantity: 10, + value: 0, + product_id: '12345', + content_category: 'dummy', + content_ids: [], + content_type: 'product', + currency: 'USD', + contents: [], + num_items: 0, + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-ecomm-test-10', + name: 'facebook_pixel', + description: 'Track call : checkout started event call with properties with product array', + scenario: 'ecommerce', + successCriteria: + 'It should be internally mapped to InitiateCheckout, with necessary mapping from message.properties and should be sent to the destination', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'checkout started', + properties: commonPropertiesWithProductArray, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://graph.facebook.com/v18.0/dummyPixelId/events?access_token=09876', + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'InitiateCheckout', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + 'products[0].product_id': '017c6f5d5cf86a4b22432066', + 'products[0].sku': '8732-98', + 'products[0].name': 'Just Another Game', + 'products[0].price': 22, + 'products[0].position': 2, + 'products[0].category': 'Games and Entertainment', + 'products[0].url': 'https://www.myecommercewebsite.com/product', + 'products[0].image_url': + 'https://www.myecommercewebsite.com/product/path.jpg', + 'products[1].product_id': '89ac6f5d5cf86a4b64eac145', + 'products[1].sku': '1267-01', + 'products[1].name': 'Wrestling Trump Cards', + 'products[1].price': 4, + 'products[1].position': 21, + 'products[1].category': 'Card Games', + category: 'dummy', + quantity: 10, + revenue: 100, + price: 50, + product_id: '12345', + order_id: '23456', + content_category: 'dummy', + content_ids: ['017c6f5d5cf86a4b22432066', '89ac6f5d5cf86a4b64eac145'], + content_type: 'product', + currency: 'USD', + value: 100, + contents: [ + { + id: '017c6f5d5cf86a4b22432066', + quantity: 10, + item_price: 22, + }, + { + id: '89ac6f5d5cf86a4b64eac145', + quantity: 10, + item_price: 4, + }, + ], + num_items: 2, + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-ecomm-test-11', + name: 'facebook_pixel', + description: + 'Track call : custom event ABC Started event call with properties with product array', + scenario: 'ecommerce', + successCriteria: + 'It should be internally mapped to InitiateCheckout, with necessary mapping from message.properties and should be sent to the destination', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'ABC Started', + properties: commonPropertiesWithProductArray, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'InitiateCheckout', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + 'products[0].product_id': '017c6f5d5cf86a4b22432066', + 'products[0].sku': '8732-98', + 'products[0].name': 'Just Another Game', + 'products[0].price': 22, + 'products[0].position': 2, + 'products[0].category': 'Games and Entertainment', + 'products[0].url': 'https://www.myecommercewebsite.com/product', + 'products[0].image_url': + 'https://www.myecommercewebsite.com/product/path.jpg', + 'products[1].product_id': '89ac6f5d5cf86a4b64eac145', + 'products[1].sku': '1267-01', + 'products[1].name': 'Wrestling Trump Cards', + 'products[1].price': 4, + 'products[1].position': 21, + 'products[1].category': 'Card Games', + category: 'dummy', + quantity: 10, + revenue: 100, + price: 50, + product_id: '12345', + order_id: '23456', + content_category: 'dummy', + content_ids: ['017c6f5d5cf86a4b22432066', '89ac6f5d5cf86a4b64eac145'], + content_type: 'product', + currency: 'USD', + value: 100, + contents: [ + { + id: '017c6f5d5cf86a4b22432066', + quantity: 10, + item_price: 22, + }, + { + id: '89ac6f5d5cf86a4b64eac145', + quantity: 10, + item_price: 4, + }, + ], + num_items: 2, + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-ecomm-test-12', + name: 'facebook_pixel', + description: + 'Track call : product list viewed event call with properties without product array and revenue as string', + scenario: 'ecommerce', + successCriteria: + 'Error : It should throw an error as revenue is not a number and should not be sent to the destination', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'product list viewed', + properties: { ...commonPropertiesWithoutProductArray, value: '$20' }, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Revenue could not be converted to number', + metadata: generateMetadata(1), + statTags: { + ...commonStatTags, + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + statusCode: 400, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/facebook_pixel/processor/identifyTestData.ts b/test/integrations/destinations/facebook_pixel/processor/identifyTestData.ts new file mode 100644 index 00000000000..d315b03cead --- /dev/null +++ b/test/integrations/destinations/facebook_pixel/processor/identifyTestData.ts @@ -0,0 +1,209 @@ +import { VERSION } from '../../../../../src/v0/destinations/facebook_pixel/config'; +import { Destination } from '../../../../../src/types'; +import { generateMetadata, transformResultBuilder, overrideDestination } from '../../../testUtils'; +import { ProcessorTestData } from '../../../testTypes'; + +const commonDestination: Destination = { + ID: '12335', + Name: 'sample-destination', + DestinationDefinition: { + ID: '123', + Name: 'facebook_pixel', + DisplayName: 'Facebook Pixel', + Config: {}, + }, + WorkspaceID: '123', + Transformations: [], + Config: { + blacklistPiiProperties: [ + { + blacklistPiiProperties: '', + blacklistPiiHash: false, + }, + ], + accessToken: '09876', + pixelId: 'dummyPixelId', + eventsToEvents: [ + { + from: '', + to: '', + }, + ], + eventCustomProperties: [ + { + eventCustomProperties: '', + }, + ], + valueFieldIdentifier: '', + advancedMapping: true, + whitelistPiiProperties: [ + { + whitelistPiiProperties: '', + }, + ], + }, + Enabled: true, +}; +const commonMessage = { + channel: 'web', + context: { + traits: { + name: 'Rudder Test', + email: 'abc@gmail.com', + firstname: 'Rudder', + lastname: 'Test', + phone: 9000000000, + gender: 'female', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2023-10-14T15:46:51.693229+05:30', + anonymousId: '00000000000000000000000000', + userId: '123456', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', +}; +const commonStatTags = { + errorCategory: 'dataValidation', + errorType: 'configuration', + destType: 'FACEBOOK_PIXEL', + module: 'destination', + implementation: 'native', + feature: 'processor', +}; + +export const identifyTestData: ProcessorTestData[] = [ + { + id: 'fbPixel-identify-test-1', + name: 'facebook_pixel', + description: '[Error]: Check if advancedMapping configuration is enabled', + scenario: 'Framework', + successCriteria: + 'Response should contain error message and status code should be 400, we are sending identify event with advancedMapping disabled', + module: 'destination', + feature: 'processor', + version: 'v0', + input: { + request: { + body: [ + { + message: commonMessage, + metadata: generateMetadata(1), + destination: overrideDestination(commonDestination, { advancedMapping: false }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: + 'For identify events, "Advanced Mapping" configuration must be enabled on the RudderStack dashboard', + statTags: { + ...commonStatTags, + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'fbPixel-identify-test-2', + name: 'facebook_pixel', + description: 'Identify event happy flow : without integrations object hashed true', + scenario: 'Business', + successCriteria: + ' Response should contain status code 200 and body should contain unhashed user traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: commonMessage, + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + ph: '593a6d58f34eb5c3de4f47e38d1faaa7d389fafe332a85400b1e54498391c579', + ge: '252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111', + ln: '532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25', + fn: '2c2ccf28d806f6f9a34b67aa874d2113b7ac1444f1a4092541b8b75b84771747', + client_ip_address: '0.0.0.0', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + }, + event_name: 'identify', + event_time: 1697278611, + event_id: '84e26acc-56a5-4835-8233-591137fca468', + action_source: 'website', + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/facebook_pixel/processor/pageScreenTestData.ts b/test/integrations/destinations/facebook_pixel/processor/pageScreenTestData.ts new file mode 100644 index 00000000000..dee772522ab --- /dev/null +++ b/test/integrations/destinations/facebook_pixel/processor/pageScreenTestData.ts @@ -0,0 +1,721 @@ +import { VERSION } from '../../../../../src/v0/destinations/facebook_pixel/config'; +import { + generateSimplifiedPageOrScreenPayload, + overrideDestination, + generateMetadata, + transformResultBuilder, +} from '../../../testUtils'; +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; + +const commonDestination: Destination = { + ID: '12335', + Name: 'sample-destination', + DestinationDefinition: { + ID: '123', + Name: 'facebook_pixel', + DisplayName: 'Facebook Pixel', + Config: {}, + }, + WorkspaceID: '123', + Transformations: [], + Config: { + blacklistPiiProperties: [ + { + blacklistPiiProperties: 'phone', + blacklistPiiHash: true, + }, + ], + accessToken: '09876', + pixelId: 'dummyPixelId', + eventsToEvents: [ + { + from: '', + to: '', + }, + ], + eventCustomProperties: [ + { + eventCustomProperties: '', + }, + ], + valueFieldIdentifier: '', + advancedMapping: false, + whitelistPiiProperties: [ + { + whitelistPiiProperties: 'email', + }, + ], + }, + Enabled: true, +}; +const commonMessage = { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'page', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + timestamp: '2023-10-14T15:46:51.693229+05:30', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + path: '/abc', + referrer: 'xyz', + search: 'def', + title: 'ghi', + url: 'jkl', + }, + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2019-10-14T11:15:53.296Z', +}; + +const commonPageMessage = { ...commonMessage, type: 'page' }; + +const commonScreenMessage = { ...commonMessage, type: 'screen' }; + +const commonStatTags = { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'FACEBOOK_PIXEL', + module: 'destination', + implementation: 'native', + feature: 'processor', +}; + +export const pageScreenTestData: ProcessorTestData[] = [ + { + id: 'facebook_pixel-page-test-1', + name: 'facebook_pixel', + description: + 'Page call : Happy flow without standard page switched on and with name and properties', + scenario: 'Page', + successCriteria: 'Response should contain status code 200 and no error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateSimplifiedPageOrScreenPayload( + { + event: 'TestEven001', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + context: { + traits: { + email: 'abc@example.com', + }, + }, + properties: { + path: '/abc', + referrer: 'xyz', + search: 'def', + title: 'ghi', + url: 'jkl', + }, + name: 'ApplicationLoaded', + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2023-10-14T15:32:56.409Z', + }, + 'page', + ), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '470582f368e5aeec2cf487decd1e125b7d265e8b0b06b74a25e999e93bfb699f', + em: '9eceb13483d7f187ec014fd6d4854d1420cfc634328af85f51d0323ba8622e21', + }, + event_name: 'Viewed page ApplicationLoaded', + event_time: 1697297576, + event_source_url: 'jkl', + action_source: 'website', + custom_data: { + path: '/abc', + referrer: 'xyz', + search: 'def', + title: 'ghi', + url: 'jkl', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-page-test-2', + name: 'facebook_pixel', + description: 'Page call : with standard page switched on and no properties and no name', + scenario: 'Page', + successCriteria: + 'Response should contain error message and status code should be 400, as we are not sending any other properties other than standard page properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateSimplifiedPageOrScreenPayload( + { + event: 'TestEven001', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + context: { + traits: { + email: 'abc@example.com', + }, + }, + properties: {}, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2023-10-14T15:32:56.409Z', + }, + 'page', + ), + metadata: generateMetadata(1), + destination: overrideDestination(commonDestination, { standardPageCall: true }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + "After excluding opt_out,event_id,action_source, no fields are present in 'properties' for a standard event", + metadata: generateMetadata(1), + statTags: { + ...commonStatTags, + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-page-test-3', + name: 'facebook_pixel', + description: 'Page call : with standard page switched on and properties', + scenario: 'Page', + successCriteria: 'Response should contain status code 200 and no error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateSimplifiedPageOrScreenPayload( + { + event: 'TestEven001', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + context: { + traits: { + email: 'abc@example.com', + }, + }, + properties: { + path: '/abc', + referrer: 'xyz', + search: 'def', + title: 'ghi', + url: 'jkl', + }, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2023-10-14T15:32:56.409Z', + }, + 'page', + ), + metadata: generateMetadata(1), + destination: overrideDestination(commonDestination, { standardPageCall: true }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '470582f368e5aeec2cf487decd1e125b7d265e8b0b06b74a25e999e93bfb699f', + em: '9eceb13483d7f187ec014fd6d4854d1420cfc634328af85f51d0323ba8622e21', + }, + event_name: 'PageView', + event_time: 1697297576, + event_source_url: 'jkl', + action_source: 'website', + custom_data: { + path: '/abc', + referrer: 'xyz', + search: 'def', + title: 'ghi', + url: 'jkl', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-page-test-4', + name: 'facebook_pixel', + description: 'Page call : with standard page switched off and with properties but no page name', + scenario: 'Page', + successCriteria: 'Response should contain status code 200 and no error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateSimplifiedPageOrScreenPayload( + { + event: 'TestEven001', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + context: { + traits: {}, + }, + properties: { + path: '/abc', + referrer: 'xyz', + search: 'def', + title: 'ghi', + url: 'jkl', + }, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2023-10-14T15:32:56.409Z', + }, + 'page', + ), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '470582f368e5aeec2cf487decd1e125b7d265e8b0b06b74a25e999e93bfb699f', + }, + event_name: 'PageView', + event_time: 1697297576, + event_source_url: 'jkl', + action_source: 'website', + custom_data: { + path: '/abc', + referrer: 'xyz', + search: 'def', + title: 'ghi', + url: 'jkl', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-screen-test-1', + name: 'facebook_pixel', + description: + 'Screen call : Happy flow without standard page switched on and with name and properties', + scenario: 'Screen', + successCriteria: 'Response should contain status code 200 and no error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateSimplifiedPageOrScreenPayload( + { + event: 'TestEven001', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + context: { + traits: {}, + }, + properties: { + path: '/abc', + referrer: 'xyz', + search: 'def', + title: 'ghi', + url: 'jkl', + }, + anonymousId: '9c6bd77ea9da3e68', + name: 'ApplicationLoaded', + originalTimestamp: '2023-10-14T15:32:56.409Z', + }, + 'screen', + ), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '470582f368e5aeec2cf487decd1e125b7d265e8b0b06b74a25e999e93bfb699f', + }, + event_name: 'PageView', + event_time: 1697297576, + event_source_url: 'jkl', + action_source: 'website', + custom_data: { + path: '/abc', + referrer: 'xyz', + search: 'def', + title: 'ghi', + url: 'jkl', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-screen-test-2', + name: 'facebook_pixel', + description: 'Screen call : with standard page switched on and no properties and no name', + scenario: 'Screen', + successCriteria: + 'Response should contain error message and status code should be 400, as we are not sending any other properties other than standard page properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateSimplifiedPageOrScreenPayload( + { + event: 'TestEven001', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + context: { + traits: {}, + }, + properties: {}, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2023-10-14T15:32:56.409Z', + }, + 'screen', + ), + metadata: generateMetadata(1), + destination: overrideDestination(commonDestination, { standardPageCall: true }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + "After excluding opt_out,event_id,action_source, no fields are present in 'properties' for a standard event", + statTags: { + ...commonStatTags, + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + metadata: generateMetadata(1), + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-screen-test-3', + name: 'facebook_pixel', + description: 'Screen call : with standard page switched on and properties', + scenario: 'Screen', + successCriteria: 'Response should contain status code 200 and no error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateSimplifiedPageOrScreenPayload( + { + event: 'TestEven001', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + context: { + traits: {}, + }, + properties: { + path: '/abc', + referrer: 'xyz', + search: 'def', + title: 'ghi', + url: 'jkl', + }, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2023-10-14T15:32:56.409Z', + }, + 'screen', + ), + metadata: generateMetadata(1), + destination: overrideDestination(commonDestination, { standardPageCall: true }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '470582f368e5aeec2cf487decd1e125b7d265e8b0b06b74a25e999e93bfb699f', + }, + event_name: 'PageView', + event_time: 1697297576, + event_source_url: 'jkl', + action_source: 'website', + custom_data: { + path: '/abc', + referrer: 'xyz', + search: 'def', + title: 'ghi', + url: 'jkl', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'facebook_pixel-screen-test-4', + name: 'facebook_pixel', + description: + 'Screen call : with standard page switched off and with properties but no page name', + scenario: 'Screen', + successCriteria: 'Response should contain status code 200 and no error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateSimplifiedPageOrScreenPayload( + { + event: 'TestEven001', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + context: { + traits: {}, + }, + properties: { + path: '/abc', + referrer: 'xyz', + search: 'def', + title: 'ghi', + url: 'jkl', + }, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2023-10-14T15:32:56.409Z', + }, + 'screen', + ), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '470582f368e5aeec2cf487decd1e125b7d265e8b0b06b74a25e999e93bfb699f', + }, + event_name: 'PageView', + event_time: 1697297576, + event_source_url: 'jkl', + action_source: 'website', + custom_data: { + path: '/abc', + referrer: 'xyz', + search: 'def', + title: 'ghi', + url: 'jkl', + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/facebook_pixel/processor/trackTestData.ts b/test/integrations/destinations/facebook_pixel/processor/trackTestData.ts new file mode 100644 index 00000000000..9fd65945c4d --- /dev/null +++ b/test/integrations/destinations/facebook_pixel/processor/trackTestData.ts @@ -0,0 +1,208 @@ +import { VERSION } from '../../../../../src/v0/destinations/facebook_pixel/config'; +import { generateMetadata, generateTrackPayload, transformResultBuilder } from '../../../testUtils'; +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; + +const commonDestination: Destination = { + ID: '12335', + Name: 'sample-destination', + DestinationDefinition: { + ID: '123', + Name: 'facebook_pixel', + DisplayName: 'Facebook Pixel', + Config: {}, + }, + WorkspaceID: '123', + Transformations: [], + Config: { + blacklistPiiProperties: [ + { + blacklistPiiProperties: '', + blacklistPiiHash: false, + }, + ], + accessToken: '09876', + pixelId: 'dummyPixelId', + eventsToEvents: [ + { + from: '', + to: '', + }, + ], + eventCustomProperties: [ + { + eventCustomProperties: '', + }, + ], + valueFieldIdentifier: '', + advancedMapping: false, + whitelistPiiProperties: [ + { + whitelistPiiProperties: 'email', + }, + ], + }, + Enabled: true, +}; + +const commonUserTraits = { + email: 'abc@gmail.com', + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + event_id: '12345', +}; + +const commonUserProperties = { + revenue: 400, + additional_bet_index: 0, + email: 'abc@gmail.com', +}; + +const commonTimestamp = new Date('2023-10-14'); + +export const trackTestData: ProcessorTestData[] = [ + { + id: 'fbPixel-track-test-1', + name: 'facebook_pixel', + description: 'Track call : custom event calls with simple user properties and traits', + scenario: 'Business', + successCriteria: + 'event not respecting the internal mapping and as well as UI mapping should be considered as a custom event and should be sent as it is', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'spin_result', + properties: commonUserProperties, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'spin_result', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + additional_bet_index: 0, + email: 'abc@gmail.com', + value: 400, + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'fbPixel-track-test-2', + name: 'facebook_pixel', + description: + 'Track call : other standard type event calls with simple user properties and traits', + scenario: 'Business', + successCriteria: + 'event not respecting the internal mapping and as well as UI mapping but falls under other standard events, should be considered as a simple track event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'AddToWishlist', + properties: commonUserProperties, + context: { + traits: commonUserTraits, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, + headers: {}, + params: {}, + FORM: { + data: [ + JSON.stringify({ + user_data: { + external_id: + '3ffc8a075f330402d82aa0a86c596b0d2fe70df38b22c5be579f86a18e4aca47', + em: '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + client_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + event_name: 'AddToWishlist', + event_time: 1697241600, + event_id: '12345', + action_source: 'website', + custom_data: { + additional_bet_index: 0, + email: 'abc@gmail.com', + value: 400, + }, + }), + ], + }, + files: {}, + userId: '', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/facebook_pixel/processor/validationTestData.ts b/test/integrations/destinations/facebook_pixel/processor/validationTestData.ts new file mode 100644 index 00000000000..8e248014642 --- /dev/null +++ b/test/integrations/destinations/facebook_pixel/processor/validationTestData.ts @@ -0,0 +1,373 @@ +import { Destination } from '../../../../../src/types'; +import { + generateMetadata, + generateSimplifiedGroupPayload, + generateSimplifiedTrackPayload, + generateTrackPayload, + overrideDestination, +} from '../../../testUtils'; +const commonTimestamp = new Date('2023-10-12'); +const commonDestination: Destination = { + ID: '12335', + Name: 'sample-destination', + DestinationDefinition: { + ID: '123', + Name: 'facebook_pixel', + DisplayName: 'Facebook Pixel', + Config: {}, + }, + WorkspaceID: '123', + Transformations: [], + Config: { + limitedDataUsage: true, + blacklistPiiProperties: [ + { + blacklistPiiProperties: '', + blacklistPiiHash: false, + }, + ], + eventsToEvents: [ + { + from: '', + to: '', + }, + ], + eventCustomProperties: [ + { + eventCustomProperties: '', + }, + ], + removeExternalId: true, + valueFieldIdentifier: '', + advancedMapping: true, + whitelistPiiProperties: [ + { + whitelistPiiProperties: '', + }, + ], + }, + Enabled: true, +}; + +const commonStatTags = { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'FACEBOOK_PIXEL', + module: 'destination', + implementation: 'native', + feature: 'processor', +}; + +export const validationTestData = [ + { + id: 'fbPixel-validation-test-1', + name: 'facebook_pixel', + description: '[Error]: Check for unsupported message type', + scenario: 'Framework', + successCriteria: + 'Response should contain error message and status code should be 400, as we are sending a message type which is not supported by facebook pixel destination and the error message should be Event type random is not supported', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: overrideDestination(commonDestination, { + accessToken: '09876', + pixelId: 'dummyPixelId', + }), + message: generateSimplifiedGroupPayload({ + userId: 'user123', + groupId: 'XUepkK', + traits: { + subscribe: true, + }, + context: { + traits: { + email: 'test@rudderstack.com', + phone: '+12 345 678 900', + consent: ['email'], + }, + }, + timestamp: '2023-10-14T00:21:34.208Z', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Message type group not supported', + statTags: commonStatTags, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'fbPixel-validation-test-2', + name: 'facebook_pixel', + description: + 'Track call : error in instrumentation as pixel id is not mentioned in destination object', + scenario: 'Business', + successCriteria: + 'Error: Pixel Id not found. Aborting, as we are sending an event without pixel id and the status code should be 400', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'spin_result', + properties: { + revenue: 400, + additional_bet_index: 0, + }, + context: { + traits: { + email: 'abc@gmail.com', + }, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: commonDestination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Pixel Id not found. Aborting', + metadata: generateMetadata(1), + statTags: { + ...commonStatTags, + destinationId: 'default-destinationId', + errorType: 'configuration', + workspaceId: 'default-workspaceId', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'fbPixel-validation-test-3', + name: 'facebook_pixel', + description: 'Track call : custom event calls with simple user properties and traits', + scenario: 'Business', + successCriteria: + 'event not respecting the internal mapping and as well as UI mapping should be considered as a custom event and should be sent as it is', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateTrackPayload({ + event: 'spin_result', + properties: { + revenue: 400, + additional_bet_index: 0, + }, + context: { + traits: { + email: 'abc@gmail.com', + }, + }, + timestamp: commonTimestamp, + }), + metadata: generateMetadata(1), + destination: overrideDestination(commonDestination, { + pixelId: 'dummyPixelId', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Access token not found. Aborting', + metadata: generateMetadata(1), + statTags: { + ...commonStatTags, + destinationId: 'default-destinationId', + errorType: 'configuration', + workspaceId: 'default-workspaceId', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'fbPixel-validation-test-3', + name: 'facebook_pixel', + description: '[Error]: validate event date and time', + scenario: 'Framework + business', + successCriteria: + 'Response should contain error message and status code should be 400, as we are sending an event which is older than 7 days and the error message should be Events must be sent within seven days of their occurrence or up to one minute in the future.', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: generateSimplifiedTrackPayload({ + type: 'track', + event: 'TestEven001', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + context: { + traits: { + email: 'test@rudderstack.com', + phone: '9112340375', + plan_details: { + plan_type: 'gold', + duration: '3 months', + }, + }, + }, + properties: { + revenue: 400, + additional_bet_index: 0, + }, + anonymousId: '9c6bd77ea9da3e68', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }), + destination: overrideDestination(commonDestination, { + accessToken: '09876', + pixelId: 'dummyPixelId', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: + 'Events must be sent within seven days of their occurrence or up to one minute in the future.', + statTags: commonStatTags, + }, + ], + }, + }, + }, + { + id: 'fbPixel-validation-test-4', + name: 'facebook_pixel', + description: + 'Track call : error in instrumentation as event name is not mentioned in track call', + scenario: 'Business', + successCriteria: + 'event not respecting the internal mapping and as well as UI mapping should be considered as a custom event and should be sent as it is', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + properties: { + revenue: 400, + additional_bet_index: 0, + }, + }, + metadata: generateMetadata(1), + destination: overrideDestination(commonDestination, { + pixelId: 'dummyPixelId', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: "'event' is required", + metadata: generateMetadata(1), + statTags: { + ...commonStatTags, + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'fbPixel-validation-test-4', + name: 'facebook_pixel', + description: 'Track call : error in instrumentation as event name is not a string', + scenario: 'Business', + successCriteria: + 'Error message should be event name should be string and status code should be 400, as we are sending an event which is not a string', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 1234, + properties: { + revenue: 400, + additional_bet_index: 0, + }, + }, + metadata: generateMetadata(1), + destination: overrideDestination(commonDestination, { + pixelId: 'dummyPixelId', + }), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'event name should be string', + metadata: generateMetadata(1), + statTags: { + ...commonStatTags, + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, + statusCode: 400, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/fb/dataDelivery/business.ts b/test/integrations/destinations/fb/dataDelivery/business.ts new file mode 100644 index 00000000000..156dc265725 --- /dev/null +++ b/test/integrations/destinations/fb/dataDelivery/business.ts @@ -0,0 +1,226 @@ +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; +import { ProxyV1TestData } from '../../../testTypes'; +import { VERSION } from '../../../../../src/v0/destinations/fb/config'; + +export const testData1 = { + event: 'CUSTOM_APP_EVENTS', + advertiser_id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + 'ud[em]': '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + 'ud[fn]': '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', + 'ud[ge]': '62c66a7a5dd70c3146618063c344e531e6d4b59e379808443ce962b3abd63c5a', + 'ud[ln]': '3547cb112ac4489af2310c0626cdba6f3097a2ad5a3b42ddd3b59c76c7a079a3', + 'ud[ph]': '588211a01b10feacbf7988d97a06e86c18af5259a7f457fd8759b7f7409a7d1f', + extinfo: + '["a2","","","","8.1.0","Redmi 6","","","Banglalink",640,480,"1.23",0,0,0,"Europe/Berlin"]', + app_user_id: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + custom_events: + '[{"_logTime":1567333011693,"_eventName":"spin_result","_valueToSum":400,"fb_currency":"GBP","additional_bet_index":0,"battle_id":"N/A","bet_amount":9,"bet_level":1,"bet_multiplier":1,"coin_balance":9466052,"current_module_name":"CasinoGameModule","days_in_game":0,"extra_param":"N/A","fb_profile":"0","featureGameType":"N/A","game_fps":30,"game_id":"fireEagleBase","game_name":"FireEagleSlots","gem_balance":0,"graphicsQuality":"HD","idfa":"2bf99787-33d2-4ae2-a76a-c49672f97252","internetReachability":"ReachableViaLocalAreaNetwork","isLowEndDevice":"False","is_auto_spin":"False","is_turbo":"False","isf":"False","ishighroller":"False","jackpot_win_amount":90,"jackpot_win_type":"Silver","level":6,"lifetime_gem_balance":0,"no_of_spin":1,"player_total_battles":0,"player_total_shields":0,"start_date":"2019-08-01","total_payments":0,"tournament_id":"T1561970819","userId":"c82cbdff-e5be-4009-ac78-cdeea09ab4b1","versionSessionCount":2,"win_amount":0,"fb_content_id":["123","345","567"]}]', + advertiser_tracking_enabled: '0', + application_tracking_enabled: '0', +}; + +export const testData2 = { + extinfo: '["a2","","","","8.1.0","Redmi 6","","","Banglalink",0,100,"50.00",0,0,0,""]', + custom_events: + '[{"_logTime":1567333011693,"_eventName":"Viewed Screen","fb_description":"Main.1233"}]', + 'ud[em]': '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + advertiser_tracking_enabled: '0', + application_tracking_enabled: '0', + event: 'CUSTOM_APP_EVENTS', +}; + +export const statTags = { + destType: 'FB', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', +}; + +export const testScenariosForV1API: ProxyV1TestData[] = [ + { + id: 'fb_v1_scenario_1', + name: 'fb', + description: 'app event fails due to access token error', + successCriteria: 'Should return 400 with invalid access token error', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities?access_token=invalid_access_token`, + headers: { + 'x-forwarded-for': '1.2.3.4', + }, + params: { + destination: 'fb', + }, + FORM: testData1, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'Invalid OAuth 2.0 access token', + statTags: { + ...statTags, + errorCategory: 'dataValidation', + errorType: 'configuration', + meta: 'accessTokenExpired', + }, + response: [ + { + error: 'Invalid OAuth 2.0 access token', + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'fb_v1_scenario_2', + name: 'fb', + description: 'app event sent successfully', + successCriteria: 'Should return 200', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities?access_token=my_access_token`, + headers: { + 'x-forwarded-for': '1.2.3.4', + }, + params: { + destination: 'fb', + }, + FORM: testData1, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + response: [ + { + error: '{"events_received":1,"fbtrace_id":"facebook_trace_id"}', + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'fb_v1_scenario_3', + name: 'fb', + description: 'app event fails due to invalid timestamp', + successCriteria: 'Should return 400 with invalid timestamp error', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_timestamp_correct_access_token`, + headers: { + 'x-forwarded-for': '1.2.3.4', + }, + params: { + destination: 'fb', + }, + FORM: testData1, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'Event Timestamp Too Old', + statTags, + response: [ + { + error: 'Event Timestamp Too Old', + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'fb_v1_scenario_4', + name: 'fb', + description: 'app event fails due to missing permissions', + successCriteria: 'Should return 400 with missing permissions error', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_account_id_valid_access_token`, + headers: { + 'x-forwarded-for': '1.2.3.4', + }, + params: { + destination: 'fb', + }, + FORM: testData2, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: + "Object with ID 'PIXEL_ID' / 'DATASET_ID' / 'AUDIENCE_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", + statTags, + response: [ + { + error: + "Object with ID 'PIXEL_ID' / 'DATASET_ID' / 'AUDIENCE_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/fb/dataDelivery/data.ts b/test/integrations/destinations/fb/dataDelivery/data.ts index f9405ba4b30..9ee19af265c 100644 --- a/test/integrations/destinations/fb/dataDelivery/data.ts +++ b/test/integrations/destinations/fb/dataDelivery/data.ts @@ -1,6 +1,8 @@ import { VERSION } from '../../../../../src/v0/destinations/fb/config'; +import { testScenariosForV1API } from './business'; +import { otherScenariosV1 } from './other'; -export const data = [ +export const existingTestData = [ { name: 'fb', description: 'Test 0', @@ -57,19 +59,20 @@ export const data = [ message: 'Invalid OAuth 2.0 access token', destinationResponse: { error: { - message: 'The access token could not be decrypted', - type: 'OAuthException', code: 190, fbtrace_id: 'fbpixel_trace_id', + message: 'The access token could not be decrypted', + type: 'OAuthException', }, status: 500, }, statTags: { destType: 'FB', - errorCategory: 'network', + errorCategory: 'dataValidation', destinationId: 'Non-determininable', workspaceId: 'Non-determininable', - errorType: 'aborted', + errorType: 'configuration', + meta: 'accessTokenExpired', feature: 'dataDelivery', implementation: 'native', module: 'destination', @@ -370,3 +373,5 @@ export const data = [ }, }, ]; + +export const data = [...existingTestData, ...testScenariosForV1API, ...otherScenariosV1]; diff --git a/test/integrations/destinations/fb/dataDelivery/other.ts b/test/integrations/destinations/fb/dataDelivery/other.ts new file mode 100644 index 00000000000..9ac3f14fb54 --- /dev/null +++ b/test/integrations/destinations/fb/dataDelivery/other.ts @@ -0,0 +1,51 @@ +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; +import { ProxyV1TestData } from '../../../testTypes'; +import { VERSION } from '../../../../../src/v0/destinations/fb/config'; +import { testData2 as testData, statTags } from './business'; + +export const otherScenariosV1: ProxyV1TestData[] = [ + { + id: 'fb_v1_other_scenario_1', + name: 'fb', + description: 'user update request is throttled due to too many calls', + successCriteria: 'Should return 429 with message there have been too many calls', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=throttled_valid_access_token`, + params: { + destination: 'fb', + }, + FORM: testData, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 429, + message: 'API User Too Many Calls', + statTags: { + ...statTags, + errorType: 'throttled', + }, + response: [ + { + error: 'API User Too Many Calls', + statusCode: 429, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/fb/network.ts b/test/integrations/destinations/fb/network.ts index 1a2f114d74c..31bbaf0b6ee 100644 --- a/test/integrations/destinations/fb/network.ts +++ b/test/integrations/destinations/fb/network.ts @@ -12,7 +12,7 @@ const fbPixelTcs = data return nw.httpReq.url === fbendpoint; })[0]; const clonedFbpTc = cloneDeep(fbpTc); - const clonedFormData = cloneDeep(d.input.request.body.body.FORM); + const clonedFormData = cloneDeep(d.input.request.body.body?.FORM); clonedFbpTc.httpReq.data = getFormData(clonedFormData).toString(); return clonedFbpTc; }); @@ -21,7 +21,7 @@ export const networkCallsData = [ { httpReq: { url: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities?access_token=invalid_access_token`, - data: getFormData(data[0].input.request.body.body.FORM).toString(), + data: getFormData(data[0].input.request.body.body?.FORM).toString(), params: { destination: 'fb' }, headers: { 'User-Agent': 'RudderLabs' }, method: 'POST', @@ -41,7 +41,7 @@ export const networkCallsData = [ { httpReq: { url: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities?access_token=my_access_token`, - data: getFormData(data[1].input.request.body.body.FORM).toString(), + data: getFormData(data[1].input.request.body.body?.FORM).toString(), params: { destination: 'fb' }, headers: { 'x-forwarded-for': '1.2.3.4', 'User-Agent': 'RudderLabs' }, method: 'POST', diff --git a/test/integrations/destinations/fb_custom_audience/dataDelivery/business.ts b/test/integrations/destinations/fb_custom_audience/dataDelivery/business.ts new file mode 100644 index 00000000000..c48ad227ab7 --- /dev/null +++ b/test/integrations/destinations/fb_custom_audience/dataDelivery/business.ts @@ -0,0 +1,427 @@ +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; +import { ProxyV1TestData } from '../../../testTypes'; +import { getEndPoint } from '../../../../../src/v0/destinations/fb_custom_audience/config'; + +export const statTags = { + destType: 'FB_CUSTOM_AUDIENCE', + destinationId: 'default-destinationId', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'default-workspaceId', +}; + +const testParams1 = { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, +}; + +export const testParams2 = { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: ['DOBY', 'PHONE', 'GEN', 'FI', 'MADID', 'ZIP', 'ST', 'COUNTRY'], + data: [['2013', '@09432457768', 'f', 'Ms.', 'ABC', 'ZIP ', '123abc ', 'IN']], + }, +}; + +const testParams3 = { + access_token: 'BCD', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: ['DOBM', 'DOBD', 'DOBY', 'PHONE', 'GEN', 'FI', 'MADID', 'ZIP', 'ST', 'COUNTRY'], + data: [['2', '13', '2013', '@09432457768', 'f', 'Ms.', 'ABC', 'ZIP ', '123abc ', 'IN']], + }, +}; + +export const testScenariosForV1API: ProxyV1TestData[] = [ + { + id: 'fbca_v1_scenario_1', + name: 'fb_custom_audience', + description: 'successfully delete users from audience', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + method: 'DELETE', + endpoint: getEndPoint('aud1'), + headers: { + 'test-dest-response-key': 'successResponse', + }, + params: testParams1, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + response: [ + { + error: + '{"audience_id":"aud1","session_id":"123","num_received":4,"num_invalid_entries":0,"invalid_entry_samples":{}}', + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'fbca_v1_scenario_2', + name: 'fb_custom_audience', + description: 'user addition failed due to missing permission', + successCriteria: 'Fail with status code 400 due to missing permissions', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + method: 'POST', + endpoint: getEndPoint('aud1'), + headers: { + 'test-dest-response-key': 'permissionMissingError', + }, + params: testParams3, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: + 'Missing permission. Please make sure you have ads_management permission and the application is included in the allowlist', + statTags, + response: [ + { + error: + 'Missing permission. Please make sure you have ads_management permission and the application is included in the allowlist', + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'fbca_v1_scenario_3', + name: 'fb_custom_audience', + description: 'user deletion failed due to unavailable audience error', + successCriteria: 'Fail with status code 400', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + method: 'DELETE', + endpoint: getEndPoint('aud1'), + headers: { + 'test-dest-response-key': 'audienceUnavailableError', + }, + params: testParams2, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: + 'Custom Audience Unavailable: The custom audience you are trying to use has not been shared with your ad account', + statTags, + response: [ + { + error: + 'Custom Audience Unavailable: The custom audience you are trying to use has not been shared with your ad account', + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'fbca_v1_scenario_4', + name: 'fb_custom_audience', + description: 'user deletion failed because the custom audience has been deleted', + successCriteria: 'Fail with status code 400', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + method: 'DELETE', + endpoint: getEndPoint('aud1'), + headers: { + 'test-dest-response-key': 'audienceDeletedError', + }, + params: testParams2, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'Custom Audience Has Been Deleted', + statTags, + response: [ + { + error: 'Custom Audience Has Been Deleted', + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'fbca_v1_scenario_5', + name: 'fb_custom_audience', + description: 'Failed to update the custom audience for unknown reason', + successCriteria: 'Fail with status code 400', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + method: 'DELETE', + endpoint: getEndPoint('aud1'), + headers: { + 'test-dest-response-key': 'failedToUpdateAudienceError', + }, + params: testParams2, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'Failed to update the custom audience', + statTags, + response: [ + { + error: 'Failed to update the custom audience', + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'fbca_v1_scenario_6', + name: 'fb_custom_audience', + description: + 'Failed to update the custom audience as excessive number of parameters were passed in the request', + successCriteria: 'Fail with status code 400', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + method: 'DELETE', + endpoint: getEndPoint('aud1'), + headers: { + 'test-dest-response-key': 'parameterExceededError', + }, + params: testParams2, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'The number of parameters exceeded the maximum for this operation', + statTags, + response: [ + { + error: 'The number of parameters exceeded the maximum for this operation', + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'fbca_v1_scenario_7', + name: 'fb_custom_audience', + description: 'user having permission issue while updating audience', + successCriteria: 'Fail with status code 403', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + method: 'DELETE', + endpoint: getEndPoint('aud1'), + headers: { + 'test-dest-response-key': 'code200PermissionError', + }, + params: testParams2, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 403, + message: '(#200) The current user can not update audience 23861283180290489', + statTags, + response: [ + { + error: '(#200) The current user can not update audience 23861283180290489', + statusCode: 403, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, + { + id: 'fbca_v1_scenario_8', + name: 'fb_custom_audience', + description: 'user deletion failed due expired access token error', + successCriteria: 'Fail with status code 400', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + method: 'DELETE', + endpoint: getEndPoint('aud1'), + headers: { + 'test-dest-response-key': 'accessTokenInvalidError', + }, + params: testParams2, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: + 'Error validating access token: Session has expired on Tuesday, 01-Aug-23 10:12:14 PDT. The current time is Sunday, 28-Jan-24 16:01:17 PST.', + statTags: { + ...statTags, + errorCategory: 'dataValidation', + errorType: 'configuration', + meta: 'accessTokenExpired', + }, + response: [ + { + error: + 'Error validating access token: Session has expired on Tuesday, 01-Aug-23 10:12:14 PDT. The current time is Sunday, 28-Jan-24 16:01:17 PST.', + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts b/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts index 3066dae8879..b41c656d9f9 100644 --- a/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts +++ b/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts @@ -1,6 +1,8 @@ import { getEndPoint } from '../../../../../src/v0/destinations/fb_custom_audience/config'; +import { testScenariosForV1API } from './business'; +import { otherScenariosV1 } from './other'; -export const data = [ +export const existingTestData = [ { name: 'fb_custom_audience', description: 'successfully adding users to audience', @@ -572,4 +574,78 @@ export const data = [ }, }, }, + { + name: 'fb_custom_audience', + description: 'user addition failed due expired access token error', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: getEndPoint('aud1'), + headers: { + 'test-dest-response-key': 'accessTokenInvalidError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: ['DOBY', 'PHONE', 'GEN', 'FI', 'MADID', 'ZIP', 'ST', 'COUNTRY'], + data: [['2013', '@09432457768', 'f', 'Ms.', 'ABC', 'ZIP ', '123abc ', 'IN']], + }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: { + error: { + code: 190, + error_subcode: 463, + fbtrace_id: 'A3b8C6PpI-kdIOwPwV4PANi', + message: + 'Error validating access token: Session has expired on Tuesday, 01-Aug-23 10:12:14 PDT. The current time is Sunday, 28-Jan-24 16:01:17 PST.', + type: 'OAuthException', + }, + status: 400, + }, + message: + 'Error validating access token: Session has expired on Tuesday, 01-Aug-23 10:12:14 PDT. The current time is Sunday, 28-Jan-24 16:01:17 PST.', + statTags: { + destType: 'FB_CUSTOM_AUDIENCE', + destinationId: 'Non-determininable', + errorCategory: 'dataValidation', + errorType: 'configuration', + meta: 'accessTokenExpired', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'Non-determininable', + }, + status: 400, + }, + }, + }, + }, + }, ]; + +export const data = [...existingTestData, ...testScenariosForV1API, ...otherScenariosV1]; diff --git a/test/integrations/destinations/fb_custom_audience/dataDelivery/other.ts b/test/integrations/destinations/fb_custom_audience/dataDelivery/other.ts new file mode 100644 index 00000000000..52138604b07 --- /dev/null +++ b/test/integrations/destinations/fb_custom_audience/dataDelivery/other.ts @@ -0,0 +1,53 @@ +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; +import { ProxyV1TestData } from '../../../testTypes'; +import { getEndPoint } from '../../../../../src/v0/destinations/fb_custom_audience/config'; +import { statTags, testParams2 as testParams } from './business'; + +export const otherScenariosV1: ProxyV1TestData[] = [ + { + id: 'fbca_v1_other_scenario_1', + name: 'fb_custom_audience', + description: 'user update request is throttled due to too many calls to the ad account', + successCriteria: + 'Should return 429 with message there have been too many calls to this ad-account', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + method: 'DELETE', + endpoint: getEndPoint('aud1'), + headers: { + 'test-dest-response-key': 'tooManyCallsError', + }, + params: testParams, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'There have been too many calls to this ad-account.', + statTags: { + ...statTags, + errorType: 'throttled', + }, + status: 429, + response: [ + { + error: 'There have been too many calls to this ad-account.', + statusCode: 429, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/fb_custom_audience/network.ts b/test/integrations/destinations/fb_custom_audience/network.ts index bbdc1ffc28c..9b498bc07e5 100644 --- a/test/integrations/destinations/fb_custom_audience/network.ts +++ b/test/integrations/destinations/fb_custom_audience/network.ts @@ -480,4 +480,47 @@ export const networkCallsData = [ status: 403, }, }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: getEndPoint('aud1'), + headers: { + 'test-dest-response-key': 'accessTokenInvalidError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: ['DOBY', 'PHONE', 'GEN', 'FI', 'MADID', 'ZIP', 'ST', 'COUNTRY'], + data: [['2013', '@09432457768', 'f', 'Ms.', 'ABC', 'ZIP ', '123abc ', 'IN']], + }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + httpRes: { + data: { + error: { + message: + 'Error validating access token: Session has expired on Tuesday, 01-Aug-23 10:12:14 PDT. The current time is Sunday, 28-Jan-24 16:01:17 PST.', + type: 'OAuthException', + code: 190, + error_subcode: 463, + fbtrace_id: 'A3b8C6PpI-kdIOwPwV4PANi', + }, + }, + status: 400, + }, + }, ]; diff --git a/test/integrations/destinations/freshmarketer/network.ts b/test/integrations/destinations/freshmarketer/network.ts index 51f1a0c1154..9d661f26867 100644 --- a/test/integrations/destinations/freshmarketer/network.ts +++ b/test/integrations/destinations/freshmarketer/network.ts @@ -1,487 +1,495 @@ export const networkCallsData = [ - { - httpReq: { - url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/sales_accounts/upsert', - method: 'POST' - }, - httpRes: { - data: { - "sales_account": { - "id": 70003771396, - "name": "postman2.0", - "address": "Red Colony", - "city": "Pune", - "state": "Goa", - "zipcode": null, - "country": null, - "number_of_employees": 11, - "annual_revenue": 1000, - "website": null, - "owner_id": null, - "phone": "919191919191", - "open_deals_amount": null, - "open_deals_count": null, - "won_deals_amount": null, - "won_deals_count": null, - "last_contacted": null, - "last_contacted_mode": null, - "facebook": null, - "twitter": null, - "linkedin": null, - "links": { - "conversations": "/crm/sales/sales_accounts/70003771396/conversations/all?include=email_conversation_recipients%2Ctargetable%2Cphone_number%2Cphone_caller%2Cnote%2Cuser&per_page=3", - "document_associations": "/crm/sales/sales_accounts/70003771396/document_associations", - "notes": "/crm/sales/sales_accounts/70003771396/notes?include=creater", - "tasks": "/crm/sales/sales_accounts/70003771396/tasks?include=creater,owner,updater,targetable,users,task_type", - "appointments": "/crm/sales/sales_accounts/70003771396/appointments?include=creater,owner,updater,targetable,appointment_attendees,conference,note" - }, - "custom_field": {}, - "created_at": "2022-08-17T04:15:00-04:00", - "updated_at": "2022-08-24T06:03:31-04:00", - "avatar": null, - "parent_sales_account_id": null, - "recent_note": null, - "last_contacted_via_sales_activity": null, - "last_contacted_sales_activity_mode": null, - "completed_sales_sequences": null, - "active_sales_sequences": null, - "last_assigned_at": null, - "tags": [], - "is_deleted": false, - "team_user_ids": null, - "has_connections": false, - "record_type_id": "71010794477" - } - }, - status: 200 - }, + { + httpReq: { + url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/sales_accounts/upsert', + method: 'POST', }, - { - httpReq: { - url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert?include=sales_accounts', - method: 'POST' - }, - httpRes: { - data: { - "contact": { - "id": 70042006456, - "first_name": "Rk", - "last_name": "Mishra", - "display_name": "Rk Mishra", - "avatar": null, - "job_title": null, - "city": null, - "state": null, - "zipcode": null, - "country": null, - "email": "testuser@google.com", - "emails": [ - { - "id": 70037311213, - "value": "testuser@google.com", - "is_primary": true, - "label": null, - "_destroy": false - } - ], - "time_zone": "IST", - "work_number": "9988776655", - "mobile_number": "19265559504", - "address": null, - "last_seen": null, - "lead_score": 26, - "last_contacted": null, - "open_deals_amount": null, - "won_deals_amount": null, - "links": { - "conversations": "/crm/sales/contacts/70042006456/conversations/all?include=email_conversation_recipients%2Ctargetable%2Cphone_number%2Cphone_caller%2Cnote%2Cuser&per_page=3", - "timeline_feeds": "/crm/sales/contacts/70042006456/timeline_feeds", - "document_associations": "/crm/sales/contacts/70042006456/document_associations", - "notes": "/crm/sales/contacts/70042006456/notes?include=creater", - "tasks": "/crm/sales/contacts/70042006456/tasks?include=creater,owner,updater,targetable,users,task_type", - "appointments": "/crm/sales/contacts/70042006456/appointments?include=creater,owner,updater,targetable,appointment_attendees,conference,note", - "reminders": "/crm/sales/contacts/70042006456/reminders?include=creater,owner,updater,targetable", - "duplicates": "/crm/sales/contacts/70042006456/duplicates", - "connections": "/crm/sales/contacts/70042006456/connections" - }, - "last_contacted_sales_activity_mode": null, - "custom_field": {}, - "created_at": "2022-08-09T03:22:12-04:00", - "updated_at": "2022-08-30T00:33:27-04:00", - "keyword": "drilling", - "medium": "facebook", - "last_contacted_mode": null, - "recent_note": null, - "won_deals_count": null, - "last_contacted_via_sales_activity": null, - "completed_sales_sequences": null, - "active_sales_sequences": null, - "web_form_ids": null, - "open_deals_count": null, - "last_assigned_at": "2022-08-29T05:51:24-04:00", - "tags": [], - "facebook": null, - "twitter": null, - "linkedin": null, - "is_deleted": false, - "team_user_ids": null, - "external_id": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "work_email": null, - "subscription_status": 1, - "subscription_types": "2;3;4;5;1", - "customer_fit": 2, - "record_type_id": "71010794476", - "whatsapp_subscription_status": 2, - "sms_subscription_status": 2, - "last_seen_chat": null, - "first_seen_chat": null, - "locale": null, - "total_sessions": null, - "phone_numbers": [], - "sales_accounts": [ - { - "partial": true, - "id": 70003771198, - "name": "div-quer", - "avatar": null, - "website": null, - "last_contacted": null, - "record_type_id": "71010794477", - "is_primary": true - }, - { - "partial": true, - "id": 70003825177, - "name": "BisleriGroup", - "avatar": null, - "website": null, - "last_contacted": null, - "record_type_id": "71010794477", - "is_primary": false - } - ] - } - }, - status: 200 + httpRes: { + data: { + sales_account: { + id: 70003771396, + name: 'postman2.0', + address: 'Red Colony', + city: 'Pune', + state: 'Goa', + zipcode: null, + country: null, + number_of_employees: 11, + annual_revenue: 1000, + website: null, + owner_id: null, + phone: '919191919191', + open_deals_amount: null, + open_deals_count: null, + won_deals_amount: null, + won_deals_count: null, + last_contacted: null, + last_contacted_mode: null, + facebook: null, + twitter: null, + linkedin: null, + links: { + conversations: + '/crm/sales/sales_accounts/70003771396/conversations/all?include=email_conversation_recipients%2Ctargetable%2Cphone_number%2Cphone_caller%2Cnote%2Cuser&per_page=3', + document_associations: '/crm/sales/sales_accounts/70003771396/document_associations', + notes: '/crm/sales/sales_accounts/70003771396/notes?include=creater', + tasks: + '/crm/sales/sales_accounts/70003771396/tasks?include=creater,owner,updater,targetable,users,task_type', + appointments: + '/crm/sales/sales_accounts/70003771396/appointments?include=creater,owner,updater,targetable,appointment_attendees,conference,note', + }, + custom_field: {}, + created_at: '2022-08-17T04:15:00-04:00', + updated_at: '2022-08-24T06:03:31-04:00', + avatar: null, + parent_sales_account_id: null, + recent_note: null, + last_contacted_via_sales_activity: null, + last_contacted_sales_activity_mode: null, + completed_sales_sequences: null, + active_sales_sequences: null, + last_assigned_at: null, + tags: [], + is_deleted: false, + team_user_ids: null, + has_connections: false, + record_type_id: '71010794477', }, + }, + status: 200, }, - { - httpReq: { - url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/selector/sales_activity_types', - method: 'GET' - }, - httpRes: { - data: { - "sales_activity_types": [ - { - "partial": true, - "id": 70000666879, - "name": "own-calender", - "internal_name": "cappointment", - "show_in_conversation": true, - "position": 1, - "is_default": false, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000663932, - "name": "fb-support", - "internal_name": "facebook", - "show_in_conversation": true, - "position": 2, - "is_default": false, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000663746, - "name": "twitter sales", - "internal_name": "twitter", - "show_in_conversation": true, - "position": 3, - "is_default": false, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000646396, - "name": "linked sales", - "internal_name": "linkedin", - "show_in_conversation": true, - "position": 4, - "is_default": false, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000642330, - "name": "facebook sales", - "internal_name": "facebook", - "show_in_conversation": true, - "position": 5, - "is_default": false, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612897, - "name": "Chat", - "internal_name": "chat", - "show_in_conversation": true, - "position": 6, - "is_default": true, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612898, - "name": "Phone", - "internal_name": "phone", - "show_in_conversation": true, - "position": 7, - "is_default": true, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612899, - "name": "Meeting", - "internal_name": "appointment", - "show_in_conversation": true, - "position": 8, - "is_default": true, - "is_checkedin": true - }, - { - "partial": true, - "id": 70000612900, - "name": "Task", - "internal_name": "task", - "show_in_conversation": true, - "position": 9, - "is_default": true, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612901, - "name": "Email", - "internal_name": "email", - "show_in_conversation": true, - "position": 10, - "is_default": true, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612902, - "name": "SMS Outgoing", - "internal_name": "sms_outgoing", - "show_in_conversation": true, - "position": 11, - "is_default": true, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612903, - "name": "Reminder", - "internal_name": "reminder", - "show_in_conversation": false, - "position": 12, - "is_default": true, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612904, - "name": "SMS Incoming", - "internal_name": "sms_incoming", - "show_in_conversation": true, - "position": 13, - "is_default": true, - "is_checkedin": false - } - ] - }, - status: 200 - }, + }, + { + httpReq: { + url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert?include=sales_accounts', + method: 'POST', }, - { - httpReq: { - url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert', - method: 'POST' - }, - httpRes: { - data: { - "contact": { - "id": 70054866612, - "first_name": null, - "last_name": null, - "display_name": "jamessampleton120@gmail.com", - "avatar": null, - "job_title": null, - "city": null, - "state": null, - "zipcode": null, - "country": null, - "email": "jamessampleton120@gmail.com", - "emails": [ - { - "id": 70047409219, - "value": "jamessampleton120@gmail.com", - "is_primary": true, - "label": null, - "_destroy": false - } - ], - "time_zone": null, - "work_number": null, - "mobile_number": null, - "address": null, - "last_seen": null, - "lead_score": 0, - "last_contacted": null, - "open_deals_amount": null, - "won_deals_amount": null, - "links": { - "conversations": "/crm/sales/contacts/70054866612/conversations/all?include=email_conversation_recipients%2Ctargetable%2Cphone_number%2Cphone_caller%2Cnote%2Cuser&per_page=3", - "timeline_feeds": "/crm/sales/contacts/70054866612/timeline_feeds", - "document_associations": "/crm/sales/contacts/70054866612/document_associations", - "notes": "/crm/sales/contacts/70054866612/notes?include=creater", - "tasks": "/crm/sales/contacts/70054866612/tasks?include=creater,owner,updater,targetable,users,task_type", - "appointments": "/crm/sales/contacts/70054866612/appointments?include=creater,owner,updater,targetable,appointment_attendees,conference,note", - "reminders": "/crm/sales/contacts/70054866612/reminders?include=creater,owner,updater,targetable", - "duplicates": "/crm/sales/contacts/70054866612/duplicates", - "connections": "/crm/sales/contacts/70054866612/connections" - }, - "last_contacted_sales_activity_mode": null, - "custom_field": {}, - "created_at": "2022-10-11T08:42:15-04:00", - "updated_at": "2022-10-11T08:42:15-04:00", - "keyword": null, - "medium": null, - "last_contacted_mode": null, - "recent_note": null, - "won_deals_count": null, - "last_contacted_via_sales_activity": null, - "completed_sales_sequences": null, - "active_sales_sequences": null, - "web_form_ids": null, - "open_deals_count": null, - "last_assigned_at": null, - "tags": [], - "facebook": null, - "twitter": null, - "linkedin": null, - "is_deleted": false, - "team_user_ids": null, - "external_id": null, - "work_email": null, - "subscription_status": 1, - "subscription_types": "2;3;4;5;1", - "customer_fit": 0, - "record_type_id": "71012139284", - "whatsapp_subscription_status": 2, - "sms_subscription_status": 2, - "last_seen_chat": null, - "first_seen_chat": null, - "locale": null, - "total_sessions": null, - "phone_numbers": [] - } + httpRes: { + data: { + contact: { + id: 70042006456, + first_name: 'Rk', + last_name: 'Mishra', + display_name: 'Rk Mishra', + avatar: null, + job_title: null, + city: null, + state: null, + zipcode: null, + country: null, + email: 'testuser@google.com', + emails: [ + { + id: 70037311213, + value: 'testuser@google.com', + is_primary: true, + label: null, + _destroy: false, + }, + ], + time_zone: 'IST', + work_number: '9988776655', + mobile_number: '19265559504', + address: null, + last_seen: null, + lead_score: 26, + last_contacted: null, + open_deals_amount: null, + won_deals_amount: null, + links: { + conversations: + '/crm/sales/contacts/70042006456/conversations/all?include=email_conversation_recipients%2Ctargetable%2Cphone_number%2Cphone_caller%2Cnote%2Cuser&per_page=3', + timeline_feeds: '/crm/sales/contacts/70042006456/timeline_feeds', + document_associations: '/crm/sales/contacts/70042006456/document_associations', + notes: '/crm/sales/contacts/70042006456/notes?include=creater', + tasks: + '/crm/sales/contacts/70042006456/tasks?include=creater,owner,updater,targetable,users,task_type', + appointments: + '/crm/sales/contacts/70042006456/appointments?include=creater,owner,updater,targetable,appointment_attendees,conference,note', + reminders: + '/crm/sales/contacts/70042006456/reminders?include=creater,owner,updater,targetable', + duplicates: '/crm/sales/contacts/70042006456/duplicates', + connections: '/crm/sales/contacts/70042006456/connections', + }, + last_contacted_sales_activity_mode: null, + custom_field: {}, + created_at: '2022-08-09T03:22:12-04:00', + updated_at: '2022-08-30T00:33:27-04:00', + keyword: 'drilling', + medium: 'facebook', + last_contacted_mode: null, + recent_note: null, + won_deals_count: null, + last_contacted_via_sales_activity: null, + completed_sales_sequences: null, + active_sales_sequences: null, + web_form_ids: null, + open_deals_count: null, + last_assigned_at: '2022-08-29T05:51:24-04:00', + tags: [], + facebook: null, + twitter: null, + linkedin: null, + is_deleted: false, + team_user_ids: null, + external_id: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + work_email: null, + subscription_status: 1, + subscription_types: '2;3;4;5;1', + customer_fit: 2, + record_type_id: '71010794476', + whatsapp_subscription_status: 2, + sms_subscription_status: 2, + last_seen_chat: null, + first_seen_chat: null, + locale: null, + total_sessions: null, + phone_numbers: [], + sales_accounts: [ + { + partial: true, + id: 70003771198, + name: 'div-quer', + avatar: null, + website: null, + last_contacted: null, + record_type_id: '71010794477', + is_primary: true, + }, + { + partial: true, + id: 70003825177, + name: 'BisleriGroup', + avatar: null, + website: null, + last_contacted: null, + record_type_id: '71010794477', + is_primary: false, }, - status: 200 + ], }, + }, + status: 200, }, - { - httpReq: { - url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/lists', - method: 'GET' - }, - httpRes: { - data: { - "lists": [ - { - "id": 70000053624, - "name": "Sample list" - }, - { - "id": 70000056575, - "name": "list1-test" - }, - { - "id": 70000058627, - "name": "Jio 5G Group" - }, - { - "id": 70000058628, - "name": "Airtel 5G Group" - }, - { - "id": 70000059716, - "name": "Voda 5G" - } - ], - "meta": { - "total_pages": 1, - "total": 5 - } + }, + { + httpReq: { + url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/selector/sales_activity_types', + method: 'GET', + }, + httpRes: { + data: { + sales_activity_types: [ + { + partial: true, + id: 70000666879, + name: 'own-calender', + internal_name: 'cappointment', + show_in_conversation: true, + position: 1, + is_default: false, + is_checkedin: false, + }, + { + partial: true, + id: 70000663932, + name: 'fb-support', + internal_name: 'facebook', + show_in_conversation: true, + position: 2, + is_default: false, + is_checkedin: false, + }, + { + partial: true, + id: 70000663746, + name: 'twitter sales', + internal_name: 'twitter', + show_in_conversation: true, + position: 3, + is_default: false, + is_checkedin: false, + }, + { + partial: true, + id: 70000646396, + name: 'linked sales', + internal_name: 'linkedin', + show_in_conversation: true, + position: 4, + is_default: false, + is_checkedin: false, + }, + { + partial: true, + id: 70000642330, + name: 'facebook sales', + internal_name: 'facebook', + show_in_conversation: true, + position: 5, + is_default: false, + is_checkedin: false, + }, + { + partial: true, + id: 70000612897, + name: 'Chat', + internal_name: 'chat', + show_in_conversation: true, + position: 6, + is_default: true, + is_checkedin: false, + }, + { + partial: true, + id: 70000612898, + name: 'Phone', + internal_name: 'phone', + show_in_conversation: true, + position: 7, + is_default: true, + is_checkedin: false, + }, + { + partial: true, + id: 70000612899, + name: 'Meeting', + internal_name: 'appointment', + show_in_conversation: true, + position: 8, + is_default: true, + is_checkedin: true, + }, + { + partial: true, + id: 70000612900, + name: 'Task', + internal_name: 'task', + show_in_conversation: true, + position: 9, + is_default: true, + is_checkedin: false, + }, + { + partial: true, + id: 70000612901, + name: 'Email', + internal_name: 'email', + show_in_conversation: true, + position: 10, + is_default: true, + is_checkedin: false, + }, + { + partial: true, + id: 70000612902, + name: 'SMS Outgoing', + internal_name: 'sms_outgoing', + show_in_conversation: true, + position: 11, + is_default: true, + is_checkedin: false, + }, + { + partial: true, + id: 70000612903, + name: 'Reminder', + internal_name: 'reminder', + show_in_conversation: false, + position: 12, + is_default: true, + is_checkedin: false, + }, + { + partial: true, + id: 70000612904, + name: 'SMS Incoming', + internal_name: 'sms_incoming', + show_in_conversation: true, + position: 13, + is_default: true, + is_checkedin: false, + }, + ], + }, + status: 200, + }, + }, + { + httpReq: { + url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert', + method: 'POST', + }, + httpRes: { + data: { + contact: { + id: 70054866612, + first_name: null, + last_name: null, + display_name: 'jamessampleton120@gmail.com', + avatar: null, + job_title: null, + city: null, + state: null, + zipcode: null, + country: null, + email: 'jamessampleton120@gmail.com', + emails: [ + { + id: 70047409219, + value: 'jamessampleton120@gmail.com', + is_primary: true, + label: null, + _destroy: false, }, - status: 200 + ], + time_zone: null, + work_number: null, + mobile_number: null, + address: null, + last_seen: null, + lead_score: 0, + last_contacted: null, + open_deals_amount: null, + won_deals_amount: null, + links: { + conversations: + '/crm/sales/contacts/70054866612/conversations/all?include=email_conversation_recipients%2Ctargetable%2Cphone_number%2Cphone_caller%2Cnote%2Cuser&per_page=3', + timeline_feeds: '/crm/sales/contacts/70054866612/timeline_feeds', + document_associations: '/crm/sales/contacts/70054866612/document_associations', + notes: '/crm/sales/contacts/70054866612/notes?include=creater', + tasks: + '/crm/sales/contacts/70054866612/tasks?include=creater,owner,updater,targetable,users,task_type', + appointments: + '/crm/sales/contacts/70054866612/appointments?include=creater,owner,updater,targetable,appointment_attendees,conference,note', + reminders: + '/crm/sales/contacts/70054866612/reminders?include=creater,owner,updater,targetable', + duplicates: '/crm/sales/contacts/70054866612/duplicates', + connections: '/crm/sales/contacts/70054866612/connections', + }, + last_contacted_sales_activity_mode: null, + custom_field: {}, + created_at: '2022-10-11T08:42:15-04:00', + updated_at: '2022-10-11T08:42:15-04:00', + keyword: null, + medium: null, + last_contacted_mode: null, + recent_note: null, + won_deals_count: null, + last_contacted_via_sales_activity: null, + completed_sales_sequences: null, + active_sales_sequences: null, + web_form_ids: null, + open_deals_count: null, + last_assigned_at: null, + tags: [], + facebook: null, + twitter: null, + linkedin: null, + is_deleted: false, + team_user_ids: null, + external_id: null, + work_email: null, + subscription_status: 1, + subscription_types: '2;3;4;5;1', + customer_fit: 0, + record_type_id: '71012139284', + whatsapp_subscription_status: 2, + sms_subscription_status: 2, + last_seen_chat: null, + first_seen_chat: null, + locale: null, + total_sessions: null, + phone_numbers: [], }, + }, + status: 200, }, - { - httpReq: { - url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/selector/lifecycle_stages', - method: 'GET' - }, - httpRes: { - data: { - "lifecycle_stages": [ - { - "id": 71012139274, - "name": "Sales Qualified Lead start", - "position": 1, - "disabled": false, - "default": true, - "type": "Sales Qualified Lead", - "contact_status_ids": [70000697858, 70000697859, 70000697860] - }, - { - "id": 71012139273, - "name": "Lead", - "position": 2, - "disabled": false, - "default": true, - "type": "Lead", - "contact_status_ids": [70000697854, 70000697855, 70000697856, 70000697857] - }, - { - "id": 71012806409, - "name": "final Customer", - "position": 3, - "disabled": false, - "default": false, - "type": "Custom", - "contact_status_ids": [70000736543, 70000736544] - }, - { - "id": 71012139275, - "name": "Customer", - "position": 4, - "disabled": false, - "default": true, - "type": "Customer", - "contact_status_ids": [70000697861, 70000697862] - } - ] - }, - status: 200 + }, + { + httpReq: { + url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/lists', + method: 'GET', + }, + httpRes: { + data: { + lists: [ + { + id: 70000053624, + name: 'Sample list', + }, + { + id: 70000056575, + name: 'list1-test', + }, + { + id: 70000058627, + name: 'Jio 5G Group', + }, + { + id: 70000058628, + name: 'Airtel 5G Group', + }, + { + id: 70000059716, + name: 'Voda 5G', + }, + ], + meta: { + total_pages: 1, + total: 5, }, - } + }, + status: 200, + }, + }, + { + httpReq: { + url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/selector/lifecycle_stages', + method: 'GET', + }, + httpRes: { + data: { + lifecycle_stages: [ + { + id: 71012139274, + name: 'Sales Qualified Lead start', + position: 1, + disabled: false, + default: true, + type: 'Sales Qualified Lead', + contact_status_ids: [70000697858, 70000697859, 70000697860], + }, + { + id: 71012139273, + name: 'Lead', + position: 2, + disabled: false, + default: true, + type: 'Lead', + contact_status_ids: [70000697854, 70000697855, 70000697856, 70000697857], + }, + { + id: 71012806409, + name: 'final Customer', + position: 3, + disabled: false, + default: false, + type: 'Custom', + contact_status_ids: [70000736543, 70000736544], + }, + { + id: 71012139275, + name: 'Customer', + position: 4, + disabled: false, + default: true, + type: 'Customer', + contact_status_ids: [70000697861, 70000697862], + }, + ], + }, + status: 200, + }, + }, ]; - - - diff --git a/test/integrations/destinations/freshmarketer/processor/data.ts b/test/integrations/destinations/freshmarketer/processor/data.ts index c05dedef1fe..ed920faef0a 100644 --- a/test/integrations/destinations/freshmarketer/processor/data.ts +++ b/test/integrations/destinations/freshmarketer/processor/data.ts @@ -1,3130 +1,3147 @@ export const data = [ - { - "name": "freshmarketer", - "description": "Identify call for creating new user", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105.myfreshworks.com" - } - }, - "message": { - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - } - }, - "traits": { - "email": "testuser@google.com", - "first_name": "Rk", - "last_name": "Mishra", - "mobileNumber": "1-926-555-9504", - "lifecycleStageId": 71010794467, - "phone": "9988776655", - "owner_id": "70000090119" - }, - "type": "identify", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "contact": { - "emails": "testuser@google.com", - "last_name": "Mishra", - "created_at": "2022-06-22T10:57:58Z", - "first_name": "Rk", - "updated_at": "2022-06-22T10:57:58Z", - "external_id": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "work_number": "9988776655", - "mobile_number": "1-926-555-9504", - "lifecycle_stage_id": 71010794467 - }, - "unique_identifier": { - "emails": "testuser@google.com" - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://rudderstack-476952domain3105.myfreshworks.com/crm/sales/api/contacts/upsert", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Identify call with numbers in lifecycleStageId, ownerId", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105.myfreshworks.com" - } - }, - "message": { - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - } - }, - "traits": { - "email": "testuser@google.com", - "first_name": "Rk", - "last_name": "Mishra", - "mobileNumber": "1-926-555-9504", - "lifecycleStageId": 71010794467, - "phone": "9988776655", - "owner_id": "70000090119" - }, - "type": "identify", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "contact": { - "emails": "testuser@google.com", - "last_name": "Mishra", - "created_at": "2022-06-22T10:57:58Z", - "first_name": "Rk", - "updated_at": "2022-06-22T10:57:58Z", - "external_id": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "work_number": "9988776655", - "mobile_number": "1-926-555-9504", - "lifecycle_stage_id": 71010794467 - }, - "unique_identifier": { - "emails": "testuser@google.com" - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://rudderstack-476952domain3105.myfreshworks.com/crm/sales/api/contacts/upsert", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Identify call with wrong data type in lifecycleStageId, ownerId", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105.myfreshworks.com" - } - }, - "message": { - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - } - }, - "traits": { - "email": "testuser@google.com", - "first_name": "Rk", - "last_name": "Mishra", - "mobileNumber": "1-926-555-9504", - "lifecycleStageId": "rudderSample", - "phone": "9988776655", - "ownerId": "rudderSample" - }, - "type": "identify", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "owner_id,lifecycle_stage_id: invalid number format", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Identify call, email is not provided.", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105.myfreshworks.com" - } - }, - "message": { - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - } - }, - "traits": { - "first_name": "Rk", - "last_name": "Mishra", - "mobileNumber": "1-926-555-9504", - "lifecycleStageId": "rudderSample", - "phone": "9988776655", - "owner_id": "rudderSample" - }, - "type": "identify", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Missing required value from \"email\"", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Group call: testing with mock api", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - }, - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - }, - "traits": { - "email": "testuser@google.com" - } - }, - "traits": { - "groupType": "accounts", - "name": "Mark Twain", - "phone": "919191919191", - "numberOfEmployees": 51, - "annualRevenue": 1000, - "address": "Red Colony", - "city": "Colony", - "state": "Haryana" - }, - "type": "group", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "contact": { - "sales_accounts": [ - { - "id": 70003771198, - "name": "div-quer", - "avatar": null, - "partial": true, - "website": null, - "is_primary": true, - "last_contacted": null, - "record_type_id": "71010794477" - }, - { - "id": 70003825177, - "name": "BisleriGroup", - "avatar": null, - "partial": true, - "website": null, - "is_primary": false, - "last_contacted": null, - "record_type_id": "71010794477" - }, - { - "id": 70003771396, - "is_primary": false - } - ] - }, - "unique_identifier": { - "emails": "testuser@google.com" - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Group call: name is required field.", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - }, - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - }, - "traits": { - "email": "testuser@google.com" - } - }, - "traits": { - "groupType": "accounts", - "phone": "919191919191", - "numberOfEmployees": 51, - "annualRevenue": 1000, - "address": "Red Colony", - "city": "Colony", - "state": "Haryana" - }, - "type": "group", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Missing required value from \"name\"", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "missing message type", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - }, - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - }, - "traits": { - "email": "testuser4google.com" - } - }, - "traits": { - "name": "Mark Twain", - "phone": "919191919191", - "numberOfEmployees": 51, - "annualRevenue": 1000, - "address": "Red Colony", - "city": "Colony", - "state": "Haryana" - }, - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Message Type is not present. Aborting message.", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Wrong message type", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - }, - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - }, - "traits": { - "email": "testuser4google.com" - } - }, - "traits": { - "name": "Mark Twain", - "phone": "919191919191", - "numberOfEmployees": 51, - "annualRevenue": 1000, - "address": "Red Colony", - "city": "Colony", - "state": "Haryana" - }, - "type": "page", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "message type page not supported", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Group call: user email is missing", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - }, - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - }, - "traits": {} - }, - "traits": { - "groupType": "accounts", - "name": "div-quer", - "phone": "919191919191", - "numberOfEmployees": 51, - "annualRevenue": 1000, - "address": "Red Colony", - "city": "Lal colony", - "state": "Haryana" - }, - "type": "group", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "sales_account": { - "city": "Lal colony", - "name": "div-quer", - "phone": "919191919191", - "state": "Haryana", - "address": "Red Colony", - "created_at": "2022-06-22T10:57:58Z", - "updated_at": "2022-06-22T10:57:58Z", - "annual_revenue": 1000, - "number_of_employees": 51 - }, - "unique_identifier": { - "name": "div-quer" - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/sales_accounts/upsert", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Identify call: Email is not present", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - } - }, - "traits": { - "first_name": "Rk", - "last_name": "Narayan", - "mobileNumber": "1-926-555-9504", - "phone": "9988776655" - }, - "type": "identify", - "sentAt": "2022-04-22T10:57:58Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Missing required value from \"email\"", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call, event is not supported.", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn" - }, - "event": "Add to Cart", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "event name Add to Cart is not supported. Aborting!", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call: some required properties is missing for sales_activity", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "test@rudderstack.com", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn" - }, - "event": "sales_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Missing required value from \"properties.title\"", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call: for salesActivityName", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - }, - "externalId": { - "type": "Contact" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "test@rudderstack.com", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn", - "salesActivityName": "own-calender", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612" - }, - "event": "sales_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "sales_activity": { - "title": "new Contact", - "end_date": "2022-06-04T17:30:00+05:30", - "owner_id": "70054866612", - "start_date": "2021-05-04T17:00:00+05:30", - "created_at": "2020-10-20T08:14:28.778Z", - "updated_at": "2020-10-20T08:14:28.778Z", - "targetable_id": 70054866612, - "targetable_type": "Contact", - "sales_activity_name": "own-calender", - "sales_activity_type_id": 70000666879 - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call: lifecycle_stage_id", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "email": "jamessampleton3@gmail.com", - "lifecycleStageId": "71012139273", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612", - "targetableType": "Contact" - }, - "event": "lifecycle_stage", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert", - "headers": { - "Authorization": "Token token=dummyApiKey", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "contact": { - "lifecycle_stage_id": "71012139273" - }, - "unique_identifier": { - "emails": "jamessampleton3@gmail.com" - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call: In lifecycle stage, email is missing", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "lifecycleStageId": "71012139273", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612", - "targetableType": "Contact" - }, - "event": "lifecycle_stage", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "email is required for updating life Cycle Stages. Aborting!", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call: Either of lifecycleStageName or lifecycleStageId is required", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "jamessampleton3@gmail.com", - "properties": { - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612", - "targetableType": "Contact" - }, - "event": "lifecycle_stage", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Either of lifecycleStageName or lifecycleStageId is required. Aborting!", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call: Either of sales activity name or sales activity type id is required", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - }, - "externalId": { - "type": "Contact" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "test@rudderstack.com", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612" - }, - "event": "sales_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Either of sales activity name or sales activity type id is required. Aborting!", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call: Either of email or targetable_id is required for creating sales activity.", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - }, - "externalId": { - "type": "Contact" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn", - "salesActivityName": "own-calender", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612" - }, - "event": "sales_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Either of email or targetable_id is required for creating sales activity. Aborting!", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call: sales activity with salesActivityTypeId", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - }, - "externalId": { - "type": "Contact" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "jamessampleton3@gmail.com", - "properties": { - "salesActivityTypeId": "70000663932", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612" - }, - "event": "sales_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "sales_activity": { - "title": "new Contact", - "end_date": "2022-06-04T17:30:00+05:30", - "owner_id": "70054866612", - "start_date": "2021-05-04T17:00:00+05:30", - "created_at": "2020-10-20T08:14:28.778Z", - "updated_at": "2020-10-20T08:14:28.778Z", - "targetable_id": 70054866612, - "targetable_type": "Contact", - "sales_activity_type_id": "70000663932" - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call: updated sales activity with salesActivityTypeId and targetableId", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - }, - "externalId": { - "id": "70052305908", - "type": "Contact" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "salesActivityTypeId": "70000663932", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612" - }, - "event": "sales_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "sales_activity": { - "title": "new Contact", - "end_date": "2022-06-04T17:30:00+05:30", - "owner_id": "70054866612", - "start_date": "2021-05-04T17:00:00+05:30", - "created_at": "2020-10-20T08:14:28.778Z", - "updated_at": "2020-10-20T08:14:28.778Z", - "targetable_id": "70052305908", - "targetable_type": "Contact", - "sales_activity_type_id": "70000663932" - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Unsupported message Type", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "type": "page", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "jamessampleton3@gmail.com", - "properties": { - "lifecycleStageId": "71012139273", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612", - "targetableType": "Contact" - }, - "event": "lifecycle_stage", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "message type page not supported", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Group call: email is required for adding contacts to marketing lists", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "traits": { - "groupType": "marketing_lists" - }, - "type": "group", - "sentAt": "2022-04-22T10:57:58Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "email is required for adding in the marketing lists. Aborting!", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Group call: group type is not present", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "traits": { - "name": "Mark Twain", - "phone": "919191919191", - "numberOfEmployees": 51, - "annualRevenue": 1000, - "address": "Red Colony", - "city": "Colony", - "state": "Haryana" - }, - "type": "group", - "sentAt": "2022-04-22T10:57:58Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "groupType is required for Group call", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Group call: add contacts in existing marketing lists", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - }, - "traits": { - "email": "jamessampleton1@gmail.com" - } - }, - "traits": { - "groupType": "marketing_lists", - "listName": "Voda 5G", - "address": "Red Colony", - "city": "Colony", - "state": "Haryana" - }, - "type": "group", - "sentAt": "2022-04-22T10:57:58Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "ids": [ - 70054866612 - ] - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "PUT", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/lists/70000059716/add_contacts", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Group call: groupType is not supported", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "traits": { - "groupType": "marketing", - "listName": "Voda 5G", - "address": "Red Colony", - "city": "Colony", - "state": "Haryana" - }, - "type": "group", - "sentAt": "2022-04-22T10:57:58Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "groupType marketing is not supported. Aborting!", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Group call: listId or listName is required", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "context": { - "traits": { - "email": "jamessampleton1@gmail.com" - } - }, - "traits": { - "groupType": "marketing_lists", - "address": "Red Colony", - "city": "Colony", - "state": "Haryana" - }, - "type": "group", - "sentAt": "2022-04-22T10:57:58Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "listId or listName is required. Aborting!", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Group call: add marketing lists with listId", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - }, - "traits": { - "email": "jamessampleton1@gmail.com" - } - }, - "traits": { - "listId": "70000058627", - "groupType": "marketing_lists", - "address": "Red Colony", - "city": "Colony", - "state": "Haryana" - }, - "type": "group", - "sentAt": "2022-04-22T10:57:58Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "ids": [ - 70054866612 - ] - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "PUT", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/lists/70000058627/add_contacts", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call: with wrong sales activity name", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - }, - "externalId": { - "type": "Contact" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "test@rudderstack.com", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn", - "salesActivityName": "own-list", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612" - }, - "event": "sales_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "sales Activity own-list doesn't exists. Aborting!", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call: update contacts with sales Activity name", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "email": "jamessampleton6@gmail.com", - "lifecycleStageName": "final Customer", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612", - "targetableType": "Contact" - }, - "event": "lifecycle_stage", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "contact": { - "lifecycle_stage_id": 71012806409 - }, - "unique_identifier": { - "emails": "jamessampleton6@gmail.com" - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call: with wrong lifecycleStageName", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "email": "jamessampleton6@gmail.com", - "lifecycleStageName": "final ExCustomer", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612", - "targetableType": "Contact" - }, - "event": "lifecycle_stage", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "failed to fetch lifeCycleStages with final ExCustomer", - "statTags": { - "destType": "FRESHMARKETER", - "errorCategory": "network", - "errorType": "aborted", - "feature": "processor", - "implementation": "native", - "meta": "instrumentation", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshmarketer", - "description": "Track call: Multiplexing", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - }, - "externalId": { - "type": "Contact" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "test@rudderstack.com", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn", - "salesActivityName": "own-calender", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612", - "lifecycleStageId": "71012139273" - }, - "event": "test_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com", - "rudderEventsToFreshmarketerEvents": [ - { - "from": "test_activity", - "to": "sales_activity" - }, - { - "from": "test_activity", - "to": "lifecycle_stage" - }, - { - "from": "test_event", - "to": "lifecycle_stage" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "sales_activity": { - "title": "new Contact", - "end_date": "2022-06-04T17:30:00+05:30", - "owner_id": "70054866612", - "start_date": "2021-05-04T17:00:00+05:30", - "created_at": "2020-10-20T08:14:28.778Z", - "updated_at": "2020-10-20T08:14:28.778Z", - "targetable_id": 70054866612, - "targetable_type": "Contact", - "sales_activity_name": "own-calender", - "sales_activity_type_id": 70000666879 - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "userId": "", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities" - }, - "statusCode": 200 - }, - { - "output": { - "body": { - "JSON": { - "contact": { - "lifecycle_stage_id": "71012139273" - }, - "unique_identifier": { - "emails": "test@rudderstack.com" - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "type": "REST", - "files": {}, - "userId": "", - "method": "POST", - "params": {}, - "headers": { - "Authorization": "Token token=dummyApiKey", - "Content-Type": "application/json" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert" - }, - "statusCode": 200 - } - ] - } - } - } -] + { + name: 'freshmarketer', + description: 'Identify call for creating new user', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'rudderstack-476952domain3105.myfreshworks.com', + }, + }, + message: { + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + }, + traits: { + email: 'testuser@google.com', + first_name: 'Rk', + last_name: 'Mishra', + mobileNumber: '1-926-555-9504', + lifecycleStageId: 71010794467, + phone: '9988776655', + owner_id: '70000090119', + }, + type: 'identify', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + contact: { + emails: 'testuser@google.com', + last_name: 'Mishra', + created_at: '2022-06-22T10:57:58Z', + first_name: 'Rk', + updated_at: '2022-06-22T10:57:58Z', + external_id: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + work_number: '9988776655', + mobile_number: '1-926-555-9504', + lifecycle_stage_id: 71010794467, + }, + unique_identifier: { + emails: 'testuser@google.com', + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: + 'https://rudderstack-476952domain3105.myfreshworks.com/crm/sales/api/contacts/upsert', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Identify call with numbers in lifecycleStageId, ownerId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'rudderstack-476952domain3105.myfreshworks.com', + }, + }, + message: { + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + }, + traits: { + email: 'testuser@google.com', + first_name: 'Rk', + last_name: 'Mishra', + mobileNumber: '1-926-555-9504', + lifecycleStageId: 71010794467, + phone: '9988776655', + owner_id: '70000090119', + }, + type: 'identify', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + contact: { + emails: 'testuser@google.com', + last_name: 'Mishra', + created_at: '2022-06-22T10:57:58Z', + first_name: 'Rk', + updated_at: '2022-06-22T10:57:58Z', + external_id: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + work_number: '9988776655', + mobile_number: '1-926-555-9504', + lifecycle_stage_id: 71010794467, + }, + unique_identifier: { + emails: 'testuser@google.com', + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: + 'https://rudderstack-476952domain3105.myfreshworks.com/crm/sales/api/contacts/upsert', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Identify call with wrong data type in lifecycleStageId, ownerId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'rudderstack-476952domain3105.myfreshworks.com', + }, + }, + message: { + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + }, + traits: { + email: 'testuser@google.com', + first_name: 'Rk', + last_name: 'Mishra', + mobileNumber: '1-926-555-9504', + lifecycleStageId: 'rudderSample', + phone: '9988776655', + ownerId: 'rudderSample', + }, + type: 'identify', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'owner_id,lifecycle_stage_id: invalid number format', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Identify call, email is not provided.', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'rudderstack-476952domain3105.myfreshworks.com', + }, + }, + message: { + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + }, + traits: { + first_name: 'Rk', + last_name: 'Mishra', + mobileNumber: '1-926-555-9504', + lifecycleStageId: 'rudderSample', + phone: '9988776655', + owner_id: 'rudderSample', + }, + type: 'identify', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Missing required value from "email"', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Group call: testing with mock api', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: { + email: 'testuser@google.com', + }, + }, + traits: { + groupType: 'accounts', + name: 'Mark Twain', + phone: '919191919191', + numberOfEmployees: 51, + annualRevenue: 1000, + address: 'Red Colony', + city: 'Colony', + state: 'Haryana', + }, + type: 'group', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + contact: { + sales_accounts: [ + { + id: 70003771198, + name: 'div-quer', + avatar: null, + partial: true, + website: null, + is_primary: true, + last_contacted: null, + record_type_id: '71010794477', + }, + { + id: 70003825177, + name: 'BisleriGroup', + avatar: null, + partial: true, + website: null, + is_primary: false, + last_contacted: null, + record_type_id: '71010794477', + }, + { + id: 70003771396, + is_primary: false, + }, + ], + }, + unique_identifier: { + emails: 'testuser@google.com', + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Group call: name is required field.', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: { + email: 'testuser@google.com', + }, + }, + traits: { + groupType: 'accounts', + phone: '919191919191', + numberOfEmployees: 51, + annualRevenue: 1000, + address: 'Red Colony', + city: 'Colony', + state: 'Haryana', + }, + type: 'group', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Missing required value from "name"', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'missing message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: { + email: 'testuser4google.com', + }, + }, + traits: { + name: 'Mark Twain', + phone: '919191919191', + numberOfEmployees: 51, + annualRevenue: 1000, + address: 'Red Colony', + city: 'Colony', + state: 'Haryana', + }, + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Message Type is not present. Aborting message.', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Wrong message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: { + email: 'testuser4google.com', + }, + }, + traits: { + name: 'Mark Twain', + phone: '919191919191', + numberOfEmployees: 51, + annualRevenue: 1000, + address: 'Red Colony', + city: 'Colony', + state: 'Haryana', + }, + type: 'page', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'message type page not supported', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Group call: user email is missing', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: {}, + }, + traits: { + groupType: 'accounts', + name: 'div-quer', + phone: '919191919191', + numberOfEmployees: 51, + annualRevenue: 1000, + address: 'Red Colony', + city: 'Lal colony', + state: 'Haryana', + }, + type: 'group', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + sales_account: { + city: 'Lal colony', + name: 'div-quer', + phone: '919191919191', + state: 'Haryana', + address: 'Red Colony', + created_at: '2022-06-22T10:57:58Z', + updated_at: '2022-06-22T10:57:58Z', + annual_revenue: 1000, + number_of_employees: 51, + }, + unique_identifier: { + name: 'div-quer', + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: + 'https://domain-rudder.myfreshworks.com/crm/sales/api/sales_accounts/upsert', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Identify call: Email is not present', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + }, + traits: { + first_name: 'Rk', + last_name: 'Narayan', + mobileNumber: '1-926-555-9504', + phone: '9988776655', + }, + type: 'identify', + sentAt: '2022-04-22T10:57:58Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Missing required value from "email"', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Track call, event is not supported.', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + }, + event: 'Add to Cart', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'event name Add to Cart is not supported. Aborting!', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Track call: some required properties is missing for sales_activity', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'test@rudderstack.com', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + }, + event: 'sales_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Missing required value from "properties.title"', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Track call: for salesActivityName', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + externalId: { + type: 'Contact', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'test@rudderstack.com', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + salesActivityName: 'own-calender', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + }, + event: 'sales_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + sales_activity: { + title: 'new Contact', + end_date: '2022-06-04T17:30:00+05:30', + owner_id: '70054866612', + start_date: '2021-05-04T17:00:00+05:30', + created_at: '2020-10-20T08:14:28.778Z', + updated_at: '2020-10-20T08:14:28.778Z', + targetable_id: 70054866612, + targetable_type: 'Contact', + sales_activity_name: 'own-calender', + sales_activity_type_id: 70000666879, + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Track call: lifecycle_stage_id', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + email: 'jamessampleton3@gmail.com', + lifecycleStageId: '71012139273', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + targetableType: 'Contact', + }, + event: 'lifecycle_stage', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert', + headers: { + Authorization: 'Token token=dummyApiKey', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + contact: { + lifecycle_stage_id: '71012139273', + }, + unique_identifier: { + emails: 'jamessampleton3@gmail.com', + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Track call: In lifecycle stage, email is missing', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + lifecycleStageId: '71012139273', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + targetableType: 'Contact', + }, + event: 'lifecycle_stage', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'email is required for updating life Cycle Stages. Aborting!', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Track call: Either of lifecycleStageName or lifecycleStageId is required', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'jamessampleton3@gmail.com', + properties: { + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + targetableType: 'Contact', + }, + event: 'lifecycle_stage', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Either of lifecycleStageName or lifecycleStageId is required. Aborting!', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Track call: Either of sales activity name or sales activity type id is required', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + externalId: { + type: 'Contact', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'test@rudderstack.com', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + }, + event: 'sales_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Either of sales activity name or sales activity type id is required. Aborting!', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: + 'Track call: Either of email or targetable_id is required for creating sales activity.', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + externalId: { + type: 'Contact', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + salesActivityName: 'own-calender', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + }, + event: 'sales_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Either of email or targetable_id is required for creating sales activity. Aborting!', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Track call: sales activity with salesActivityTypeId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + externalId: { + type: 'Contact', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'jamessampleton3@gmail.com', + properties: { + salesActivityTypeId: '70000663932', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + }, + event: 'sales_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + sales_activity: { + title: 'new Contact', + end_date: '2022-06-04T17:30:00+05:30', + owner_id: '70054866612', + start_date: '2021-05-04T17:00:00+05:30', + created_at: '2020-10-20T08:14:28.778Z', + updated_at: '2020-10-20T08:14:28.778Z', + targetable_id: 70054866612, + targetable_type: 'Contact', + sales_activity_type_id: '70000663932', + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Track call: updated sales activity with salesActivityTypeId and targetableId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + externalId: { + id: '70052305908', + type: 'Contact', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + salesActivityTypeId: '70000663932', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + }, + event: 'sales_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + sales_activity: { + title: 'new Contact', + end_date: '2022-06-04T17:30:00+05:30', + owner_id: '70054866612', + start_date: '2021-05-04T17:00:00+05:30', + created_at: '2020-10-20T08:14:28.778Z', + updated_at: '2020-10-20T08:14:28.778Z', + targetable_id: '70052305908', + targetable_type: 'Contact', + sales_activity_type_id: '70000663932', + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Unsupported message Type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + type: 'page', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'jamessampleton3@gmail.com', + properties: { + lifecycleStageId: '71012139273', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + targetableType: 'Contact', + }, + event: 'lifecycle_stage', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'message type page not supported', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Group call: email is required for adding contacts to marketing lists', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + traits: { + groupType: 'marketing_lists', + }, + type: 'group', + sentAt: '2022-04-22T10:57:58Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'email is required for adding in the marketing lists. Aborting!', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Group call: group type is not present', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + traits: { + name: 'Mark Twain', + phone: '919191919191', + numberOfEmployees: 51, + annualRevenue: 1000, + address: 'Red Colony', + city: 'Colony', + state: 'Haryana', + }, + type: 'group', + sentAt: '2022-04-22T10:57:58Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'groupType is required for Group call', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Group call: add contacts in existing marketing lists', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: { + email: 'jamessampleton1@gmail.com', + }, + }, + traits: { + groupType: 'marketing_lists', + listName: 'Voda 5G', + address: 'Red Colony', + city: 'Colony', + state: 'Haryana', + }, + type: 'group', + sentAt: '2022-04-22T10:57:58Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + ids: [70054866612], + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'PUT', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: + 'https://domain-rudder.myfreshworks.com/crm/sales/api/lists/70000059716/add_contacts', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Group call: groupType is not supported', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + traits: { + groupType: 'marketing', + listName: 'Voda 5G', + address: 'Red Colony', + city: 'Colony', + state: 'Haryana', + }, + type: 'group', + sentAt: '2022-04-22T10:57:58Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'groupType marketing is not supported. Aborting!', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Group call: listId or listName is required', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + traits: { + email: 'jamessampleton1@gmail.com', + }, + }, + traits: { + groupType: 'marketing_lists', + address: 'Red Colony', + city: 'Colony', + state: 'Haryana', + }, + type: 'group', + sentAt: '2022-04-22T10:57:58Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'listId or listName is required. Aborting!', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Group call: add marketing lists with listId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: { + email: 'jamessampleton1@gmail.com', + }, + }, + traits: { + listId: '70000058627', + groupType: 'marketing_lists', + address: 'Red Colony', + city: 'Colony', + state: 'Haryana', + }, + type: 'group', + sentAt: '2022-04-22T10:57:58Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + ids: [70054866612], + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'PUT', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: + 'https://domain-rudder.myfreshworks.com/crm/sales/api/lists/70000058627/add_contacts', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Track call: with wrong sales activity name', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + externalId: { + type: 'Contact', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'test@rudderstack.com', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + salesActivityName: 'own-list', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + }, + event: 'sales_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: "sales Activity own-list doesn't exists. Aborting!", + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Track call: update contacts with sales Activity name', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + email: 'jamessampleton6@gmail.com', + lifecycleStageName: 'final Customer', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + targetableType: 'Contact', + }, + event: 'lifecycle_stage', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + contact: { + lifecycle_stage_id: 71012806409, + }, + unique_identifier: { + emails: 'jamessampleton6@gmail.com', + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Track call: with wrong lifecycleStageName', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + email: 'jamessampleton6@gmail.com', + lifecycleStageName: 'final ExCustomer', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + targetableType: 'Contact', + }, + event: 'lifecycle_stage', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'failed to fetch lifeCycleStages with final ExCustomer', + statTags: { + destType: 'FRESHMARKETER', + errorCategory: 'network', + errorType: 'aborted', + feature: 'processor', + implementation: 'native', + meta: 'instrumentation', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshmarketer', + description: 'Track call: Multiplexing', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + externalId: { + type: 'Contact', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'test@rudderstack.com', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + salesActivityName: 'own-calender', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + lifecycleStageId: '71012139273', + }, + event: 'test_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + rudderEventsToFreshmarketerEvents: [ + { + from: 'test_activity', + to: 'sales_activity', + }, + { + from: 'test_activity', + to: 'lifecycle_stage', + }, + { + from: 'test_event', + to: 'lifecycle_stage', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + sales_activity: { + title: 'new Contact', + end_date: '2022-06-04T17:30:00+05:30', + owner_id: '70054866612', + start_date: '2021-05-04T17:00:00+05:30', + created_at: '2020-10-20T08:14:28.778Z', + updated_at: '2020-10-20T08:14:28.778Z', + targetable_id: 70054866612, + targetable_type: 'Contact', + sales_activity_name: 'own-calender', + sales_activity_type_id: 70000666879, + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + userId: '', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities', + }, + statusCode: 200, + }, + { + output: { + body: { + JSON: { + contact: { + lifecycle_stage_id: '71012139273', + }, + unique_identifier: { + emails: 'test@rudderstack.com', + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + type: 'REST', + files: {}, + userId: '', + method: 'POST', + params: {}, + headers: { + Authorization: 'Token token=dummyApiKey', + 'Content-Type': 'application/json', + }, + version: '1', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/freshsales/network.ts b/test/integrations/destinations/freshsales/network.ts index f6043b265f9..9d661f26867 100644 --- a/test/integrations/destinations/freshsales/network.ts +++ b/test/integrations/destinations/freshsales/network.ts @@ -1,484 +1,495 @@ export const networkCallsData = [ - { - httpReq: { - url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/sales_accounts/upsert', - method: 'POST' - }, - httpRes: { - data: { - "sales_account": { - "id": 70003771396, - "name": "postman2.0", - "address": "Red Colony", - "city": "Pune", - "state": "Goa", - "zipcode": null, - "country": null, - "number_of_employees": 11, - "annual_revenue": 1000, - "website": null, - "owner_id": null, - "phone": "919191919191", - "open_deals_amount": null, - "open_deals_count": null, - "won_deals_amount": null, - "won_deals_count": null, - "last_contacted": null, - "last_contacted_mode": null, - "facebook": null, - "twitter": null, - "linkedin": null, - "links": { - "conversations": "/crm/sales/sales_accounts/70003771396/conversations/all?include=email_conversation_recipients%2Ctargetable%2Cphone_number%2Cphone_caller%2Cnote%2Cuser&per_page=3", - "document_associations": "/crm/sales/sales_accounts/70003771396/document_associations", - "notes": "/crm/sales/sales_accounts/70003771396/notes?include=creater", - "tasks": "/crm/sales/sales_accounts/70003771396/tasks?include=creater,owner,updater,targetable,users,task_type", - "appointments": "/crm/sales/sales_accounts/70003771396/appointments?include=creater,owner,updater,targetable,appointment_attendees,conference,note" - }, - "custom_field": {}, - "created_at": "2022-08-17T04:15:00-04:00", - "updated_at": "2022-08-24T06:03:31-04:00", - "avatar": null, - "parent_sales_account_id": null, - "recent_note": null, - "last_contacted_via_sales_activity": null, - "last_contacted_sales_activity_mode": null, - "completed_sales_sequences": null, - "active_sales_sequences": null, - "last_assigned_at": null, - "tags": [], - "is_deleted": false, - "team_user_ids": null, - "has_connections": false, - "record_type_id": "71010794477" - } - }, - status: 200 - }, + { + httpReq: { + url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/sales_accounts/upsert', + method: 'POST', }, - { - httpReq: { - url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert?include=sales_accounts', - method: 'POST' - }, - httpRes: { - data: { - "contact": { - "id": 70042006456, - "first_name": "Rk", - "last_name": "Mishra", - "display_name": "Rk Mishra", - "avatar": null, - "job_title": null, - "city": null, - "state": null, - "zipcode": null, - "country": null, - "email": "testuser@google.com", - "emails": [ - { - "id": 70037311213, - "value": "testuser@google.com", - "is_primary": true, - "label": null, - "_destroy": false - } - ], - "time_zone": "IST", - "work_number": "9988776655", - "mobile_number": "19265559504", - "address": null, - "last_seen": null, - "lead_score": 26, - "last_contacted": null, - "open_deals_amount": null, - "won_deals_amount": null, - "links": { - "conversations": "/crm/sales/contacts/70042006456/conversations/all?include=email_conversation_recipients%2Ctargetable%2Cphone_number%2Cphone_caller%2Cnote%2Cuser&per_page=3", - "timeline_feeds": "/crm/sales/contacts/70042006456/timeline_feeds", - "document_associations": "/crm/sales/contacts/70042006456/document_associations", - "notes": "/crm/sales/contacts/70042006456/notes?include=creater", - "tasks": "/crm/sales/contacts/70042006456/tasks?include=creater,owner,updater,targetable,users,task_type", - "appointments": "/crm/sales/contacts/70042006456/appointments?include=creater,owner,updater,targetable,appointment_attendees,conference,note", - "reminders": "/crm/sales/contacts/70042006456/reminders?include=creater,owner,updater,targetable", - "duplicates": "/crm/sales/contacts/70042006456/duplicates", - "connections": "/crm/sales/contacts/70042006456/connections" - }, - "last_contacted_sales_activity_mode": null, - "custom_field": {}, - "created_at": "2022-08-09T03:22:12-04:00", - "updated_at": "2022-08-30T00:33:27-04:00", - "keyword": "drilling", - "medium": "facebook", - "last_contacted_mode": null, - "recent_note": null, - "won_deals_count": null, - "last_contacted_via_sales_activity": null, - "completed_sales_sequences": null, - "active_sales_sequences": null, - "web_form_ids": null, - "open_deals_count": null, - "last_assigned_at": "2022-08-29T05:51:24-04:00", - "tags": [], - "facebook": null, - "twitter": null, - "linkedin": null, - "is_deleted": false, - "team_user_ids": null, - "external_id": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "work_email": null, - "subscription_status": 1, - "subscription_types": "2;3;4;5;1", - "customer_fit": 2, - "record_type_id": "71010794476", - "whatsapp_subscription_status": 2, - "sms_subscription_status": 2, - "last_seen_chat": null, - "first_seen_chat": null, - "locale": null, - "total_sessions": null, - "phone_numbers": [], - "sales_accounts": [ - { - "partial": true, - "id": 70003771198, - "name": "div-quer", - "avatar": null, - "website": null, - "last_contacted": null, - "record_type_id": "71010794477", - "is_primary": true - }, - { - "partial": true, - "id": 70003825177, - "name": "BisleriGroup", - "avatar": null, - "website": null, - "last_contacted": null, - "record_type_id": "71010794477", - "is_primary": false - } - ] - } - }, - status: 200 + httpRes: { + data: { + sales_account: { + id: 70003771396, + name: 'postman2.0', + address: 'Red Colony', + city: 'Pune', + state: 'Goa', + zipcode: null, + country: null, + number_of_employees: 11, + annual_revenue: 1000, + website: null, + owner_id: null, + phone: '919191919191', + open_deals_amount: null, + open_deals_count: null, + won_deals_amount: null, + won_deals_count: null, + last_contacted: null, + last_contacted_mode: null, + facebook: null, + twitter: null, + linkedin: null, + links: { + conversations: + '/crm/sales/sales_accounts/70003771396/conversations/all?include=email_conversation_recipients%2Ctargetable%2Cphone_number%2Cphone_caller%2Cnote%2Cuser&per_page=3', + document_associations: '/crm/sales/sales_accounts/70003771396/document_associations', + notes: '/crm/sales/sales_accounts/70003771396/notes?include=creater', + tasks: + '/crm/sales/sales_accounts/70003771396/tasks?include=creater,owner,updater,targetable,users,task_type', + appointments: + '/crm/sales/sales_accounts/70003771396/appointments?include=creater,owner,updater,targetable,appointment_attendees,conference,note', + }, + custom_field: {}, + created_at: '2022-08-17T04:15:00-04:00', + updated_at: '2022-08-24T06:03:31-04:00', + avatar: null, + parent_sales_account_id: null, + recent_note: null, + last_contacted_via_sales_activity: null, + last_contacted_sales_activity_mode: null, + completed_sales_sequences: null, + active_sales_sequences: null, + last_assigned_at: null, + tags: [], + is_deleted: false, + team_user_ids: null, + has_connections: false, + record_type_id: '71010794477', }, + }, + status: 200, }, - { - httpReq: { - url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/selector/sales_activity_types', - method: 'GET' - }, - httpRes: { - data: { - "sales_activity_types": [ - { - "partial": true, - "id": 70000666879, - "name": "own-calender", - "internal_name": "cappointment", - "show_in_conversation": true, - "position": 1, - "is_default": false, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000663932, - "name": "fb-support", - "internal_name": "facebook", - "show_in_conversation": true, - "position": 2, - "is_default": false, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000663746, - "name": "twitter sales", - "internal_name": "twitter", - "show_in_conversation": true, - "position": 3, - "is_default": false, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000646396, - "name": "linked sales", - "internal_name": "linkedin", - "show_in_conversation": true, - "position": 4, - "is_default": false, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000642330, - "name": "facebook sales", - "internal_name": "facebook", - "show_in_conversation": true, - "position": 5, - "is_default": false, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612897, - "name": "Chat", - "internal_name": "chat", - "show_in_conversation": true, - "position": 6, - "is_default": true, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612898, - "name": "Phone", - "internal_name": "phone", - "show_in_conversation": true, - "position": 7, - "is_default": true, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612899, - "name": "Meeting", - "internal_name": "appointment", - "show_in_conversation": true, - "position": 8, - "is_default": true, - "is_checkedin": true - }, - { - "partial": true, - "id": 70000612900, - "name": "Task", - "internal_name": "task", - "show_in_conversation": true, - "position": 9, - "is_default": true, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612901, - "name": "Email", - "internal_name": "email", - "show_in_conversation": true, - "position": 10, - "is_default": true, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612902, - "name": "SMS Outgoing", - "internal_name": "sms_outgoing", - "show_in_conversation": true, - "position": 11, - "is_default": true, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612903, - "name": "Reminder", - "internal_name": "reminder", - "show_in_conversation": false, - "position": 12, - "is_default": true, - "is_checkedin": false - }, - { - "partial": true, - "id": 70000612904, - "name": "SMS Incoming", - "internal_name": "sms_incoming", - "show_in_conversation": true, - "position": 13, - "is_default": true, - "is_checkedin": false - } - ] - }, - status: 200 - }, + }, + { + httpReq: { + url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert?include=sales_accounts', + method: 'POST', }, - { - httpReq: { - url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert', - method: 'POST' - }, - httpRes: { - data: { - "contact": { - "id": 70054866612, - "first_name": null, - "last_name": null, - "display_name": "jamessampleton120@gmail.com", - "avatar": null, - "job_title": null, - "city": null, - "state": null, - "zipcode": null, - "country": null, - "email": "jamessampleton120@gmail.com", - "emails": [ - { - "id": 70047409219, - "value": "jamessampleton120@gmail.com", - "is_primary": true, - "label": null, - "_destroy": false - } - ], - "time_zone": null, - "work_number": null, - "mobile_number": null, - "address": null, - "last_seen": null, - "lead_score": 0, - "last_contacted": null, - "open_deals_amount": null, - "won_deals_amount": null, - "links": { - "conversations": "/crm/sales/contacts/70054866612/conversations/all?include=email_conversation_recipients%2Ctargetable%2Cphone_number%2Cphone_caller%2Cnote%2Cuser&per_page=3", - "timeline_feeds": "/crm/sales/contacts/70054866612/timeline_feeds", - "document_associations": "/crm/sales/contacts/70054866612/document_associations", - "notes": "/crm/sales/contacts/70054866612/notes?include=creater", - "tasks": "/crm/sales/contacts/70054866612/tasks?include=creater,owner,updater,targetable,users,task_type", - "appointments": "/crm/sales/contacts/70054866612/appointments?include=creater,owner,updater,targetable,appointment_attendees,conference,note", - "reminders": "/crm/sales/contacts/70054866612/reminders?include=creater,owner,updater,targetable", - "duplicates": "/crm/sales/contacts/70054866612/duplicates", - "connections": "/crm/sales/contacts/70054866612/connections" - }, - "last_contacted_sales_activity_mode": null, - "custom_field": {}, - "created_at": "2022-10-11T08:42:15-04:00", - "updated_at": "2022-10-11T08:42:15-04:00", - "keyword": null, - "medium": null, - "last_contacted_mode": null, - "recent_note": null, - "won_deals_count": null, - "last_contacted_via_sales_activity": null, - "completed_sales_sequences": null, - "active_sales_sequences": null, - "web_form_ids": null, - "open_deals_count": null, - "last_assigned_at": null, - "tags": [], - "facebook": null, - "twitter": null, - "linkedin": null, - "is_deleted": false, - "team_user_ids": null, - "external_id": null, - "work_email": null, - "subscription_status": 1, - "subscription_types": "2;3;4;5;1", - "customer_fit": 0, - "record_type_id": "71012139284", - "whatsapp_subscription_status": 2, - "sms_subscription_status": 2, - "last_seen_chat": null, - "first_seen_chat": null, - "locale": null, - "total_sessions": null, - "phone_numbers": [] - } + httpRes: { + data: { + contact: { + id: 70042006456, + first_name: 'Rk', + last_name: 'Mishra', + display_name: 'Rk Mishra', + avatar: null, + job_title: null, + city: null, + state: null, + zipcode: null, + country: null, + email: 'testuser@google.com', + emails: [ + { + id: 70037311213, + value: 'testuser@google.com', + is_primary: true, + label: null, + _destroy: false, + }, + ], + time_zone: 'IST', + work_number: '9988776655', + mobile_number: '19265559504', + address: null, + last_seen: null, + lead_score: 26, + last_contacted: null, + open_deals_amount: null, + won_deals_amount: null, + links: { + conversations: + '/crm/sales/contacts/70042006456/conversations/all?include=email_conversation_recipients%2Ctargetable%2Cphone_number%2Cphone_caller%2Cnote%2Cuser&per_page=3', + timeline_feeds: '/crm/sales/contacts/70042006456/timeline_feeds', + document_associations: '/crm/sales/contacts/70042006456/document_associations', + notes: '/crm/sales/contacts/70042006456/notes?include=creater', + tasks: + '/crm/sales/contacts/70042006456/tasks?include=creater,owner,updater,targetable,users,task_type', + appointments: + '/crm/sales/contacts/70042006456/appointments?include=creater,owner,updater,targetable,appointment_attendees,conference,note', + reminders: + '/crm/sales/contacts/70042006456/reminders?include=creater,owner,updater,targetable', + duplicates: '/crm/sales/contacts/70042006456/duplicates', + connections: '/crm/sales/contacts/70042006456/connections', + }, + last_contacted_sales_activity_mode: null, + custom_field: {}, + created_at: '2022-08-09T03:22:12-04:00', + updated_at: '2022-08-30T00:33:27-04:00', + keyword: 'drilling', + medium: 'facebook', + last_contacted_mode: null, + recent_note: null, + won_deals_count: null, + last_contacted_via_sales_activity: null, + completed_sales_sequences: null, + active_sales_sequences: null, + web_form_ids: null, + open_deals_count: null, + last_assigned_at: '2022-08-29T05:51:24-04:00', + tags: [], + facebook: null, + twitter: null, + linkedin: null, + is_deleted: false, + team_user_ids: null, + external_id: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + work_email: null, + subscription_status: 1, + subscription_types: '2;3;4;5;1', + customer_fit: 2, + record_type_id: '71010794476', + whatsapp_subscription_status: 2, + sms_subscription_status: 2, + last_seen_chat: null, + first_seen_chat: null, + locale: null, + total_sessions: null, + phone_numbers: [], + sales_accounts: [ + { + partial: true, + id: 70003771198, + name: 'div-quer', + avatar: null, + website: null, + last_contacted: null, + record_type_id: '71010794477', + is_primary: true, + }, + { + partial: true, + id: 70003825177, + name: 'BisleriGroup', + avatar: null, + website: null, + last_contacted: null, + record_type_id: '71010794477', + is_primary: false, }, - status: 200 + ], }, + }, + status: 200, }, - { - httpReq: { - url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/lists', - method: 'GET' - }, - httpRes: { - data: { - "lists": [ - { - "id": 70000053624, - "name": "Sample list" - }, - { - "id": 70000056575, - "name": "list1-test" - }, - { - "id": 70000058627, - "name": "Jio 5G Group" - }, - { - "id": 70000058628, - "name": "Airtel 5G Group" - }, - { - "id": 70000059716, - "name": "Voda 5G" - } - ], - "meta": { - "total_pages": 1, - "total": 5 - } + }, + { + httpReq: { + url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/selector/sales_activity_types', + method: 'GET', + }, + httpRes: { + data: { + sales_activity_types: [ + { + partial: true, + id: 70000666879, + name: 'own-calender', + internal_name: 'cappointment', + show_in_conversation: true, + position: 1, + is_default: false, + is_checkedin: false, + }, + { + partial: true, + id: 70000663932, + name: 'fb-support', + internal_name: 'facebook', + show_in_conversation: true, + position: 2, + is_default: false, + is_checkedin: false, + }, + { + partial: true, + id: 70000663746, + name: 'twitter sales', + internal_name: 'twitter', + show_in_conversation: true, + position: 3, + is_default: false, + is_checkedin: false, + }, + { + partial: true, + id: 70000646396, + name: 'linked sales', + internal_name: 'linkedin', + show_in_conversation: true, + position: 4, + is_default: false, + is_checkedin: false, + }, + { + partial: true, + id: 70000642330, + name: 'facebook sales', + internal_name: 'facebook', + show_in_conversation: true, + position: 5, + is_default: false, + is_checkedin: false, + }, + { + partial: true, + id: 70000612897, + name: 'Chat', + internal_name: 'chat', + show_in_conversation: true, + position: 6, + is_default: true, + is_checkedin: false, + }, + { + partial: true, + id: 70000612898, + name: 'Phone', + internal_name: 'phone', + show_in_conversation: true, + position: 7, + is_default: true, + is_checkedin: false, + }, + { + partial: true, + id: 70000612899, + name: 'Meeting', + internal_name: 'appointment', + show_in_conversation: true, + position: 8, + is_default: true, + is_checkedin: true, + }, + { + partial: true, + id: 70000612900, + name: 'Task', + internal_name: 'task', + show_in_conversation: true, + position: 9, + is_default: true, + is_checkedin: false, + }, + { + partial: true, + id: 70000612901, + name: 'Email', + internal_name: 'email', + show_in_conversation: true, + position: 10, + is_default: true, + is_checkedin: false, + }, + { + partial: true, + id: 70000612902, + name: 'SMS Outgoing', + internal_name: 'sms_outgoing', + show_in_conversation: true, + position: 11, + is_default: true, + is_checkedin: false, + }, + { + partial: true, + id: 70000612903, + name: 'Reminder', + internal_name: 'reminder', + show_in_conversation: false, + position: 12, + is_default: true, + is_checkedin: false, + }, + { + partial: true, + id: 70000612904, + name: 'SMS Incoming', + internal_name: 'sms_incoming', + show_in_conversation: true, + position: 13, + is_default: true, + is_checkedin: false, + }, + ], + }, + status: 200, + }, + }, + { + httpReq: { + url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert', + method: 'POST', + }, + httpRes: { + data: { + contact: { + id: 70054866612, + first_name: null, + last_name: null, + display_name: 'jamessampleton120@gmail.com', + avatar: null, + job_title: null, + city: null, + state: null, + zipcode: null, + country: null, + email: 'jamessampleton120@gmail.com', + emails: [ + { + id: 70047409219, + value: 'jamessampleton120@gmail.com', + is_primary: true, + label: null, + _destroy: false, }, - status: 200 + ], + time_zone: null, + work_number: null, + mobile_number: null, + address: null, + last_seen: null, + lead_score: 0, + last_contacted: null, + open_deals_amount: null, + won_deals_amount: null, + links: { + conversations: + '/crm/sales/contacts/70054866612/conversations/all?include=email_conversation_recipients%2Ctargetable%2Cphone_number%2Cphone_caller%2Cnote%2Cuser&per_page=3', + timeline_feeds: '/crm/sales/contacts/70054866612/timeline_feeds', + document_associations: '/crm/sales/contacts/70054866612/document_associations', + notes: '/crm/sales/contacts/70054866612/notes?include=creater', + tasks: + '/crm/sales/contacts/70054866612/tasks?include=creater,owner,updater,targetable,users,task_type', + appointments: + '/crm/sales/contacts/70054866612/appointments?include=creater,owner,updater,targetable,appointment_attendees,conference,note', + reminders: + '/crm/sales/contacts/70054866612/reminders?include=creater,owner,updater,targetable', + duplicates: '/crm/sales/contacts/70054866612/duplicates', + connections: '/crm/sales/contacts/70054866612/connections', + }, + last_contacted_sales_activity_mode: null, + custom_field: {}, + created_at: '2022-10-11T08:42:15-04:00', + updated_at: '2022-10-11T08:42:15-04:00', + keyword: null, + medium: null, + last_contacted_mode: null, + recent_note: null, + won_deals_count: null, + last_contacted_via_sales_activity: null, + completed_sales_sequences: null, + active_sales_sequences: null, + web_form_ids: null, + open_deals_count: null, + last_assigned_at: null, + tags: [], + facebook: null, + twitter: null, + linkedin: null, + is_deleted: false, + team_user_ids: null, + external_id: null, + work_email: null, + subscription_status: 1, + subscription_types: '2;3;4;5;1', + customer_fit: 0, + record_type_id: '71012139284', + whatsapp_subscription_status: 2, + sms_subscription_status: 2, + last_seen_chat: null, + first_seen_chat: null, + locale: null, + total_sessions: null, + phone_numbers: [], }, + }, + status: 200, }, - { - httpReq: { - url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/selector/lifecycle_stages', - method: 'GET' - }, - httpRes: { - data: { - "lifecycle_stages": [ - { - "id": 71012139274, - "name": "Sales Qualified Lead start", - "position": 1, - "disabled": false, - "default": true, - "type": "Sales Qualified Lead", - "contact_status_ids": [70000697858, 70000697859, 70000697860] - }, - { - "id": 71012139273, - "name": "Lead", - "position": 2, - "disabled": false, - "default": true, - "type": "Lead", - "contact_status_ids": [70000697854, 70000697855, 70000697856, 70000697857] - }, - { - "id": 71012806409, - "name": "final Customer", - "position": 3, - "disabled": false, - "default": false, - "type": "Custom", - "contact_status_ids": [70000736543, 70000736544] - }, - { - "id": 71012139275, - "name": "Customer", - "position": 4, - "disabled": false, - "default": true, - "type": "Customer", - "contact_status_ids": [70000697861, 70000697862] - } - ] - }, - status: 200 + }, + { + httpReq: { + url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/lists', + method: 'GET', + }, + httpRes: { + data: { + lists: [ + { + id: 70000053624, + name: 'Sample list', + }, + { + id: 70000056575, + name: 'list1-test', + }, + { + id: 70000058627, + name: 'Jio 5G Group', + }, + { + id: 70000058628, + name: 'Airtel 5G Group', + }, + { + id: 70000059716, + name: 'Voda 5G', + }, + ], + meta: { + total_pages: 1, + total: 5, }, - } -]; \ No newline at end of file + }, + status: 200, + }, + }, + { + httpReq: { + url: 'https://domain-rudder.myfreshworks.com/crm/sales/api/selector/lifecycle_stages', + method: 'GET', + }, + httpRes: { + data: { + lifecycle_stages: [ + { + id: 71012139274, + name: 'Sales Qualified Lead start', + position: 1, + disabled: false, + default: true, + type: 'Sales Qualified Lead', + contact_status_ids: [70000697858, 70000697859, 70000697860], + }, + { + id: 71012139273, + name: 'Lead', + position: 2, + disabled: false, + default: true, + type: 'Lead', + contact_status_ids: [70000697854, 70000697855, 70000697856, 70000697857], + }, + { + id: 71012806409, + name: 'final Customer', + position: 3, + disabled: false, + default: false, + type: 'Custom', + contact_status_ids: [70000736543, 70000736544], + }, + { + id: 71012139275, + name: 'Customer', + position: 4, + disabled: false, + default: true, + type: 'Customer', + contact_status_ids: [70000697861, 70000697862], + }, + ], + }, + status: 200, + }, + }, +]; diff --git a/test/integrations/destinations/freshsales/processor/data.ts b/test/integrations/destinations/freshsales/processor/data.ts index e1436e12b37..eca3b88d9dd 100644 --- a/test/integrations/destinations/freshsales/processor/data.ts +++ b/test/integrations/destinations/freshsales/processor/data.ts @@ -1,2668 +1,2688 @@ export const data = [ - { - "name": "freshsales", - "description": "Track call, event is not supported.", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn" - }, - "event": { - "name": "Add to Cart" - }, - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Event is a required field and should be a string", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Identify call for creating new user", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105.myfreshworks.com" - } - }, - "message": { - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - } - }, - "traits": { - "email": "testuser@google.com", - "first_name": "Rk", - "last_name": "Mishra", - "mobileNumber": "1-926-555-9504", - "lifecycleStageId": 71010794467, - "phone": "9988776655", - "owner_id": "70000090119" - }, - "type": "identify", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "contact": { - "emails": "testuser@google.com", - "last_name": "Mishra", - "created_at": "2022-06-22T10:57:58Z", - "first_name": "Rk", - "updated_at": "2022-06-22T10:57:58Z", - "external_id": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "work_number": "9988776655", - "mobile_number": "1-926-555-9504", - "lifecycle_stage_id": 71010794467 - }, - "unique_identifier": { - "emails": "testuser@google.com" - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://rudderstack-476952domain3105.myfreshworks.com/crm/sales/api/contacts/upsert", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Identify call with numbers in lifecycleStageId, ownerId", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105.myfreshworks.com" - } - }, - "message": { - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - } - }, - "traits": { - "email": "testuser@google.com", - "first_name": "Rk", - "last_name": "Mishra", - "mobileNumber": "1-926-555-9504", - "lifecycleStageId": 71010794467, - "phone": "9988776655", - "owner_id": "70000090119" - }, - "type": "identify", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "contact": { - "emails": "testuser@google.com", - "last_name": "Mishra", - "created_at": "2022-06-22T10:57:58Z", - "first_name": "Rk", - "updated_at": "2022-06-22T10:57:58Z", - "external_id": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "work_number": "9988776655", - "mobile_number": "1-926-555-9504", - "lifecycle_stage_id": 71010794467 - }, - "unique_identifier": { - "emails": "testuser@google.com" - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://rudderstack-476952domain3105.myfreshworks.com/crm/sales/api/contacts/upsert", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Identify call with wrong data type in lifecycleStageId, ownerId", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105.myfreshworks.com" - } - }, - "message": { - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - } - }, - "traits": { - "email": "testuser@google.com", - "first_name": "Rk", - "last_name": "Mishra", - "mobileNumber": "1-926-555-9504", - "lifecycleStageId": "rudderSample", - "phone": "9988776655", - "ownerId": "rudderSample" - }, - "type": "identify", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://rudderstack-476952domain3105.myfreshworks.com/crm/sales/api/contacts/upsert", - "headers": { - "Authorization": "Token token=dummyApiKey", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "contact": { - "emails": "testuser@google.com", - "first_name": "Rk", - "last_name": "Mishra", - "work_number": "9988776655", - "external_id": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "mobile_number": "1-926-555-9504", - "created_at": "2022-06-22T10:57:58Z", - "updated_at": "2022-06-22T10:57:58Z" - }, - "unique_identifier": { - "emails": "testuser@google.com" - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Identify call, email is not provided.", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105.myfreshworks.com" - } - }, - "message": { - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - } - }, - "traits": { - "first_name": "Rk", - "last_name": "Mishra", - "mobileNumber": "1-926-555-9504", - "lifecycleStageId": "rudderSample", - "phone": "9988776655", - "owner_id": "rudderSample" - }, - "type": "identify", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Missing required value from \"email\"", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Group call: testing with mock api", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - }, - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - }, - "traits": { - "email": "testuser@google.com" - } - }, - "traits": { - "groupType": "accounts", - "name": "Mark Twain", - "phone": "919191919191", - "numberOfEmployees": 51, - "annualRevenue": 1000, - "address": "Red Colony", - "city": "Colony", - "state": "Haryana" - }, - "type": "group", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "contact": { - "sales_accounts": [ - { - "id": 70003771198, - "name": "div-quer", - "avatar": null, - "partial": true, - "website": null, - "is_primary": true, - "last_contacted": null, - "record_type_id": "71010794477" - }, - { - "id": 70003825177, - "name": "BisleriGroup", - "avatar": null, - "partial": true, - "website": null, - "is_primary": false, - "last_contacted": null, - "record_type_id": "71010794477" - }, - { - "id": 70003771396, - "is_primary": false - } - ] - }, - "unique_identifier": { - "emails": "testuser@google.com" - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Group call: name is required field.", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - }, - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - }, - "traits": { - "email": "testuser@google.com" - } - }, - "traits": { - "groupType": "accounts", - "phone": "919191919191", - "numberOfEmployees": 51, - "annualRevenue": 1000, - "address": "Red Colony", - "city": "Colony", - "state": "Haryana" - }, - "type": "group", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Missing required value from \"name\"", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "missing message type", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - }, - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - }, - "traits": { - "email": "testuser4google.com" - } - }, - "traits": { - "name": "Mark Twain", - "phone": "919191919191", - "numberOfEmployees": 51, - "annualRevenue": 1000, - "address": "Red Colony", - "city": "Colony", - "state": "Haryana" - }, - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Message Type is not present. Aborting message.", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Wrong message type", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - }, - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - }, - "traits": { - "email": "testuser4google.com" - } - }, - "traits": { - "name": "Mark Twain", - "phone": "919191919191", - "numberOfEmployees": 51, - "annualRevenue": 1000, - "address": "Red Colony", - "city": "Colony", - "state": "Haryana" - }, - "type": "page", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "message type page not supported", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Group call: user email is missing", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - }, - "message": { - "messageId": "sadjb-1e2r3fhgb-12bvbbj", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99090", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - }, - "traits": {} - }, - "traits": { - "groupType": "accounts", - "name": "div-quer", - "phone": "919191919191", - "numberOfEmployees": 51, - "annualRevenue": 1000, - "address": "Red Colony", - "city": "Lal colony", - "state": "Haryana" - }, - "type": "group", - "sentAt": "2022-04-22T10:57:58Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/sales_accounts/upsert", - "headers": { - "Authorization": "Token token=dummyApiKey", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "unique_identifier": { - "name": "div-quer" - }, - "sales_account": { - "name": "div-quer", - "phone": "919191919191", - "number_of_employees": 51, - "annual_revenue": 1000, - "address": "", - "city": "Lal colony", - "state": "Haryana", - "created_at": "2022-06-22T10:57:58Z", - "updated_at": "2022-06-22T10:57:58Z" - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Identify call: Email is not present", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2022-06-22T10:57:58Z", - "anonymousId": "ea5cfab2-3961-4d8a-8187-3d1858c99099", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "device": { - "advertisingId": "T0T0T072-5e28-45a1-9eda-ce22a3e36d1a", - "id": "3f034872-5e28-45a1-9eda-ce22a3e36d1a", - "manufacturer": "Google", - "model": "AOSP on IA Emulator", - "name": "generic_x86_arm", - "type": "ios", - "attTrackingStatus": 3 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "iOS", - "version": "14.4.1" - }, - "screen": { - "density": 2 - } - }, - "traits": { - "first_name": "Rk", - "last_name": "Narayan", - "mobileNumber": "1-926-555-9504", - "phone": "9988776655" - }, - "type": "identify", - "sentAt": "2022-04-22T10:57:58Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Missing required value from \"email\"", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Track call, event is not supported.", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn" - }, - "event": "Add to Cart", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "event name Add to Cart is not supported. Aborting!", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Track call: some required properties is missing for sales_activity", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "test@rudderstack.com", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn" - }, - "event": "sales_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Missing required value from \"properties.title\"", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Track call: for salesActivityName", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - }, - "externalId": { - "type": "Contact" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "test@rudderstack.com", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn", - "salesActivityName": "own-calender", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612" - }, - "event": "test", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com", - "rudderEventsToFreshsalesEvents": [ - { - "from": "test", - "to": "sales_activity" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "sales_activity": { - "title": "new Contact", - "created_at": "2020-10-20T08:14:28.778Z", - "end_date": "2022-06-04T17:30:00+05:30", - "owner_id": "70054866612", - "start_date": "2021-05-04T17:00:00+05:30", - "updated_at": "2020-10-20T08:14:28.778Z", - "targetable_id": 70054866612, - "targetable_type": "Contact", - "sales_activity_name": "own-calender", - "sales_activity_type_id": 70000666879 - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "userId": "", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Track call: lifecycle_stage_id", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "email": "jamessampleton3@gmail.com", - "lifecycleStageId": "71012139273", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612", - "targetableType": "Contact" - }, - "event": "lifecycle_stage", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert", - "headers": { - "Authorization": "Token token=dummyApiKey", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "contact": { - "lifecycle_stage_id": "71012139273" - }, - "unique_identifier": { - "emails": "jamessampleton3@gmail.com" - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Track call: In lifecycle stage, email is missing", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "lifecycleStageId": "71012139273", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612", - "targetableType": "Contact" - }, - "event": "lifecycle_stage", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "email is required for updating life Cycle Stages. Aborting!", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Track call: Either of lifecycleStageName or lifecycleStageId is required", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "jamessampleton3@gmail.com", - "properties": { - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612", - "targetableType": "Contact" - }, - "event": "lifecycle_stage", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Either of lifecycleStageName or lifecycleStageId is required. Aborting!", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Track call: Either of sales activity name or sales activity type id is required", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - }, - "externalId": { - "type": "Contact" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "test@rudderstack.com", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612" - }, - "event": "sales_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Either of sales activity name or sales activity type id is required. Aborting!", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Track call: Either of email or targetable_id is required for creating sales activity.", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - }, - "externalId": { - "type": "Contact" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn", - "salesActivityName": "own-calender", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612" - }, - "event": "sales_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Either of email or targetable_id is required for creating sales activity. Aborting!", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Track call: sales activity with salesActivityTypeId", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - }, - "externalId": { - "type": "Contact" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "jamessampleton3@gmail.com", - "properties": { - "salesActivityTypeId": "70000663932", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612" - }, - "event": "sales_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "sales_activity": { - "title": "new Contact", - "created_at": "2020-10-20T08:14:28.778Z", - "end_date": "2022-06-04T17:30:00+05:30", - "owner_id": "70054866612", - "start_date": "2021-05-04T17:00:00+05:30", - "updated_at": "2020-10-20T08:14:28.778Z", - "targetable_id": 70054866612, - "targetable_type": "Contact", - "sales_activity_type_id": "70000663932" - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Track call: updated sales activity with salesActivityTypeId and targetableId", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - }, - "externalId": { - "id": "70052305908", - "type": "Contact" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "salesActivityTypeId": "70000663932", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612" - }, - "event": "sales_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "sales_activity": { - "title": "new Contact", - "created_at": "2020-10-20T08:14:28.778Z", - "end_date": "2022-06-04T17:30:00+05:30", - "owner_id": "70054866612", - "start_date": "2021-05-04T17:00:00+05:30", - "updated_at": "2020-10-20T08:14:28.778Z", - "targetable_id": "70052305908", - "targetable_type": "Contact", - "sales_activity_type_id": "70000663932" - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Unsupported message Type", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "type": "page", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "jamessampleton3@gmail.com", - "properties": { - "lifecycleStageId": "71012139273", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612", - "targetableType": "Contact" - }, - "event": "lifecycle_stage", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "message type page not supported", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Track call: with wrong sales activity name", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "email": "test@rudderstack.com", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - }, - "externalId": { - "type": "Contact" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "email": "test@rudderstack.com", - "properties": { - "product_name": "Shirt", - "brand": "Wrogn", - "salesActivityName": "own-list", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612" - }, - "event": "sales_activity", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "sales Activity own-list doesn't exists. Aborting!", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Track call: update contacts with sales Activity name", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "email": "jamessampleton6@gmail.com", - "lifecycleStageName": "final Customer", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612", - "targetableType": "Contact" - }, - "event": "lifecycle_stage", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "FORM": {}, - "JSON": { - "contact": { - "lifecycle_stage_id": 71012806409 - }, - "unique_identifier": { - "emails": "jamessampleton6@gmail.com" - } - }, - "JSON_ARRAY": {} - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Content-Type": "application/json", - "Authorization": "Token token=dummyApiKey" - }, - "version": "1", - "endpoint": "https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "freshsales", - "description": "Track call: with wrong lifecycleStageName", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.5" - }, - "traits": { - "name": "Shehan Study", - "category": "SampleIdentify", - "plan": "Open source", - "logins": 5, - "createdAt": 1599264000 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.5" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 0.8999999761581421 - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content", - "name": "some campaign", - "test": "other value" - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "type": "track", - "messageId": "dd46338d-5f83-493b-bd28-3b48f55d0be8", - "originalTimestamp": "2020-10-20T08:14:28.778Z", - "anonymousId": "my-anonymous-id-new", - "userId": "newUserIdAlias", - "properties": { - "email": "jamessampleton6@gmail.com", - "lifecycleStageName": "final ExCustomer", - "title": "new Contact", - "startDate": "2021-05-04T17:00:00+05:30", - "endDate": "2022-06-04T17:30:00+05:30", - "ownerId": "70054866612", - "targetableType": "Contact" - }, - "event": "lifecycle_stage", - "previousId": "sampleusrRudder3", - "sentAt": "2020-10-20T08:14:28.778Z" - }, - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "domain": "domain-rudder.myfreshworks.com" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "failed to fetch lifeCycleStages with final ExCustomer", - "statTags": { - "destType": "FRESHSALES", - "errorCategory": "network", - "errorType": "aborted", - "feature": "processor", - "implementation": "native", - "meta": "instrumentation", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - } -] + { + name: 'freshsales', + description: 'Track call, event is not supported.', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + }, + event: { + name: 'Add to Cart', + }, + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Event is a required field and should be a string', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Identify call for creating new user', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'rudderstack-476952domain3105.myfreshworks.com', + }, + }, + message: { + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + }, + traits: { + email: 'testuser@google.com', + first_name: 'Rk', + last_name: 'Mishra', + mobileNumber: '1-926-555-9504', + lifecycleStageId: 71010794467, + phone: '9988776655', + owner_id: '70000090119', + }, + type: 'identify', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + contact: { + emails: 'testuser@google.com', + last_name: 'Mishra', + created_at: '2022-06-22T10:57:58Z', + first_name: 'Rk', + updated_at: '2022-06-22T10:57:58Z', + external_id: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + work_number: '9988776655', + mobile_number: '1-926-555-9504', + lifecycle_stage_id: 71010794467, + }, + unique_identifier: { + emails: 'testuser@google.com', + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: + 'https://rudderstack-476952domain3105.myfreshworks.com/crm/sales/api/contacts/upsert', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Identify call with numbers in lifecycleStageId, ownerId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'rudderstack-476952domain3105.myfreshworks.com', + }, + }, + message: { + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + }, + traits: { + email: 'testuser@google.com', + first_name: 'Rk', + last_name: 'Mishra', + mobileNumber: '1-926-555-9504', + lifecycleStageId: 71010794467, + phone: '9988776655', + owner_id: '70000090119', + }, + type: 'identify', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + contact: { + emails: 'testuser@google.com', + last_name: 'Mishra', + created_at: '2022-06-22T10:57:58Z', + first_name: 'Rk', + updated_at: '2022-06-22T10:57:58Z', + external_id: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + work_number: '9988776655', + mobile_number: '1-926-555-9504', + lifecycle_stage_id: 71010794467, + }, + unique_identifier: { + emails: 'testuser@google.com', + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: + 'https://rudderstack-476952domain3105.myfreshworks.com/crm/sales/api/contacts/upsert', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Identify call with wrong data type in lifecycleStageId, ownerId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'rudderstack-476952domain3105.myfreshworks.com', + }, + }, + message: { + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + }, + traits: { + email: 'testuser@google.com', + first_name: 'Rk', + last_name: 'Mishra', + mobileNumber: '1-926-555-9504', + lifecycleStageId: 'rudderSample', + phone: '9988776655', + ownerId: 'rudderSample', + }, + type: 'identify', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://rudderstack-476952domain3105.myfreshworks.com/crm/sales/api/contacts/upsert', + headers: { + Authorization: 'Token token=dummyApiKey', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + contact: { + emails: 'testuser@google.com', + first_name: 'Rk', + last_name: 'Mishra', + work_number: '9988776655', + external_id: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + mobile_number: '1-926-555-9504', + created_at: '2022-06-22T10:57:58Z', + updated_at: '2022-06-22T10:57:58Z', + }, + unique_identifier: { + emails: 'testuser@google.com', + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Identify call, email is not provided.', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'rudderstack-476952domain3105.myfreshworks.com', + }, + }, + message: { + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + }, + traits: { + first_name: 'Rk', + last_name: 'Mishra', + mobileNumber: '1-926-555-9504', + lifecycleStageId: 'rudderSample', + phone: '9988776655', + owner_id: 'rudderSample', + }, + type: 'identify', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Missing required value from "email"', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Group call: testing with mock api', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: { + email: 'testuser@google.com', + }, + }, + traits: { + groupType: 'accounts', + name: 'Mark Twain', + phone: '919191919191', + numberOfEmployees: 51, + annualRevenue: 1000, + address: 'Red Colony', + city: 'Colony', + state: 'Haryana', + }, + type: 'group', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + contact: { + sales_accounts: [ + { + id: 70003771198, + name: 'div-quer', + avatar: null, + partial: true, + website: null, + is_primary: true, + last_contacted: null, + record_type_id: '71010794477', + }, + { + id: 70003825177, + name: 'BisleriGroup', + avatar: null, + partial: true, + website: null, + is_primary: false, + last_contacted: null, + record_type_id: '71010794477', + }, + { + id: 70003771396, + is_primary: false, + }, + ], + }, + unique_identifier: { + emails: 'testuser@google.com', + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Group call: name is required field.', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: { + email: 'testuser@google.com', + }, + }, + traits: { + groupType: 'accounts', + phone: '919191919191', + numberOfEmployees: 51, + annualRevenue: 1000, + address: 'Red Colony', + city: 'Colony', + state: 'Haryana', + }, + type: 'group', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Missing required value from "name"', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'missing message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: { + email: 'testuser4google.com', + }, + }, + traits: { + name: 'Mark Twain', + phone: '919191919191', + numberOfEmployees: 51, + annualRevenue: 1000, + address: 'Red Colony', + city: 'Colony', + state: 'Haryana', + }, + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Message Type is not present. Aborting message.', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Wrong message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: { + email: 'testuser4google.com', + }, + }, + traits: { + name: 'Mark Twain', + phone: '919191919191', + numberOfEmployees: 51, + annualRevenue: 1000, + address: 'Red Colony', + city: 'Colony', + state: 'Haryana', + }, + type: 'page', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'message type page not supported', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Group call: user email is missing', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + message: { + messageId: 'sadjb-1e2r3fhgb-12bvbbj', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: {}, + }, + traits: { + groupType: 'accounts', + name: 'div-quer', + phone: '919191919191', + numberOfEmployees: 51, + annualRevenue: 1000, + address: 'Red Colony', + city: 'Lal colony', + state: 'Haryana', + }, + type: 'group', + sentAt: '2022-04-22T10:57:58Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://domain-rudder.myfreshworks.com/crm/sales/api/sales_accounts/upsert', + headers: { + Authorization: 'Token token=dummyApiKey', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + unique_identifier: { + name: 'div-quer', + }, + sales_account: { + name: 'div-quer', + phone: '919191919191', + number_of_employees: 51, + annual_revenue: 1000, + address: '', + city: 'Lal colony', + state: 'Haryana', + created_at: '2022-06-22T10:57:58Z', + updated_at: '2022-06-22T10:57:58Z', + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Identify call: Email is not present', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2022-06-22T10:57:58Z', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99099', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + }, + traits: { + first_name: 'Rk', + last_name: 'Narayan', + mobileNumber: '1-926-555-9504', + phone: '9988776655', + }, + type: 'identify', + sentAt: '2022-04-22T10:57:58Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Missing required value from "email"', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Track call, event is not supported.', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + }, + event: 'Add to Cart', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'event name Add to Cart is not supported. Aborting!', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Track call: some required properties is missing for sales_activity', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'test@rudderstack.com', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + }, + event: 'sales_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Missing required value from "properties.title"', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Track call: for salesActivityName', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + externalId: { + type: 'Contact', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'test@rudderstack.com', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + salesActivityName: 'own-calender', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + }, + event: 'test', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + rudderEventsToFreshsalesEvents: [ + { + from: 'test', + to: 'sales_activity', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + sales_activity: { + title: 'new Contact', + created_at: '2020-10-20T08:14:28.778Z', + end_date: '2022-06-04T17:30:00+05:30', + owner_id: '70054866612', + start_date: '2021-05-04T17:00:00+05:30', + updated_at: '2020-10-20T08:14:28.778Z', + targetable_id: 70054866612, + targetable_type: 'Contact', + sales_activity_name: 'own-calender', + sales_activity_type_id: 70000666879, + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + userId: '', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Track call: lifecycle_stage_id', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + email: 'jamessampleton3@gmail.com', + lifecycleStageId: '71012139273', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + targetableType: 'Contact', + }, + event: 'lifecycle_stage', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert', + headers: { + Authorization: 'Token token=dummyApiKey', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + contact: { + lifecycle_stage_id: '71012139273', + }, + unique_identifier: { + emails: 'jamessampleton3@gmail.com', + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Track call: In lifecycle stage, email is missing', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + lifecycleStageId: '71012139273', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + targetableType: 'Contact', + }, + event: 'lifecycle_stage', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'email is required for updating life Cycle Stages. Aborting!', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Track call: Either of lifecycleStageName or lifecycleStageId is required', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'jamessampleton3@gmail.com', + properties: { + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + targetableType: 'Contact', + }, + event: 'lifecycle_stage', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Either of lifecycleStageName or lifecycleStageId is required. Aborting!', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Track call: Either of sales activity name or sales activity type id is required', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + externalId: { + type: 'Contact', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'test@rudderstack.com', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + }, + event: 'sales_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Either of sales activity name or sales activity type id is required. Aborting!', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: + 'Track call: Either of email or targetable_id is required for creating sales activity.', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + externalId: { + type: 'Contact', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + salesActivityName: 'own-calender', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + }, + event: 'sales_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Either of email or targetable_id is required for creating sales activity. Aborting!', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Track call: sales activity with salesActivityTypeId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + externalId: { + type: 'Contact', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'jamessampleton3@gmail.com', + properties: { + salesActivityTypeId: '70000663932', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + }, + event: 'sales_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + sales_activity: { + title: 'new Contact', + created_at: '2020-10-20T08:14:28.778Z', + end_date: '2022-06-04T17:30:00+05:30', + owner_id: '70054866612', + start_date: '2021-05-04T17:00:00+05:30', + updated_at: '2020-10-20T08:14:28.778Z', + targetable_id: 70054866612, + targetable_type: 'Contact', + sales_activity_type_id: '70000663932', + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Track call: updated sales activity with salesActivityTypeId and targetableId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + externalId: { + id: '70052305908', + type: 'Contact', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + salesActivityTypeId: '70000663932', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + }, + event: 'sales_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + sales_activity: { + title: 'new Contact', + created_at: '2020-10-20T08:14:28.778Z', + end_date: '2022-06-04T17:30:00+05:30', + owner_id: '70054866612', + start_date: '2021-05-04T17:00:00+05:30', + updated_at: '2020-10-20T08:14:28.778Z', + targetable_id: '70052305908', + targetable_type: 'Contact', + sales_activity_type_id: '70000663932', + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/sales_activities', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Unsupported message Type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + type: 'page', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'jamessampleton3@gmail.com', + properties: { + lifecycleStageId: '71012139273', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + targetableType: 'Contact', + }, + event: 'lifecycle_stage', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'message type page not supported', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Track call: with wrong sales activity name', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + externalId: { + type: 'Contact', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + email: 'test@rudderstack.com', + properties: { + product_name: 'Shirt', + brand: 'Wrogn', + salesActivityName: 'own-list', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + }, + event: 'sales_activity', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: "sales Activity own-list doesn't exists. Aborting!", + statTags: { + destType: 'FRESHSALES', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Track call: update contacts with sales Activity name', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + email: 'jamessampleton6@gmail.com', + lifecycleStageName: 'final Customer', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + targetableType: 'Contact', + }, + event: 'lifecycle_stage', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + FORM: {}, + JSON: { + contact: { + lifecycle_stage_id: 71012806409, + }, + unique_identifier: { + emails: 'jamessampleton6@gmail.com', + }, + }, + JSON_ARRAY: {}, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Token token=dummyApiKey', + }, + version: '1', + endpoint: 'https://domain-rudder.myfreshworks.com/crm/sales/api/contacts/upsert', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'freshsales', + description: 'Track call: with wrong lifecycleStageName', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + type: 'track', + messageId: 'dd46338d-5f83-493b-bd28-3b48f55d0be8', + originalTimestamp: '2020-10-20T08:14:28.778Z', + anonymousId: 'my-anonymous-id-new', + userId: 'newUserIdAlias', + properties: { + email: 'jamessampleton6@gmail.com', + lifecycleStageName: 'final ExCustomer', + title: 'new Contact', + startDate: '2021-05-04T17:00:00+05:30', + endDate: '2022-06-04T17:30:00+05:30', + ownerId: '70054866612', + targetableType: 'Contact', + }, + event: 'lifecycle_stage', + previousId: 'sampleusrRudder3', + sentAt: '2020-10-20T08:14:28.778Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + domain: 'domain-rudder.myfreshworks.com', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'failed to fetch lifeCycleStages with final ExCustomer', + statTags: { + destType: 'FRESHSALES', + errorCategory: 'network', + errorType: 'aborted', + feature: 'processor', + implementation: 'native', + meta: 'instrumentation', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/ga/processor/data.ts b/test/integrations/destinations/ga/processor/data.ts index d2ccfa4a5b5..43a222e025f 100644 --- a/test/integrations/destinations/ga/processor/data.ts +++ b/test/integrations/destinations/ga/processor/data.ts @@ -1,9979 +1,10034 @@ export const mockFns = (_) => { - // @ts-ignore - jest - .useFakeTimers() - .setSystemTime(new Date('2023-09-29')); + // @ts-ignore + jest.useFakeTimers().setSystemTime(new Date('2023-09-29')); }; export const data = [ - { - "name": "ga", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "externalId": [ - { - "id": "lynnanderson@smith.net", - "identifierType": "device_id", - "type": "AM-users" - } - ], - "mappedToDestination": "true", - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "anonymousId": "123456", - "email": "test@rudderstack.com", - "address": { - "country": "India", - "postalCode": 712136, - "state": "WB", - "street": "", - "os_version": "test os" - }, - "ip": "0.0.0.0", - "age": 26 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "page": { - "path": "/destinations/amplitude", - "referrer": "", - "search": "", - "title": "", - "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", - "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com" - } - }, - "traits": { - "anonymousId": "123456", - "email": "test@rudderstack.com", - "city": "kolkata", - "address": { - "country": "India", - "postalCode": 712136, - "state": "WB", - "street": "" - }, - "os_version": "test os", - "ip": "0.0.0.0", - "age": 26, - "an": "Test App name", - "ul": "Test ul" - }, - "type": "identify", - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "123456", - "userId": "123456", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "name", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "name", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "action1", - "ec": "All", - "ni": 1, - "ul": "Test ul", - "an": "Test App name", - "cm1": "test@rudderstack.com", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "uid": "123456", - "cid": "123456", - "uip": "0.0.0.0", - "qt": 124901802438 - }, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "123456" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "traits": { - "name": "Rudder Test" - }, - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "properties": { - "plan": "standard plan", - "name": "rudder test" - }, - "type": "identify", - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "123456", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "name", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "name", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "action1", - "ec": "Rudder Test", - "cd1": "Rudder Test", - "cg2": "Rudder Test", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "uid": "123456", - "cid": "00000000000000000000000000", - "ni": 1, - "uip": "0.0.0.0", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "qt": 124893881701 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "page", - "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "properties": { - "path": "/abc", - "referrer": "q", - "search": "", - "title": "a", - "url": "https://www.example.com/abc" - }, - "integrations": { - "All": true - }, - "name": "ApplicationLoaded", - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "v": "1", - "t": "pageview", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "uip": "0.0.0.0", - "ul": "en-US", - "dh": "www.example.com", - "dl": "https://www.example.com/abc", - "dp": "%2Fabc", - "dr": "q", - "dt": "a", - "qt": 124893881701 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "test track event GA3", - "properties": { - "category": "test-category", - "user_actual_role": "system_admin, system_user", - "user_actual_id": 12345 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ec": "test-category", - "ni": 1, - "v": "1", - "el": "event", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "test track event GA3", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order completed", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "purchase", - "tr": 99.99, - "ev": 100, - "pr1id": "p-298", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr2id": "p-299", - "pr2cd1": "other product", - "pr2nm": "other product", - "pr2pr": 24.75, - "ea": "order completed", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ti": "rudderstackorder1", - "ts": 13.99, - "tt": 20.99, - "cu": "INR", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ni": 1, - "pr1qt": 1, - "pr2qt": 3, - "ul": "en-US", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 5", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product added", - "properties": { - "currency": "CAD", - "quantity": 1, - "price": 24.75, - "name": "my product 1", - "category": "cat 1", - "sku": "p-298", - "testDimension": true, - "testMetric": true, - "position": 4.5 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product added", - "ec": "cat 1", - "pa": "add", - "pr1cd1": "my product 1", - "pr1id": "p-298", - "cd1": "my product 1", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "pr1nm": "my product 1", - "pr1ca": "cat 1", - "cu": "CAD", - "pr1ps": 4.5, - "pr1pr": 24.75, - "pr1qt": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ni": 1, - "ul": "en-US", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 6", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product removed", - "properties": { - "currency": "CAD", - "quantity": 1, - "price": 24.75, - "name": "my product 1", - "category": "cat 1", - "sku": "p-298", - "testDimension": true, - "testMetric": true, - "position": 4.5 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product removed", - "ec": "cat 1", - "pa": "remove", - "pr1cd1": "my product 1", - "pr1id": "p-298", - "cd1": "my product 1", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "pr1nm": "my product 1", - "pr1ca": "cat 1", - "cu": "CAD", - "pr1ps": 4.5, - "pr1pr": 24.75, - "pr1qt": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 7", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product viewed", - "properties": { - "currency": "CAD", - "quantity": 1, - "price": 24.75, - "name": "my product 1", - "category": "cat 1", - "sku": "p-298", - "testDimension": true, - "testMetric": true, - "position": 4.5 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product viewed", - "ec": "cat 1", - "pa": "detail", - "pr1cd1": "my product 1", - "pr1id": "p-298", - "cd1": "my product 1", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "pr1nm": "my product 1", - "pr1ca": "cat 1", - "cu": "CAD", - "pr1ps": 4.5, - "pr1pr": 24.75, - "pr1qt": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 8", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product removed", - "properties": { - "currency": "CAD", - "quantity": 1, - "price": 24.75, - "name": "my product 1", - "category": "cat 1", - "sku": "p-298", - "testDimension": true, - "testMetric": true, - "position": 4.5 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product removed", - "ec": "cat 1", - "pa": "remove", - "pr1cd1": "my product 1", - "pr1id": "p-298", - "cd1": "my product 1", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "pr1nm": "my product 1", - "pr1ca": "cat 1", - "cu": "CAD", - "pr1ps": 4.5, - "pr1pr": 24.75, - "pr1qt": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881701 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 9", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product viewed", - "properties": { - "currency": "CAD", - "quantity": 1, - "price": 24.75, - "name": "my product 1", - "category": "cat 1", - "sku": "p-298", - "testDimension": true, - "testMetric": true, - "position": 4.5 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product viewed", - "ec": "cat 1", - "pa": "detail", - "pr1cd1": "my product 1", - "pr1id": "p-298", - "cd1": "my product 1", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "pr1nm": "my product 1", - "pr1ca": "cat 1", - "cu": "CAD", - "pr1ps": 4.5, - "pr1pr": 24.75, - "pr1qt": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 10", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product list filtered", - "properties": { - "category": "cat 1", - "list_id": "1234", - "filters": [ - { - "type": "department", - "value": "beauty" - }, - { - "type": "price", - "value": "under" - } - ], - "sorts": [ - { - "type": "price", - "value": "desc" - } - ], - "products": [ - { - "product_id": "507f1f77bcf86cd799439011", - "productDimension": "My Product Dimension", - "productMetric": "My Product Metric" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product list filtered", - "ec": "cat 1", - "pa": "detail", - "il1pi1id": "507f1f77bcf86cd799439011", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "il1nm": "1234", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "il1pi1qt": 1, - "il1pi1va": "department:beauty,price:under::price:desc", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 11", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product list viewed", - "properties": { - "category": "cat 1", - "list_id": "1234", - "filters": [ - { - "type": "department", - "value": "beauty" - }, - { - "type": "price", - "value": "under" - } - ], - "sorts": [ - { - "type": "price", - "value": "desc" - } - ], - "products": [ - { - "product_id": "507f1f77bcf86cd799439011", - "productDimension": "My Product Dimension", - "productMetric": "My Product Metric", - "position": 10 - }, - { - "product_id": "507f1f77bcf86cdef799439011", - "productDimension": "My Product Dimension1", - "productMetric": "My Product Metric1", - "position": -10 - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product list viewed", - "ec": "cat 1", - "pa": "detail", - "il1pi1id": "507f1f77bcf86cd799439011", - "il1pi1ps": 10, - "il1pi2id": "507f1f77bcf86cdef799439011", - "il1pi2ps": -10, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "il1nm": "1234", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "il1pi1qt": 1, - "il1pi1va": "department:beauty,price:under::price:desc", - "il1pi2qt": 1, - "il1pi2va": "department:beauty,price:under::price:desc", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 12", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product clicked", - "properties": { - "currency": "CAD", - "quantity": 1, - "price": 24.75, - "name": "my product", - "category": "cat 1", - "sku": "p-298", - "list": "search results", - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product clicked", - "ec": "cat 1", - "pa": "click", - "pr1cd1": "my product", - "pr1id": "p-298", - "cd1": "my product", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "pr1nm": "my product", - "pr1ca": "cat 1", - "cu": "CAD", - "pr1pr": 24.75, - "pr1qt": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "pal": "search results", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 13", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "promotion viewed", - "properties": { - "currency": "CAD", - "promotion_id": "PROMO_1234", - "name": "my product", - "creative": "summer_banner2", - "position": "banner_slot1", - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "promotion viewed", - "ec": "EnhancedEcommerce", - "cu": "CAD", - "promoa": "view", - "pa": "view", - "cd1": "my product", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "promo1id": "PROMO_1234", - "promo1cr": "summer_banner2", - "promo1ps": "banner_slot1", - "promo1nm": "my product", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 14", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "promotion clicked", - "properties": { - "currency": "CAD", - "promotion_id": "PROMO_1234", - "name": "my product", - "creative": "summer_banner2", - "position": "banner_slot1", - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "promotion clicked", - "ec": "EnhancedEcommerce", - "cu": "CAD", - "promoa": "promo_click", - "pa": "promo_click", - "cd1": "my product", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "promo1id": "PROMO_1234", - "promo1cr": "summer_banner2", - "promo1ps": "banner_slot1", - "promo1nm": "my product", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 15", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "checkout started", - "properties": { - "currency": "CAD", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298" - }, - { - "quantity": 1, - "price": 24.75, - "name": "my product 2", - "sku": "p-299" - } - ], - "step": 1, - "paymentMethod": "Visa", - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "checkout", - "pr1id": "p-298", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr2id": "p-299", - "pr2cd1": "my product 2", - "pr2nm": "my product 2", - "pr2pr": 24.75, - "ea": "checkout started", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "cu": "CAD", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "cos": 1, - "pr1qt": 1, - "pr2qt": 1, - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 16", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order updated", - "properties": { - "currency": "CAD", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298" - }, - { - "quantity": 1, - "price": 24.75, - "name": "my product 2", - "sku": "p-299" - } - ], - "step": 1, - "paymentMethod": "Visa", - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "checkout", - "pr1id": "p-298", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr2id": "p-299", - "pr2cd1": "my product 2", - "pr2nm": "my product 2", - "pr2pr": 24.75, - "ea": "order updated", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "cu": "CAD", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "cos": 1, - "pr1qt": 1, - "pr2qt": 1, - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 17", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "checkout step viewed", - "properties": { - "currency": "CAD", - "step": 1 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "checkout", - "ea": "checkout step viewed", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "cos": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 18", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "checkout step completed", - "properties": { - "currency": "CAD", - "step": 1, - "paymentMethod": "Visa" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "checkout_option", - "ea": "checkout step completed", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "cos": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 19", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order refunded", - "properties": { - "products": [ - { - "quantity": 1, - "sku": "p-298" - }, - { - "quantity": 1, - "sku": "p-299" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "order refunded", - "ec": "EnhancedEcommerce", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "pa": "refund", - "pr1id": "p-298", - "pr1qt": 1, - "pr2id": "p-299", - "ul": "en-US", - "pr2qt": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 20", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order starterefundedd", - "properties": { - "products": [ - { - "quantity": 1, - "sku": "p-298" - }, - { - "quantity": 1, - "sku": "p-299" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "order starterefundedd", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 21", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order starterefundedd", - "properties": { - "products": [ - { - "quantity": 1, - "sku": "p-298" - }, - { - "quantity": 1, - "sku": "p-299" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "order starterefundedd", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 22", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order starterefundedd", - "properties": { - "products": [ - { - "quantity": 1, - "sku": "p-298" - }, - { - "quantity": 1, - "sku": "p-299" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "order starterefundedd", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 23", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order starterefundedd", - "properties": { - "products": [ - { - "quantity": 1, - "sku": "p-298" - }, - { - "quantity": 1, - "sku": "p-299" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "cid": "00000000000000000000000000", - "ea": "order starterefundedd", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 24", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order starterefundedd", - "properties": { - "products": [ - { - "quantity": 1, - "sku": "p-298" - }, - { - "quantity": 1, - "sku": "p-299" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "order starterefundedd", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 25", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "linkid test", - "properties": { - "linkid": "abc123", - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "linkid": "abc123", - "cid": "00000000000000000000000000", - "ea": "linkid test", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 26", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "campaign": { - "name": "sampleName", - "source": "sampleSource", - "medium": "sampleMedium", - "content": "sampleContent", - "term": "sampleTerm" - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "campaign test", - "properties": { - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "cn": "sampleName", - "cs": "sampleSource", - "cm": "sampleMedium", - "cc": "sampleContent", - "ck": "sampleTerm", - "cid": "00000000000000000000000000", - "ea": "campaign test", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 27", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "campaign": { - "name": "sampleName", - "source": "sampleSource", - "medium": "sampleMedium", - "content": "sampleContent", - "term": "sampleTerm" - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "event": "campaign test", - "properties": { - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "cn": "sampleName", - "cs": "sampleSource", - "cm": "sampleMedium", - "cc": "sampleContent", - "ck": "sampleTerm", - "cid": "00000000000000000000000000", - "ea": "campaign test", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 28", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "campaign": { - "name": "sampleName", - "source": "sampleSource", - "medium": "sampleMedium", - "content": "sampleContent", - "term": "sampleTerm" - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "event": "campaign test", - "properties": { - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "cn": "sampleName", - "cs": "sampleSource", - "cm": "sampleMedium", - "cc": "sampleContent", - "ck": "sampleTerm", - "cid": "00000000000000000000000000", - "ea": "campaign test", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 29", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.2" - }, - "traits": { - "abc": "1234" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.2" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36", - "locale": "en-GB", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "page": { - "path": "/tests/html/ecomm_test.html", - "referrer": "http://0.0.0.0:1112/tests/html/", - "search": "", - "title": "GA Ecommerce Test", - "url": "http://0.0.0.0:1112/tests/html/ecomm_test.html" - } - }, - "type": "identify", - "messageId": "bc8a6af8-37fd-46a9-9592-ea29a256435f", - "originalTimestamp": "2020-06-22T11:30:32.493Z", - "anonymousId": "38e169a1-3234-46f7-9ceb-c1a6a69005fe", - "userId": "123", - "integrations": { - "All": true - }, - "sentAt": "2020-06-22T11:30:32.494Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "User Enriched", - "dt": "GA Ecommerce Test", - "ec": "All", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.1.2", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "uid": "123", - "cid": "38e169a1-3234-46f7-9ceb-c1a6a69005fe", - "ni": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36", - "ul": "en-GB", - "qt": 103120167507 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "38e169a1-3234-46f7-9ceb-c1a6a69005fe" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 30", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "page", - "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "integrations": { - "All": true - }, - "name": "ApplicationLoaded", - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "v": "1", - "t": "pageview", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "uip": "0.0.0.0", - "qt": 124893881701 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 31", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "page", - "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "properties": { - "path": "/abc", - "referrer": "", - "search": "?xyz=1", - "title": "", - "url": "https://www.example.com/abc" - }, - "integrations": { - "All": true - }, - "name": "ApplicationLoaded", - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "v": "1", - "t": "pageview", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "uip": "0.0.0.0", - "dh": "www.example.com", - "dl": "https://www.example.com/abc", - "dp": "%2Fabc%3Fxyz%3D1", - "qt": 124893881701 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 32", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "integrations": { - "All": true - }, - "event": "sample event", - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "sample event", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "uip": "0.0.0.0", - "qt": 124893881701 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 33", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Refunded", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "refund", - "ev": 100, - "pr1id": "p-298", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr1qt": 1, - "pr2id": "p-299", - "pr2cd1": "other product", - "pr2nm": "other product", - "pr2pr": 24.75, - "pr2qt": 3, - "ea": "Order Refunded", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "ti": "rudderstackorder1", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 34", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Refunded", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ev": 100, - "pa": "refund", - "ti": "rudderstackorder1", - "ea": "Order Refunded", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 35", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Refunded", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ev": 100, - "pa": "refund", - "ti": "rudderstackorder1", - "ea": "Order Refunded", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 36", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Refunded", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ev": 100, - "pa": "refund", - "pr1id": "1", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr1qt": 1, - "pr2id": "2", - "pr2cd1": "other product", - "pr2nm": "other product", - "pr2pr": 24.75, - "pr2qt": 3, - "ea": "Order Refunded", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "ti": "rudderstackorder1", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 37", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Cart Shared", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ev": 100, - "ea": "Cart Shared", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "st": " 1 2", - "ul": "en-US", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 38", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Product Shared", - "properties": { - "product_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "url": "https://www.example.com/abc" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ev": 100, - "ea": "Product Shared", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "st": "https://www.example.com/abc", - "dh": "www.example.com", - "dl": "https://www.example.com/abc", - "dp": "%2Fabc", - "ul": "en-US", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 39", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Product List Clicked", - "properties": { - "list_id": "Sample Product List", - "category": "Sample Product List", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "Product List Clicked", - "ec": "Sample Product List", - "pa": "click", - "il1pi1id": "1", - "pr1cd1": "my product", - "il1pi1nm": "my product", - "il1pi1pr": 24.75, - "il1pi2id": "2", - "pr2cd1": "other product", - "il1pi2nm": "other product", - "il1pi2pr": 24.75, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "il1nm": "Sample Product List", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "ni": 1, - "il1pi2qt": 3, - "il1pi1qt": 1, - "ul": "en-US", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 40", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Product List Clicked", - "properties": { - "list_id": "Sample Product List", - "category": "Sample Product List", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "Product List Clicked", - "ec": "Sample Product List", - "pa": "click", - "il1pi1id": "p-298", - "pr1cd1": "my product", - "il1pi1nm": "my product", - "il1pi1pr": 24.75, - "il1pi2id": "p-299", - "pr2cd1": "other product", - "il1pi2nm": "other product", - "il1pi2pr": 24.75, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "il1nm": "Sample Product List", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "ul": "en-US", - "il1pi2qt": 3, - "il1pi1qt": 1, - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 41", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Product List Clicked", - "properties": { - "list_id": "Sample Product List", - "category": "Sample Product List", - "products": [] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ni": 1, - "ea": "Product List Clicked", - "ec": "Sample Product List", - "pa": "click", - "el": "event", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "il1nm": "Sample Product List", - "uid": "12345", - "cid": "00000000000000000000000000", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 42", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Cancelled", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "refund", - "ev": 100, - "tr": 99.99, - "pr1id": "1", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr2id": "2", - "pr2cd1": "other product", - "pr2nm": "other product", - "pr2pr": 24.75, - "ea": "Order Cancelled", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ti": "rudderstackorder1", - "ts": 13.99, - "tt": 20.99, - "cu": "INR", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "pr1qt": 1, - "pr2qt": 3, - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 43", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Cancelled", - "properties": { - "order_id": "rudderstackorder1", - "value": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "refund", - "tr": 99.99, - "pr1id": "1", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr2id": "2", - "pr2cd1": "other product", - "pr2nm": "other product", - "pr2pr": 24.75, - "ea": "Order Cancelled", - "ev": 100, - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ti": "rudderstackorder1", - "ts": 13.99, - "tt": 20.99, - "cu": "INR", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "pr1qt": 1, - "pr2qt": 3, - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 44", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Cancelled", - "properties": { - "order_id": "rudderstackorder1", - "revenue": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "refund", - "tr": 99.99, - "pr1id": "1", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr2id": "2", - "pr2cd1": "other product", - "pr2nm": "other product", - "pr2pr": 24.75, - "ea": "Order Cancelled", - "ev": 100, - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ti": "rudderstackorder1", - "ts": 13.99, - "tt": 20.99, - "cu": "INR", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "pr1qt": 1, - "pr2qt": 3, - "ni": 1, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 45", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Cancelled", - "properties": { - "order_id": "rudderstackorder1", - "revenue": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "No product information supplied for transaction event", - "statTags": { - "destType": "GA", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 46", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Cart Viewed", - "properties": { - "order_id": "rudderstackorder1", - "revenue": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "Cart Viewed", - "ev": 100, - "ec": "EnhancedEcommerce", - "pa": "detail", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "pr1cd1": "my product", - "pr1id": "1", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr1qt": 1, - "pr2cd1": "other product", - "pr2id": "2", - "pr2nm": "other product", - "pr2pr": 24.75, - "pr2qt": 3, - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 47", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "traits": { - "name1": "Test" - }, - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "properties": { - "plan": "standard plan", - "name": "rudder test" - }, - "type": "identify", - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "00000000000000000000000000", - "userId": "123456", - "integrations": { - "All": true - }, - "traits": { - "name1": "Test" - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "serverSideIdentifyEventCategory": "name", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "server side identify is not on", - "statTags": { - "destType": "GA", - "errorCategory": "dataValidation", - "errorType": "configuration", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 48", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "screen", - "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "properties": { - "name": "homescreen" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "cd1": "homescreen", - "v": "1", - "t": "screenview", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "cd": "homescreen", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "uip": "0.0.0.0", - "qt": 124893881701 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 49", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "newtype", - "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "properties": { - "name": "homescreen" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Message type newtype not supported", - "statTags": { - "destType": "GA", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 50", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "traits": { - "name": "Test" - }, - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "properties": { - "plan": "standard plan", - "name": "rudder test" - }, - "type": "identify", - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "userId": "12345", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "name", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "userId": "12345", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "action1", - "ec": "Test", - "ni": 1, - "cd1": "Test", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "uid": "12345", - "cid": "827ccb0eea8a706c4c34a16891f84e7b", - "uip": "0.0.0.0", - "qt": 124901802438 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {} - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 51", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "traits": { - "name": "Test" - }, - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "properties": { - "plan": "standard plan", - "name": "rudder test" - }, - "type": "identify", - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "userId": "12345", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "name", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "disableMd5": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "userId": "12345", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "action1", - "ec": "Test", - "ni": 1, - "cd1": "Test", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "uid": "12345", - "uip": "0.0.0.0", - "qt": 124901802438 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {} - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 52", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "traits": { - "name": "Test" - }, - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "properties": { - "plan": "standard plan", - "name": "rudder test" - }, - "type": "identify", - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "userId": "12345", - "integrations": { - "All": true, - "GA": { - "clientId": "clientId" - }, - "Google Analytics": { - "clientId": "clientId" - } - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "name", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "userId": "12345", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "action1", - "ec": "Test", - "ni": 1, - "cd1": "Test", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "uid": "12345", - "cid": "clientId", - "uip": "0.0.0.0", - "qt": 124901802438 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {} - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 53", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "externalId": [ - { - "id": "externalClientId", - "type": "gaExternalId" - } - ], - "traits": { - "name": "Test" - }, - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "properties": { - "plan": "standard plan", - "name": "rudder test" - }, - "type": "identify", - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "userId": "12345", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "name", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "userId": "12345", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "action1", - "ec": "Test", - "ni": 1, - "cd1": "Test", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "uid": "12345", - "cid": "externalClientId", - "uip": "0.0.0.0", - "qt": 124901802438 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {} - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 54", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product list viewed", - "properties": { - "nonInteraction": 0, - "category": "cat 1", - "list_id": "1234", - "filters": { - "a": "department", - "b": "beauty" - }, - "sorts": [ - { - "type": "price", - "value": "desc" - } - ], - "products": [ - { - "product_id": "507f1f77bcf86cd799439011", - "productDimension": "My Product Dimension", - "productMetric": "My Product Metric", - "position": 10 - }, - { - "product_id": "507f1f77bcf86cdef799439011", - "productDimension": "My Product Dimension1", - "productMetric": "My Product Metric1", - "position": -10 - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "content1" - }, - { - "from": "prop2", - "to": "content2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ni": 0, - "ea": "product list viewed", - "ec": "cat 1", - "pa": "detail", - "il1pi1id": "507f1f77bcf86cd799439011", - "il1pi1va": "::price:desc", - "il1pi1ps": 10, - "il1pi1qt": 1, - "il1pi2id": "507f1f77bcf86cdef799439011", - "il1pi2va": "::price:desc", - "il1pi2ps": -10, - "il1pi2qt": 1, - "el": "event", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "il1nm": "1234", - "uid": "12345", - "cid": "00000000000000000000000000", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga", - "description": "Test 55", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "page", - "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "properties": { - "referrer": "https://google.com/answer/7554821?zippy=%2Cfields-in-event-snippets-for-counter-tags%2Cstep-add-the-global-snippet-to-every-page-of-your-site%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-tg%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learns-more-about-the-global-site-tag%2Cwhy-is-the-globalthe-head-when-iframe-and-image-tags-were-placed-in-the-body-placed-of-my-site%2Cwhere-can-i-learn-g2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-and-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-n-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag", - "search": "", - "title": "a", - "url": "https://support.google.com/campaignmanager/answer/7554821?zippy=%2Cfields-in-event-snippets-for-counter-tags%2Cstep-add-the-global-snippet-to-every-page-of-your-site%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-lakjsdlkfjalsdkfjis-the-global-site-tag-placed-in-the-head-lakjsdlkfjalsdkfjis-the-global-site-tag-placed-in-the-head-lakjsdlkfjalsdkfjakljshdlfkjahsldkfjahlskdfjhaklsjdfhalksjdhflakjshdflakjsdhfklasjhdflaksjhdflaksjdfhlakjshdflakjsdhfklasjhdflaksjhdflaksjdfhlakjshdflakjsdhfklasjhdflaksjhdflaksjdfhljkkwoipqpweoirpoqiwerpoqi1111111111111" - }, - "integrations": { - "All": true - }, - "name": "ApplicationLoaded", - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "anonymizeIp": false, - "eventDeliveryTS": 1657516676962, - "eventFilteringOption": "disable", - "trackingID": "UA-165994240-1" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "dp": "%2Fcampaignmanager%2Fanswer%2F7554821", - "dl": "https://support.google.com/campaignmanager/answer/7554821?zippy=%2Cfields-in-event-snippets-for-counter-tags%2Cstep-add-the-global-snippet-to-every-page-of-your-site%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-lakjsdlkfjalsdkfjis-the-global-site-tag-placed-in-the-head-lakjsdlkfjalsdkfjis-the-global-site-tag-placed-in-the-head-lakjsdlkfjalsdkfjakljshdlfkjahsldkfjahlskdfjhaklsjdfhalksjdhflakjshdflakjsdhfklasjhdflaksjhdflaksjdfhlakjshdflakjsdhfklasjhdflaksjhdflaksjdfhlakjshdflakjsdhfklasjhdflaksjhdflaksjdfhljkkwoipqpweoirpoqiwerpoqi1111111111111", - "dh": "support.google.com", - "dt": "a", - "dr": "https://google.com/answer/7554821?zippy=%2Cfields-in-event-snippets-for-counter-tags%2Cstep-add-the-global-snippet-to-every-page-of-your-site%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-tg%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learns-more-about-the-global-site-tag%2Cwhy-is-the-globalthe-head-when-iframe-and-image-tags-were-placed-in-the-body-placed-of-my-site%2Cwhere-can-i-learn-g2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-and-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-n-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag", - "v": "1", - "t": "pageview", - "tid": "UA-165994240-1", - "ds": "web", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "cid": "00000000000000000000000000", - "uip": "0.0.0.0", - "qt": 124893881701 - }, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - } -].map((d) => ({ ...d, mockFns })) + { + name: 'ga', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + externalId: [ + { + id: 'lynnanderson@smith.net', + identifierType: 'device_id', + type: 'AM-users', + }, + ], + mappedToDestination: 'true', + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + anonymousId: '123456', + email: 'test@rudderstack.com', + address: { + country: 'India', + postalCode: 712136, + state: 'WB', + street: '', + os_version: 'test os', + }, + ip: '0.0.0.0', + age: 26, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + page: { + path: '/destinations/amplitude', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/amplitude', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + }, + traits: { + anonymousId: '123456', + email: 'test@rudderstack.com', + city: 'kolkata', + address: { + country: 'India', + postalCode: 712136, + state: 'WB', + street: '', + }, + os_version: 'test os', + ip: '0.0.0.0', + age: 26, + an: 'Test App name', + ul: 'Test ul', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + userId: '123456', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'name', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'name', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'action1', + ec: 'All', + ni: 1, + ul: 'Test ul', + an: 'Test App name', + cm1: 'test@rudderstack.com', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + uid: '123456', + cid: '123456', + uip: '0.0.0.0', + qt: 124901802438, + }, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '123456', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + name: 'Rudder Test', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '123456', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'name', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'name', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'action1', + ec: 'Rudder Test', + cd1: 'Rudder Test', + cg2: 'Rudder Test', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + uid: '123456', + cid: '00000000000000000000000000', + ni: 1, + uip: '0.0.0.0', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + qt: 124893881701, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'page', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + path: '/abc', + referrer: 'q', + search: '', + title: 'a', + url: 'https://www.example.com/abc', + }, + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + v: '1', + t: 'pageview', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + uip: '0.0.0.0', + ul: 'en-US', + dh: 'www.example.com', + dl: 'https://www.example.com/abc', + dp: '%2Fabc', + dr: 'q', + dt: 'a', + qt: 124893881701, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'test track event GA3', + properties: { + category: 'test-category', + user_actual_role: 'system_admin, system_user', + user_actual_id: 12345, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ec: 'test-category', + ni: 1, + v: '1', + el: 'event', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ea: 'test track event GA3', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order completed', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'purchase', + tr: 99.99, + ev: 100, + pr1id: 'p-298', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr2id: 'p-299', + pr2cd1: 'other product', + pr2nm: 'other product', + pr2pr: 24.75, + ea: 'order completed', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ti: 'rudderstackorder1', + ts: 13.99, + tt: 20.99, + cu: 'INR', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ni: 1, + pr1qt: 1, + pr2qt: 3, + ul: 'en-US', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product added', + properties: { + currency: 'CAD', + quantity: 1, + price: 24.75, + name: 'my product 1', + category: 'cat 1', + sku: 'p-298', + testDimension: true, + testMetric: true, + position: 4.5, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product added', + ec: 'cat 1', + pa: 'add', + pr1cd1: 'my product 1', + pr1id: 'p-298', + cd1: 'my product 1', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + pr1nm: 'my product 1', + pr1ca: 'cat 1', + cu: 'CAD', + pr1ps: 4.5, + pr1pr: 24.75, + pr1qt: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ni: 1, + ul: 'en-US', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 6', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product removed', + properties: { + currency: 'CAD', + quantity: 1, + price: 24.75, + name: 'my product 1', + category: 'cat 1', + sku: 'p-298', + testDimension: true, + testMetric: true, + position: 4.5, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product removed', + ec: 'cat 1', + pa: 'remove', + pr1cd1: 'my product 1', + pr1id: 'p-298', + cd1: 'my product 1', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + pr1nm: 'my product 1', + pr1ca: 'cat 1', + cu: 'CAD', + pr1ps: 4.5, + pr1pr: 24.75, + pr1qt: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 7', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product viewed', + properties: { + currency: 'CAD', + quantity: 1, + price: 24.75, + name: 'my product 1', + category: 'cat 1', + sku: 'p-298', + testDimension: true, + testMetric: true, + position: 4.5, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product viewed', + ec: 'cat 1', + pa: 'detail', + pr1cd1: 'my product 1', + pr1id: 'p-298', + cd1: 'my product 1', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + pr1nm: 'my product 1', + pr1ca: 'cat 1', + cu: 'CAD', + pr1ps: 4.5, + pr1pr: 24.75, + pr1qt: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 8', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product removed', + properties: { + currency: 'CAD', + quantity: 1, + price: 24.75, + name: 'my product 1', + category: 'cat 1', + sku: 'p-298', + testDimension: true, + testMetric: true, + position: 4.5, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product removed', + ec: 'cat 1', + pa: 'remove', + pr1cd1: 'my product 1', + pr1id: 'p-298', + cd1: 'my product 1', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + pr1nm: 'my product 1', + pr1ca: 'cat 1', + cu: 'CAD', + pr1ps: 4.5, + pr1pr: 24.75, + pr1qt: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881701, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 9', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product viewed', + properties: { + currency: 'CAD', + quantity: 1, + price: 24.75, + name: 'my product 1', + category: 'cat 1', + sku: 'p-298', + testDimension: true, + testMetric: true, + position: 4.5, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product viewed', + ec: 'cat 1', + pa: 'detail', + pr1cd1: 'my product 1', + pr1id: 'p-298', + cd1: 'my product 1', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + pr1nm: 'my product 1', + pr1ca: 'cat 1', + cu: 'CAD', + pr1ps: 4.5, + pr1pr: 24.75, + pr1qt: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 10', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product list filtered', + properties: { + category: 'cat 1', + list_id: '1234', + filters: [ + { + type: 'department', + value: 'beauty', + }, + { + type: 'price', + value: 'under', + }, + ], + sorts: [ + { + type: 'price', + value: 'desc', + }, + ], + products: [ + { + product_id: '507f1f77bcf86cd799439011', + productDimension: 'My Product Dimension', + productMetric: 'My Product Metric', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product list filtered', + ec: 'cat 1', + pa: 'detail', + il1pi1id: '507f1f77bcf86cd799439011', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + il1nm: '1234', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + il1pi1qt: 1, + il1pi1va: 'department:beauty,price:under::price:desc', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 11', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product list viewed', + properties: { + category: 'cat 1', + list_id: '1234', + filters: [ + { + type: 'department', + value: 'beauty', + }, + { + type: 'price', + value: 'under', + }, + ], + sorts: [ + { + type: 'price', + value: 'desc', + }, + ], + products: [ + { + product_id: '507f1f77bcf86cd799439011', + productDimension: 'My Product Dimension', + productMetric: 'My Product Metric', + position: 10, + }, + { + product_id: '507f1f77bcf86cdef799439011', + productDimension: 'My Product Dimension1', + productMetric: 'My Product Metric1', + position: -10, + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product list viewed', + ec: 'cat 1', + pa: 'detail', + il1pi1id: '507f1f77bcf86cd799439011', + il1pi1ps: 10, + il1pi2id: '507f1f77bcf86cdef799439011', + il1pi2ps: -10, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + il1nm: '1234', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + il1pi1qt: 1, + il1pi1va: 'department:beauty,price:under::price:desc', + il1pi2qt: 1, + il1pi2va: 'department:beauty,price:under::price:desc', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 12', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product clicked', + properties: { + currency: 'CAD', + quantity: 1, + price: 24.75, + name: 'my product', + category: 'cat 1', + sku: 'p-298', + list: 'search results', + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product clicked', + ec: 'cat 1', + pa: 'click', + pr1cd1: 'my product', + pr1id: 'p-298', + cd1: 'my product', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + pr1nm: 'my product', + pr1ca: 'cat 1', + cu: 'CAD', + pr1pr: 24.75, + pr1qt: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + pal: 'search results', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 13', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'promotion viewed', + properties: { + currency: 'CAD', + promotion_id: 'PROMO_1234', + name: 'my product', + creative: 'summer_banner2', + position: 'banner_slot1', + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'promotion viewed', + ec: 'EnhancedEcommerce', + cu: 'CAD', + promoa: 'view', + pa: 'view', + cd1: 'my product', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + promo1id: 'PROMO_1234', + promo1cr: 'summer_banner2', + promo1ps: 'banner_slot1', + promo1nm: 'my product', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 14', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'promotion clicked', + properties: { + currency: 'CAD', + promotion_id: 'PROMO_1234', + name: 'my product', + creative: 'summer_banner2', + position: 'banner_slot1', + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'promotion clicked', + ec: 'EnhancedEcommerce', + cu: 'CAD', + promoa: 'promo_click', + pa: 'promo_click', + cd1: 'my product', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + promo1id: 'PROMO_1234', + promo1cr: 'summer_banner2', + promo1ps: 'banner_slot1', + promo1nm: 'my product', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 15', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'checkout started', + properties: { + currency: 'CAD', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + }, + { + quantity: 1, + price: 24.75, + name: 'my product 2', + sku: 'p-299', + }, + ], + step: 1, + paymentMethod: 'Visa', + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'checkout', + pr1id: 'p-298', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr2id: 'p-299', + pr2cd1: 'my product 2', + pr2nm: 'my product 2', + pr2pr: 24.75, + ea: 'checkout started', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + cu: 'CAD', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + cos: 1, + pr1qt: 1, + pr2qt: 1, + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 16', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order updated', + properties: { + currency: 'CAD', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + }, + { + quantity: 1, + price: 24.75, + name: 'my product 2', + sku: 'p-299', + }, + ], + step: 1, + paymentMethod: 'Visa', + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'checkout', + pr1id: 'p-298', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr2id: 'p-299', + pr2cd1: 'my product 2', + pr2nm: 'my product 2', + pr2pr: 24.75, + ea: 'order updated', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + cu: 'CAD', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + cos: 1, + pr1qt: 1, + pr2qt: 1, + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 17', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'checkout step viewed', + properties: { + currency: 'CAD', + step: 1, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'checkout', + ea: 'checkout step viewed', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + cos: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 18', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'checkout step completed', + properties: { + currency: 'CAD', + step: 1, + paymentMethod: 'Visa', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'checkout_option', + ea: 'checkout step completed', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + cos: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 19', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order refunded', + properties: { + products: [ + { + quantity: 1, + sku: 'p-298', + }, + { + quantity: 1, + sku: 'p-299', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ea: 'order refunded', + ec: 'EnhancedEcommerce', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + pa: 'refund', + pr1id: 'p-298', + pr1qt: 1, + pr2id: 'p-299', + ul: 'en-US', + pr2qt: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 20', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order starterefundedd', + properties: { + products: [ + { + quantity: 1, + sku: 'p-298', + }, + { + quantity: 1, + sku: 'p-299', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ea: 'order starterefundedd', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 21', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order starterefundedd', + properties: { + products: [ + { + quantity: 1, + sku: 'p-298', + }, + { + quantity: 1, + sku: 'p-299', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ea: 'order starterefundedd', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 22', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order starterefundedd', + properties: { + products: [ + { + quantity: 1, + sku: 'p-298', + }, + { + quantity: 1, + sku: 'p-299', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + aip: 1, + cid: '00000000000000000000000000', + ea: 'order starterefundedd', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 23', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order starterefundedd', + properties: { + products: [ + { + quantity: 1, + sku: 'p-298', + }, + { + quantity: 1, + sku: 'p-299', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + cid: '00000000000000000000000000', + ea: 'order starterefundedd', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 24', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order starterefundedd', + properties: { + products: [ + { + quantity: 1, + sku: 'p-298', + }, + { + quantity: 1, + sku: 'p-299', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ea: 'order starterefundedd', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 25', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'linkid test', + properties: { + linkid: 'abc123', + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + linkid: 'abc123', + cid: '00000000000000000000000000', + ea: 'linkid test', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 26', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + campaign: { + name: 'sampleName', + source: 'sampleSource', + medium: 'sampleMedium', + content: 'sampleContent', + term: 'sampleTerm', + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'campaign test', + properties: { + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + cn: 'sampleName', + cs: 'sampleSource', + cm: 'sampleMedium', + cc: 'sampleContent', + ck: 'sampleTerm', + cid: '00000000000000000000000000', + ea: 'campaign test', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 27', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + campaign: { + name: 'sampleName', + source: 'sampleSource', + medium: 'sampleMedium', + content: 'sampleContent', + term: 'sampleTerm', + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + event: 'campaign test', + properties: { + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + cn: 'sampleName', + cs: 'sampleSource', + cm: 'sampleMedium', + cc: 'sampleContent', + ck: 'sampleTerm', + cid: '00000000000000000000000000', + ea: 'campaign test', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 28', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + campaign: { + name: 'sampleName', + source: 'sampleSource', + medium: 'sampleMedium', + content: 'sampleContent', + term: 'sampleTerm', + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + event: 'campaign test', + properties: { + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + cn: 'sampleName', + cs: 'sampleSource', + cm: 'sampleMedium', + cc: 'sampleContent', + ck: 'sampleTerm', + cid: '00000000000000000000000000', + ea: 'campaign test', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 29', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.2', + }, + traits: { + abc: '1234', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.2', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36', + locale: 'en-GB', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + page: { + path: '/tests/html/ecomm_test.html', + referrer: 'http://0.0.0.0:1112/tests/html/', + search: '', + title: 'GA Ecommerce Test', + url: 'http://0.0.0.0:1112/tests/html/ecomm_test.html', + }, + }, + type: 'identify', + messageId: 'bc8a6af8-37fd-46a9-9592-ea29a256435f', + originalTimestamp: '2020-06-22T11:30:32.493Z', + anonymousId: '38e169a1-3234-46f7-9ceb-c1a6a69005fe', + userId: '123', + integrations: { + All: true, + }, + sentAt: '2020-06-22T11:30:32.494Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'User Enriched', + dt: 'GA Ecommerce Test', + ec: 'All', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.1.2', + aiid: 'com.rudderlabs.javascript', + npa: 1, + uid: '123', + cid: '38e169a1-3234-46f7-9ceb-c1a6a69005fe', + ni: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36', + ul: 'en-GB', + qt: 103120167507, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '38e169a1-3234-46f7-9ceb-c1a6a69005fe', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 30', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'page', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + v: '1', + t: 'pageview', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + uip: '0.0.0.0', + qt: 124893881701, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 31', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'page', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + path: '/abc', + referrer: '', + search: '?xyz=1', + title: '', + url: 'https://www.example.com/abc', + }, + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + v: '1', + t: 'pageview', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + uip: '0.0.0.0', + dh: 'www.example.com', + dl: 'https://www.example.com/abc', + dp: '%2Fabc%3Fxyz%3D1', + qt: 124893881701, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 32', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + integrations: { + All: true, + }, + event: 'sample event', + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ea: 'sample event', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + uip: '0.0.0.0', + qt: 124893881701, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 33', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Refunded', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'refund', + ev: 100, + pr1id: 'p-298', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr1qt: 1, + pr2id: 'p-299', + pr2cd1: 'other product', + pr2nm: 'other product', + pr2pr: 24.75, + pr2qt: 3, + ea: 'Order Refunded', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + ti: 'rudderstackorder1', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 34', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Refunded', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ev: 100, + pa: 'refund', + ti: 'rudderstackorder1', + ea: 'Order Refunded', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 35', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Refunded', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ev: 100, + pa: 'refund', + ti: 'rudderstackorder1', + ea: 'Order Refunded', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 36', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Refunded', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ev: 100, + pa: 'refund', + pr1id: '1', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr1qt: 1, + pr2id: '2', + pr2cd1: 'other product', + pr2nm: 'other product', + pr2pr: 24.75, + pr2qt: 3, + ea: 'Order Refunded', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + ti: 'rudderstackorder1', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 37', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Cart Shared', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ev: 100, + ea: 'Cart Shared', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + st: ' 1 2', + ul: 'en-US', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 38', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Product Shared', + properties: { + product_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + url: 'https://www.example.com/abc', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ev: 100, + ea: 'Product Shared', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + st: 'https://www.example.com/abc', + dh: 'www.example.com', + dl: 'https://www.example.com/abc', + dp: '%2Fabc', + ul: 'en-US', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 39', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Product List Clicked', + properties: { + list_id: 'Sample Product List', + category: 'Sample Product List', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'Product List Clicked', + ec: 'Sample Product List', + pa: 'click', + il1pi1id: '1', + pr1cd1: 'my product', + il1pi1nm: 'my product', + il1pi1pr: 24.75, + il1pi2id: '2', + pr2cd1: 'other product', + il1pi2nm: 'other product', + il1pi2pr: 24.75, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + il1nm: 'Sample Product List', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + ni: 1, + il1pi2qt: 3, + il1pi1qt: 1, + ul: 'en-US', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 40', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Product List Clicked', + properties: { + list_id: 'Sample Product List', + category: 'Sample Product List', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'Product List Clicked', + ec: 'Sample Product List', + pa: 'click', + il1pi1id: 'p-298', + pr1cd1: 'my product', + il1pi1nm: 'my product', + il1pi1pr: 24.75, + il1pi2id: 'p-299', + pr2cd1: 'other product', + il1pi2nm: 'other product', + il1pi2pr: 24.75, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + il1nm: 'Sample Product List', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + ul: 'en-US', + il1pi2qt: 3, + il1pi1qt: 1, + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 41', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Product List Clicked', + properties: { + list_id: 'Sample Product List', + category: 'Sample Product List', + products: [], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ni: 1, + ea: 'Product List Clicked', + ec: 'Sample Product List', + pa: 'click', + el: 'event', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + il1nm: 'Sample Product List', + uid: '12345', + cid: '00000000000000000000000000', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 42', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Cancelled', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'refund', + ev: 100, + tr: 99.99, + pr1id: '1', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr2id: '2', + pr2cd1: 'other product', + pr2nm: 'other product', + pr2pr: 24.75, + ea: 'Order Cancelled', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ti: 'rudderstackorder1', + ts: 13.99, + tt: 20.99, + cu: 'INR', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + pr1qt: 1, + pr2qt: 3, + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 43', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Cancelled', + properties: { + order_id: 'rudderstackorder1', + value: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'refund', + tr: 99.99, + pr1id: '1', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr2id: '2', + pr2cd1: 'other product', + pr2nm: 'other product', + pr2pr: 24.75, + ea: 'Order Cancelled', + ev: 100, + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ti: 'rudderstackorder1', + ts: 13.99, + tt: 20.99, + cu: 'INR', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + pr1qt: 1, + pr2qt: 3, + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 44', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Cancelled', + properties: { + order_id: 'rudderstackorder1', + revenue: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'refund', + tr: 99.99, + pr1id: '1', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr2id: '2', + pr2cd1: 'other product', + pr2nm: 'other product', + pr2pr: 24.75, + ea: 'Order Cancelled', + ev: 100, + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ti: 'rudderstackorder1', + ts: 13.99, + tt: 20.99, + cu: 'INR', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + pr1qt: 1, + pr2qt: 3, + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 45', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Cancelled', + properties: { + order_id: 'rudderstackorder1', + revenue: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'No product information supplied for transaction event', + statTags: { + destType: 'GA', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 46', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Cart Viewed', + properties: { + order_id: 'rudderstackorder1', + revenue: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'Cart Viewed', + ev: 100, + ec: 'EnhancedEcommerce', + pa: 'detail', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + ul: 'en-US', + ni: 1, + pr1cd1: 'my product', + pr1id: '1', + pr1nm: 'my product', + pr1pr: 24.75, + pr1qt: 1, + pr2cd1: 'other product', + pr2id: '2', + pr2nm: 'other product', + pr2pr: 24.75, + pr2qt: 3, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 47', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + name1: 'Test', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '00000000000000000000000000', + userId: '123456', + integrations: { + All: true, + }, + traits: { + name1: 'Test', + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + serverSideIdentifyEventCategory: 'name', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'server side identify is not on', + statTags: { + destType: 'GA', + errorCategory: 'dataValidation', + errorType: 'configuration', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 48', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'screen', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + name: 'homescreen', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + cd1: 'homescreen', + v: '1', + t: 'screenview', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + cd: 'homescreen', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + uip: '0.0.0.0', + qt: 124893881701, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 49', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'newtype', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + name: 'homescreen', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Message type newtype not supported', + statTags: { + destType: 'GA', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 50', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + name: 'Test', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + userId: '12345', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'name', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + userId: '12345', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'action1', + ec: 'Test', + ni: 1, + cd1: 'Test', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + uid: '12345', + cid: '827ccb0eea8a706c4c34a16891f84e7b', + uip: '0.0.0.0', + qt: 124901802438, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 51', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + name: 'Test', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + userId: '12345', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'name', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + disableMd5: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + userId: '12345', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'action1', + ec: 'Test', + ni: 1, + cd1: 'Test', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + uid: '12345', + uip: '0.0.0.0', + qt: 124901802438, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 52', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + name: 'Test', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + userId: '12345', + integrations: { + All: true, + GA: { + clientId: 'clientId', + }, + 'Google Analytics': { + clientId: 'clientId', + }, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'name', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + userId: '12345', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'action1', + ec: 'Test', + ni: 1, + cd1: 'Test', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + uid: '12345', + cid: 'clientId', + uip: '0.0.0.0', + qt: 124901802438, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 53', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + externalId: [ + { + id: 'externalClientId', + type: 'gaExternalId', + }, + ], + traits: { + name: 'Test', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + userId: '12345', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'name', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + userId: '12345', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'action1', + ec: 'Test', + ni: 1, + cd1: 'Test', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + uid: '12345', + cid: 'externalClientId', + uip: '0.0.0.0', + qt: 124901802438, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 54', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product list viewed', + properties: { + nonInteraction: 0, + category: 'cat 1', + list_id: '1234', + filters: { + a: 'department', + b: 'beauty', + }, + sorts: [ + { + type: 'price', + value: 'desc', + }, + ], + products: [ + { + product_id: '507f1f77bcf86cd799439011', + productDimension: 'My Product Dimension', + productMetric: 'My Product Metric', + position: 10, + }, + { + product_id: '507f1f77bcf86cdef799439011', + productDimension: 'My Product Dimension1', + productMetric: 'My Product Metric1', + position: -10, + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'content1', + }, + { + from: 'prop2', + to: 'content2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ni: 0, + ea: 'product list viewed', + ec: 'cat 1', + pa: 'detail', + il1pi1id: '507f1f77bcf86cd799439011', + il1pi1va: '::price:desc', + il1pi1ps: 10, + il1pi1qt: 1, + il1pi2id: '507f1f77bcf86cdef799439011', + il1pi2va: '::price:desc', + il1pi2ps: -10, + il1pi2qt: 1, + el: 'event', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + il1nm: '1234', + uid: '12345', + cid: '00000000000000000000000000', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga', + description: 'Test 55', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'page', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + referrer: + 'https://google.com/answer/7554821?zippy=%2Cfields-in-event-snippets-for-counter-tags%2Cstep-add-the-global-snippet-to-every-page-of-your-site%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-tg%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learns-more-about-the-global-site-tag%2Cwhy-is-the-globalthe-head-when-iframe-and-image-tags-were-placed-in-the-body-placed-of-my-site%2Cwhere-can-i-learn-g2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-and-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-n-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag', + search: '', + title: 'a', + url: 'https://support.google.com/campaignmanager/answer/7554821?zippy=%2Cfields-in-event-snippets-for-counter-tags%2Cstep-add-the-global-snippet-to-every-page-of-your-site%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-lakjsdlkfjalsdkfjis-the-global-site-tag-placed-in-the-head-lakjsdlkfjalsdkfjis-the-global-site-tag-placed-in-the-head-lakjsdlkfjalsdkfjakljshdlfkjahsldkfjahlskdfjhaklsjdfhalksjdhflakjshdflakjsdhfklasjhdflaksjhdflaksjdfhlakjshdflakjsdhfklasjhdflaksjhdflaksjdfhlakjshdflakjsdhfklasjhdflaksjhdflaksjdfhljkkwoipqpweoirpoqiwerpoqi1111111111111', + }, + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + anonymizeIp: false, + eventDeliveryTS: 1657516676962, + eventFilteringOption: 'disable', + trackingID: 'UA-165994240-1', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + dp: '%2Fcampaignmanager%2Fanswer%2F7554821', + dl: 'https://support.google.com/campaignmanager/answer/7554821?zippy=%2Cfields-in-event-snippets-for-counter-tags%2Cstep-add-the-global-snippet-to-every-page-of-your-site%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-lakjsdlkfjalsdkfjis-the-global-site-tag-placed-in-the-head-lakjsdlkfjalsdkfjis-the-global-site-tag-placed-in-the-head-lakjsdlkfjalsdkfjakljshdlfkjahsldkfjahlskdfjhaklsjdfhalksjdhflakjshdflakjsdhfklasjhdflaksjhdflaksjdfhlakjshdflakjsdhfklasjhdflaksjhdflaksjdfhlakjshdflakjsdhfklasjhdflaksjhdflaksjdfhljkkwoipqpweoirpoqiwerpoqi1111111111111', + dh: 'support.google.com', + dt: 'a', + dr: 'https://google.com/answer/7554821?zippy=%2Cfields-in-event-snippets-for-counter-tags%2Cstep-add-the-global-snippet-to-every-page-of-your-site%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cstep-add-the-event-snippet-to-pages-with-events-youre-tracking%2Cfields-in-the-global-snippet%2Cfields-in-the-event-snippet---overview%2Cfields-in-all-event-snippets%2Cexample-event-snippet-for-counter---standard-activities%2Cexample-event-snippet-for-counter---unique-activities%2Cexample-event-snippet-for-counter---per-session-activities%2Cfields-in-event-snippets-for-sales-tags%2Cexample-event-snippet-for-sales---transaction-activities%2Cexample-event-snippet-for-sales---items-sold-activities%2Ccustom-fields%2Cnoscript-section-of-event-snippets%2Cdo-i-need-to-set-up-cache-busting-with-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-tg%2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learns-more-about-the-global-site-tag%2Cwhy-is-the-globalthe-head-when-iframe-and-image-tags-were-placed-in-the-body-placed-of-my-site%2Cwhere-can-i-learn-g2Cwhy-is-the-global-site-tag-placed-in-the-head-when-iframe-and-and-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag%2Cwhy-n-the-head-when-iframe-and-image-tags-were-placed-in-the-body-of-my-site%2Cwhere-can-i-learn-more-about-the-global-site-tag', + v: '1', + t: 'pageview', + tid: 'UA-165994240-1', + ds: 'web', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + cid: '00000000000000000000000000', + uip: '0.0.0.0', + qt: 124893881701, + }, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, +].map((d) => ({ ...d, mockFns })); diff --git a/test/integrations/destinations/ga360/processor/data.ts b/test/integrations/destinations/ga360/processor/data.ts index 66de4079ff9..40b3495062d 100644 --- a/test/integrations/destinations/ga360/processor/data.ts +++ b/test/integrations/destinations/ga360/processor/data.ts @@ -1,9456 +1,9507 @@ export const mockFns = (_) => { // @ts-ignore - jest - .useFakeTimers() - .setSystemTime(new Date('2023-09-29')); + jest.useFakeTimers().setSystemTime(new Date('2023-09-29')); }; export const data = [ { - "name": "ga360", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "traits": { - "name": "Rudder Test" - }, - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "properties": { - "plan": "standard plan", - "name": "rudder test" - }, - "type": "identify", - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "00000000000000000000000000", - "userId": "123456", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "name", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "name", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + name: 'Rudder Test', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '00000000000000000000000000', + userId: '123456', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'name', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'name', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'action1', + ec: 'Rudder Test', + cd1: 'Rudder Test', + cg2: 'Rudder Test', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + uid: '123456', + cid: '00000000000000000000000000', + ni: 1, + uip: '0.0.0.0', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + qt: 124901802438, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'page', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + path: '/abc', + referrer: 'q', + search: '', + title: 'a', + url: 'https://www.example.com/abc', + }, + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + v: '1', + t: 'pageview', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + uip: '0.0.0.0', + ul: 'en-US', + dh: 'www.example.com', + dl: 'https://www.example.com/abc', + dp: '%2Fabc', + dr: 'q', + dt: 'a', + qt: 124893881701, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'test track event GA3', + properties: { + category: 'test-category', + user_actual_role: 'system_admin, system_user', + user_actual_id: 12345, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ec: 'test-category', + ni: 1, + v: '1', + el: 'event', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ea: 'test track event GA3', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order completed', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'purchase', + tr: 99.99, + ev: 100, + pr1id: 'p-298', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr2id: 'p-299', + pr2cd1: 'other product', + pr2nm: 'other product', + pr2pr: 24.75, + ea: 'order completed', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ti: 'rudderstackorder1', + ts: 13.99, + tt: 20.99, + cu: 'INR', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ni: 1, + pr1qt: 1, + pr2qt: 3, + ul: 'en-US', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product added', + properties: { + currency: 'CAD', + quantity: 1, + price: 24.75, + name: 'my product 1', + category: 'cat 1', + sku: 'p-298', + testDimension: true, + testMetric: true, + position: 4.5, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product added', + ec: 'cat 1', + pa: 'add', + pr1cd1: 'my product 1', + pr1id: 'p-298', + cd1: 'my product 1', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + pr1nm: 'my product 1', + pr1ca: 'cat 1', + cu: 'CAD', + pr1ps: 4.5, + pr1pr: 24.75, + pr1qt: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ni: 1, + ul: 'en-US', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product removed', + properties: { + currency: 'CAD', + quantity: 1, + price: 24.75, + name: 'my product 1', + category: 'cat 1', + sku: 'p-298', + testDimension: true, + testMetric: true, + position: 4.5, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product removed', + ec: 'cat 1', + pa: 'remove', + pr1cd1: 'my product 1', + pr1id: 'p-298', + cd1: 'my product 1', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + pr1nm: 'my product 1', + pr1ca: 'cat 1', + cu: 'CAD', + pr1ps: 4.5, + pr1pr: 24.75, + pr1qt: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 6', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product viewed', + properties: { + currency: 'CAD', + quantity: 1, + price: 24.75, + name: 'my product 1', + category: 'cat 1', + sku: 'p-298', + testDimension: true, + testMetric: true, + position: 4.5, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product viewed', + ec: 'cat 1', + pa: 'detail', + pr1cd1: 'my product 1', + pr1id: 'p-298', + cd1: 'my product 1', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + pr1nm: 'my product 1', + pr1ca: 'cat 1', + cu: 'CAD', + pr1ps: 4.5, + pr1pr: 24.75, + pr1qt: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 7', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product removed', + properties: { + currency: 'CAD', + quantity: 1, + price: 24.75, + name: 'my product 1', + category: 'cat 1', + sku: 'p-298', + testDimension: true, + testMetric: true, + position: 4.5, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product removed', + ec: 'cat 1', + pa: 'remove', + pr1cd1: 'my product 1', + pr1id: 'p-298', + cd1: 'my product 1', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + pr1nm: 'my product 1', + pr1ca: 'cat 1', + cu: 'CAD', + pr1ps: 4.5, + pr1pr: 24.75, + pr1qt: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 8', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product viewed', + properties: { + currency: 'CAD', + quantity: 1, + price: 24.75, + name: 'my product 1', + category: 'cat 1', + sku: 'p-298', + testDimension: true, + testMetric: true, + position: 4.5, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product viewed', + ec: 'cat 1', + pa: 'detail', + pr1cd1: 'my product 1', + pr1id: 'p-298', + cd1: 'my product 1', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + pr1nm: 'my product 1', + pr1ca: 'cat 1', + cu: 'CAD', + pr1ps: 4.5, + pr1pr: 24.75, + pr1qt: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 9', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product list filtered', + properties: { + category: 'cat 1', + list_id: '1234', + filters: [ + { + type: 'department', + value: 'beauty', + }, + { + type: 'price', + value: 'under', + }, + ], + sorts: [ + { + type: 'price', + value: 'desc', + }, + ], + products: [ + { + product_id: '507f1f77bcf86cd799439011', + productDimension: 'My Product Dimension', + productMetric: 'My Product Metric', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product list filtered', + ec: 'cat 1', + pa: 'detail', + il1pi1id: '507f1f77bcf86cd799439011', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + il1nm: '1234', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + il1pi1qt: 1, + il1pi1va: 'department:beauty,price:under::price:desc', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 10', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product list viewed', + properties: { + category: 'cat 1', + list_id: '1234', + filters: [ + { + type: 'department', + value: 'beauty', + }, + { + type: 'price', + value: 'under', + }, + ], + sorts: [ + { + type: 'price', + value: 'desc', + }, + ], + products: [ + { + product_id: '507f1f77bcf86cd799439011', + productDimension: 'My Product Dimension', + productMetric: 'My Product Metric', + position: 10, + }, + { + product_id: '507f1f77bcf86cdef799439011', + productDimension: 'My Product Dimension1', + productMetric: 'My Product Metric1', + position: -10, + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product list viewed', + ec: 'cat 1', + pa: 'detail', + il1pi1id: '507f1f77bcf86cd799439011', + il1pi1ps: 10, + il1pi2id: '507f1f77bcf86cdef799439011', + il1pi2ps: -10, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + il1nm: '1234', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + il1pi1qt: 1, + il1pi1va: 'department:beauty,price:under::price:desc', + il1pi2qt: 1, + il1pi2va: 'department:beauty,price:under::price:desc', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 11', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'product clicked', + properties: { + currency: 'CAD', + quantity: 1, + price: 24.75, + name: 'my product', + category: 'cat 1', + sku: 'p-298', + list: 'search results', + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'product clicked', + ec: 'cat 1', + pa: 'click', + pr1cd1: 'my product', + pr1id: 'p-298', + cd1: 'my product', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + pr1nm: 'my product', + pr1ca: 'cat 1', + cu: 'CAD', + pr1pr: 24.75, + pr1qt: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + pal: 'search results', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 12', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'promotion viewed', + properties: { + currency: 'CAD', + promotion_id: 'PROMO_1234', + name: 'my product', + creative: 'summer_banner2', + position: 'banner_slot1', + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'promotion viewed', + ec: 'EnhancedEcommerce', + cu: 'CAD', + promoa: 'view', + pa: 'view', + cd1: 'my product', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + promo1id: 'PROMO_1234', + promo1cr: 'summer_banner2', + promo1ps: 'banner_slot1', + promo1nm: 'my product', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 13', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'promotion clicked', + properties: { + currency: 'CAD', + promotion_id: 'PROMO_1234', + name: 'my product', + creative: 'summer_banner2', + position: 'banner_slot1', + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'promotion clicked', + ec: 'EnhancedEcommerce', + cu: 'CAD', + promoa: 'promo_click', + pa: 'promo_click', + cd1: 'my product', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + promo1id: 'PROMO_1234', + promo1cr: 'summer_banner2', + promo1ps: 'banner_slot1', + promo1nm: 'my product', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 14', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'checkout started', + properties: { + currency: 'CAD', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + }, + { + quantity: 1, + price: 24.75, + name: 'my product 2', + sku: 'p-299', + }, + ], + step: 1, + paymentMethod: 'Visa', + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'checkout', + pr1id: 'p-298', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr2id: 'p-299', + pr2cd1: 'my product 2', + pr2nm: 'my product 2', + pr2pr: 24.75, + ea: 'checkout started', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + cu: 'CAD', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + cos: 1, + pr1qt: 1, + pr2qt: 1, + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 15', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order updated', + properties: { + currency: 'CAD', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + }, + { + quantity: 1, + price: 24.75, + name: 'my product 2', + sku: 'p-299', + }, + ], + step: 1, + paymentMethod: 'Visa', + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'checkout', + pr1id: 'p-298', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr2id: 'p-299', + pr2cd1: 'my product 2', + pr2nm: 'my product 2', + pr2pr: 24.75, + ea: 'order updated', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + cu: 'CAD', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + cos: 1, + pr1qt: 1, + pr2qt: 1, + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 16', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'checkout step viewed', + properties: { + currency: 'CAD', + step: 1, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'checkout', + ea: 'checkout step viewed', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + cos: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 17', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'checkout step completed', + properties: { + currency: 'CAD', + step: 1, + paymentMethod: 'Visa', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'checkout_option', + ea: 'checkout step completed', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + cos: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 18', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order refunded', + properties: { + products: [ + { + quantity: 1, + sku: 'p-298', + }, + { + quantity: 1, + sku: 'p-299', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ea: 'order refunded', + ec: 'EnhancedEcommerce', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + pa: 'refund', + pr1id: 'p-298', + pr1qt: 1, + pr2id: 'p-299', + ul: 'en-US', + pr2qt: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 19', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order starterefundedd', + properties: { + products: [ + { + quantity: 1, + sku: 'p-298', + }, + { + quantity: 1, + sku: 'p-299', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ea: 'order starterefundedd', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 20', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order starterefundedd', + properties: { + products: [ + { + quantity: 1, + sku: 'p-298', + }, + { + quantity: 1, + sku: 'p-299', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ea: 'order starterefundedd', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 21', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order starterefundedd', + properties: { + products: [ + { + quantity: 1, + sku: 'p-298', + }, + { + quantity: 1, + sku: 'p-299', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "action1", - "ec": "Rudder Test", - "cd1": "Rudder Test", - "cg2": "Rudder Test", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "uid": "123456", - "cid": "00000000000000000000000000", - "ni": 1, - "uip": "0.0.0.0", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "qt": 124901802438 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + aip: 1, + cid: '00000000000000000000000000', + ea: 'order starterefundedd', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, }, { - "name": "ga360", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "page", - "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "properties": { - "path": "/abc", - "referrer": "q", - "search": "", - "title": "a", - "url": "https://www.example.com/abc" - }, - "integrations": { - "All": true - }, - "name": "ApplicationLoaded", - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 22', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order starterefundedd', + properties: { + products: [ + { + quantity: 1, + sku: 'p-298', + }, + { + quantity: 1, + sku: 'p-299', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + cid: '00000000000000000000000000', + ea: 'order starterefundedd', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "v": "1", - "t": "pageview", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "uip": "0.0.0.0", - "ul": "en-US", - "dh": "www.example.com", - "dl": "https://www.example.com/abc", - "dp": "%2Fabc", - "dr": "q", - "dt": "a", - "qt": 124893881701, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "test track event GA3", - "properties": { - "category": "test-category", - "user_actual_role": "system_admin, system_user", - "user_actual_id": 12345 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 23', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order starterefundedd', + properties: { + products: [ + { + quantity: 1, + sku: 'p-298', + }, + { + quantity: 1, + sku: 'p-299', + }, + ], + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ea: 'order starterefundedd', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ec": "test-category", - "ni": 1, - "v": "1", - "el": "event", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "test track event GA3", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order completed", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 24', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'linkid test', + properties: { + linkid: 'abc123', + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + linkid: 'abc123', + cid: '00000000000000000000000000', + ea: 'linkid test', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "purchase", - "tr": 99.99, - "ev": 100, - "pr1id": "p-298", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr2id": "p-299", - "pr2cd1": "other product", - "pr2nm": "other product", - "pr2pr": 24.75, - "ea": "order completed", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ti": "rudderstackorder1", - "ts": 13.99, - "tt": 20.99, - "cu": "INR", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ni": 1, - "pr1qt": 1, - "pr2qt": 3, - "ul": "en-US", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product added", - "properties": { - "currency": "CAD", - "quantity": 1, - "price": 24.75, - "name": "my product 1", - "category": "cat 1", - "sku": "p-298", - "testDimension": true, - "testMetric": true, - "position": 4.5 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 25', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + campaign: { + name: 'sampleName', + source: 'sampleSource', + medium: 'sampleMedium', + content: 'sampleContent', + term: 'sampleTerm', + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'campaign test', + properties: { + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + cn: 'sampleName', + cs: 'sampleSource', + cm: 'sampleMedium', + cc: 'sampleContent', + ck: 'sampleTerm', + cid: '00000000000000000000000000', + ea: 'campaign test', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 26', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + campaign: { + name: 'sampleName', + source: 'sampleSource', + medium: 'sampleMedium', + content: 'sampleContent', + term: 'sampleTerm', + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + event: 'campaign test', + properties: { + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + cn: 'sampleName', + cs: 'sampleSource', + cm: 'sampleMedium', + cc: 'sampleContent', + ck: 'sampleTerm', + cid: '00000000000000000000000000', + ea: 'campaign test', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 27', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + campaign: { + name: 'sampleName', + source: 'sampleSource', + medium: 'sampleMedium', + content: 'sampleContent', + term: 'sampleTerm', + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + event: 'campaign test', + properties: { + testDimension: true, + testMetric: true, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ul: 'en-US', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + cn: 'sampleName', + cs: 'sampleSource', + cm: 'sampleMedium', + cc: 'sampleContent', + ck: 'sampleTerm', + cid: '00000000000000000000000000', + ea: 'campaign test', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 28', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.2', + }, + traits: { + abc: '1234', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.2', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36', + locale: 'en-GB', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + page: { + path: '/tests/html/ecomm_test.html', + referrer: 'http://0.0.0.0:1112/tests/html/', + search: '', + title: 'GA Ecommerce Test', + url: 'http://0.0.0.0:1112/tests/html/ecomm_test.html', + }, + }, + type: 'identify', + messageId: 'bc8a6af8-37fd-46a9-9592-ea29a256435f', + originalTimestamp: '2020-06-22T11:30:32.493Z', + anonymousId: '38e169a1-3234-46f7-9ceb-c1a6a69005fe', + userId: '123', + integrations: { + All: true, + }, + sentAt: '2020-06-22T11:30:32.494Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'User Enriched', + dt: 'GA Ecommerce Test', + ec: 'All', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.1.2', + aiid: 'com.rudderlabs.javascript', + npa: 1, + uid: '123', + cid: '38e169a1-3234-46f7-9ceb-c1a6a69005fe', + ni: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36', + ul: 'en-GB', + qt: 103120167507, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '38e169a1-3234-46f7-9ceb-c1a6a69005fe', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'ga360', + description: 'Test 29', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'page', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product added", - "ec": "cat 1", - "pa": "add", - "pr1cd1": "my product 1", - "pr1id": "p-298", - "cd1": "my product 1", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "pr1nm": "my product 1", - "pr1ca": "cat 1", - "cu": "CAD", - "pr1ps": 4.5, - "pr1pr": 24.75, - "pr1qt": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ni": 1, - "ul": "en-US", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 5", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product removed", - "properties": { - "currency": "CAD", - "quantity": 1, - "price": 24.75, - "name": "my product 1", - "category": "cat 1", - "sku": "p-298", - "testDimension": true, - "testMetric": true, - "position": 4.5 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + v: '1', + t: 'pageview', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + uip: '0.0.0.0', + qt: 124893881701, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product removed", - "ec": "cat 1", - "pa": "remove", - "pr1cd1": "my product 1", - "pr1id": "p-298", - "cd1": "my product 1", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "pr1nm": "my product 1", - "pr1ca": "cat 1", - "cu": "CAD", - "pr1ps": 4.5, - "pr1pr": 24.75, - "pr1qt": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 6", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product viewed", - "properties": { - "currency": "CAD", - "quantity": 1, - "price": 24.75, - "name": "my product 1", - "category": "cat 1", - "sku": "p-298", - "testDimension": true, - "testMetric": true, - "position": 4.5 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 30', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'page', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + path: '/abc', + referrer: '', + search: '?xyz=1', + title: '', + url: 'https://www.example.com/abc', + }, + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product viewed", - "ec": "cat 1", - "pa": "detail", - "pr1cd1": "my product 1", - "pr1id": "p-298", - "cd1": "my product 1", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "pr1nm": "my product 1", - "pr1ca": "cat 1", - "cu": "CAD", - "pr1ps": 4.5, - "pr1pr": 24.75, - "pr1qt": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 7", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product removed", - "properties": { - "currency": "CAD", - "quantity": 1, - "price": 24.75, - "name": "my product 1", - "category": "cat 1", - "sku": "p-298", - "testDimension": true, - "testMetric": true, - "position": 4.5 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + v: '1', + t: 'pageview', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + uip: '0.0.0.0', + dh: 'www.example.com', + dl: 'https://www.example.com/abc', + dp: '%2Fabc%3Fxyz%3D1', + qt: 124893881701, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product removed", - "ec": "cat 1", - "pa": "remove", - "pr1cd1": "my product 1", - "pr1id": "p-298", - "cd1": "my product 1", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "pr1nm": "my product 1", - "pr1ca": "cat 1", - "cu": "CAD", - "pr1ps": 4.5, - "pr1pr": 24.75, - "pr1qt": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 8", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product viewed", - "properties": { - "currency": "CAD", - "quantity": 1, - "price": 24.75, - "name": "my product 1", - "category": "cat 1", - "sku": "p-298", - "testDimension": true, - "testMetric": true, - "position": 4.5 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 31', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + integrations: { + All: true, + }, + event: 'sample event', + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product viewed", - "ec": "cat 1", - "pa": "detail", - "pr1cd1": "my product 1", - "pr1id": "p-298", - "cd1": "my product 1", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "pr1nm": "my product 1", - "pr1ca": "cat 1", - "cu": "CAD", - "pr1ps": 4.5, - "pr1pr": 24.75, - "pr1qt": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 9", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product list filtered", - "properties": { - "category": "cat 1", - "list_id": "1234", - "filters": [ - { - "type": "department", - "value": "beauty" - }, - { - "type": "price", - "value": "under" - } - ], - "sorts": [ - { - "type": "price", - "value": "desc" - } - ], - "products": [ - { - "product_id": "507f1f77bcf86cd799439011", - "productDimension": "My Product Dimension", - "productMetric": "My Product Metric" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ea: 'sample event', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + uip: '0.0.0.0', + qt: 124893881701, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product list filtered", - "ec": "cat 1", - "pa": "detail", - "il1pi1id": "507f1f77bcf86cd799439011", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "il1nm": "1234", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "il1pi1qt": 1, - "il1pi1va": "department:beauty,price:under::price:desc", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 10", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product list viewed", - "properties": { - "category": "cat 1", - "list_id": "1234", - "filters": [ - { - "type": "department", - "value": "beauty" - }, - { - "type": "price", - "value": "under" - } - ], - "sorts": [ - { - "type": "price", - "value": "desc" - } - ], - "products": [ - { - "product_id": "507f1f77bcf86cd799439011", - "productDimension": "My Product Dimension", - "productMetric": "My Product Metric", - "position": 10 - }, - { - "product_id": "507f1f77bcf86cdef799439011", - "productDimension": "My Product Dimension1", - "productMetric": "My Product Metric1", - "position": -10 - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 32', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Refunded', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product list viewed", - "ec": "cat 1", - "pa": "detail", - "il1pi1id": "507f1f77bcf86cd799439011", - "il1pi1ps": 10, - "il1pi2id": "507f1f77bcf86cdef799439011", - "il1pi2ps": -10, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "il1nm": "1234", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "il1pi1qt": 1, - "il1pi1va": "department:beauty,price:under::price:desc", - "il1pi2qt": 1, - "il1pi2va": "department:beauty,price:under::price:desc", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 11", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "product clicked", - "properties": { - "currency": "CAD", - "quantity": 1, - "price": 24.75, - "name": "my product", - "category": "cat 1", - "sku": "p-298", - "list": "search results", - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'refund', + ev: 100, + pr1id: 'p-298', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr1qt: 1, + pr2id: 'p-299', + pr2cd1: 'other product', + pr2nm: 'other product', + pr2pr: 24.75, + pr2qt: 3, + ea: 'Order Refunded', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + ti: 'rudderstackorder1', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "product clicked", - "ec": "cat 1", - "pa": "click", - "pr1cd1": "my product", - "pr1id": "p-298", - "cd1": "my product", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "pr1nm": "my product", - "pr1ca": "cat 1", - "cu": "CAD", - "pr1pr": 24.75, - "pr1qt": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "pal": "search results", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 12", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "promotion viewed", - "properties": { - "currency": "CAD", - "promotion_id": "PROMO_1234", - "name": "my product", - "creative": "summer_banner2", - "position": "banner_slot1", - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 33', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Refunded', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "promotion viewed", - "ec": "EnhancedEcommerce", - "cu": "CAD", - "promoa": "view", - "pa": "view", - "cd1": "my product", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "promo1id": "PROMO_1234", - "promo1cr": "summer_banner2", - "promo1ps": "banner_slot1", - "promo1nm": "my product", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 13", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "promotion clicked", - "properties": { - "currency": "CAD", - "promotion_id": "PROMO_1234", - "name": "my product", - "creative": "summer_banner2", - "position": "banner_slot1", - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ev: 100, + pa: 'refund', + ti: 'rudderstackorder1', + ea: 'Order Refunded', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "promotion clicked", - "ec": "EnhancedEcommerce", - "cu": "CAD", - "promoa": "promo_click", - "pa": "promo_click", - "cd1": "my product", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "promo1id": "PROMO_1234", - "promo1cr": "summer_banner2", - "promo1ps": "banner_slot1", - "promo1nm": "my product", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 14", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "checkout started", - "properties": { - "currency": "CAD", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298" - }, - { - "quantity": 1, - "price": 24.75, - "name": "my product 2", - "sku": "p-299" - } - ], - "step": 1, - "paymentMethod": "Visa", - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 34', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Refunded', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "checkout", - "pr1id": "p-298", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr2id": "p-299", - "pr2cd1": "my product 2", - "pr2nm": "my product 2", - "pr2pr": 24.75, - "ea": "checkout started", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "cu": "CAD", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "cos": 1, - "pr1qt": 1, - "pr2qt": 1, - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 15", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order updated", - "properties": { - "currency": "CAD", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298" - }, - { - "quantity": 1, - "price": 24.75, - "name": "my product 2", - "sku": "p-299" - } - ], - "step": 1, - "paymentMethod": "Visa", - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ev: 100, + pa: 'refund', + ti: 'rudderstackorder1', + ea: 'Order Refunded', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "checkout", - "pr1id": "p-298", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr2id": "p-299", - "pr2cd1": "my product 2", - "pr2nm": "my product 2", - "pr2pr": 24.75, - "ea": "order updated", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "cu": "CAD", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "cos": 1, - "pr1qt": 1, - "pr2qt": 1, - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 16", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "checkout step viewed", - "properties": { - "currency": "CAD", - "step": 1 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 35', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Refunded', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "checkout", - "ea": "checkout step viewed", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "cos": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 17", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "checkout step completed", - "properties": { - "currency": "CAD", - "step": 1, - "paymentMethod": "Visa" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ev: 100, + pa: 'refund', + pr1id: '1', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr1qt: 1, + pr2id: '2', + pr2cd1: 'other product', + pr2nm: 'other product', + pr2pr: 24.75, + pr2qt: 3, + ea: 'Order Refunded', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + ti: 'rudderstackorder1', + uid: '12345', + ul: 'en-US', + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "checkout_option", - "ea": "checkout step completed", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "cos": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 18", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order refunded", - "properties": { - "products": [ - { - "quantity": 1, - "sku": "p-298" - }, - { - "quantity": 1, - "sku": "p-299" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 36', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Cart Shared', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "order refunded", - "ec": "EnhancedEcommerce", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "pa": "refund", - "pr1id": "p-298", - "pr1qt": 1, - "pr2id": "p-299", - "ul": "en-US", - "pr2qt": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 19", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order starterefundedd", - "properties": { - "products": [ - { - "quantity": 1, - "sku": "p-298" - }, - { - "quantity": 1, - "sku": "p-299" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ev: 100, + ea: 'Cart Shared', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + st: ' 1 2', + ul: 'en-US', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "order starterefundedd", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 20", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order starterefundedd", - "properties": { - "products": [ - { - "quantity": 1, - "sku": "p-298" - }, - { - "quantity": 1, - "sku": "p-299" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 37', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Product Shared', + properties: { + product_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + url: 'https://www.example.com/abc', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "order starterefundedd", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 21", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order starterefundedd", - "properties": { - "products": [ - { - "quantity": 1, - "sku": "p-298" - }, - { - "quantity": 1, - "sku": "p-299" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ev: 100, + ea: 'Product Shared', + ec: 'All', + ni: 1, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + st: 'https://www.example.com/abc', + dh: 'www.example.com', + dl: 'https://www.example.com/abc', + dp: '%2Fabc', + ul: 'en-US', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "order starterefundedd", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 22", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order starterefundedd", - "properties": { - "products": [ - { - "quantity": 1, - "sku": "p-298" - }, - { - "quantity": 1, - "sku": "p-299" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 38', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Product List Clicked', + properties: { + list_id: 'Sample Product List', + category: 'Sample Product List', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "cid": "00000000000000000000000000", - "ea": "order starterefundedd", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 23", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "order starterefundedd", - "properties": { - "products": [ - { - "quantity": 1, - "sku": "p-298" - }, - { - "quantity": 1, - "sku": "p-299" - } - ], - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'Product List Clicked', + ec: 'Sample Product List', + pa: 'click', + il1pi1id: '1', + pr1cd1: 'my product', + il1pi1nm: 'my product', + il1pi1pr: 24.75, + il1pi2id: '2', + pr2cd1: 'other product', + il1pi2nm: 'other product', + il1pi2pr: 24.75, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + il1nm: 'Sample Product List', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + ni: 1, + il1pi2qt: 3, + il1pi1qt: 1, + ul: 'en-US', + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "order starterefundedd", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 24", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "linkid test", - "properties": { - "linkid": "abc123", - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 39', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Product List Clicked', + properties: { + list_id: 'Sample Product List', + category: 'Sample Product List', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "linkid": "abc123", - "cid": "00000000000000000000000000", - "ea": "linkid test", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 25", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "campaign": { - "name": "sampleName", - "source": "sampleSource", - "medium": "sampleMedium", - "content": "sampleContent", - "term": "sampleTerm" - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "campaign test", - "properties": { - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'Product List Clicked', + ec: 'Sample Product List', + pa: 'click', + il1pi1id: 'p-298', + pr1cd1: 'my product', + il1pi1nm: 'my product', + il1pi1pr: 24.75, + il1pi2id: 'p-299', + pr2cd1: 'other product', + il1pi2nm: 'other product', + il1pi2pr: 24.75, + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + il1nm: 'Sample Product List', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + ul: 'en-US', + il1pi2qt: 3, + il1pi1qt: 1, + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "cn": "sampleName", - "cs": "sampleSource", - "cm": "sampleMedium", - "cc": "sampleContent", - "ck": "sampleTerm", - "cid": "00000000000000000000000000", - "ea": "campaign test", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 26", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "campaign": { - "name": "sampleName", - "source": "sampleSource", - "medium": "sampleMedium", - "content": "sampleContent", - "term": "sampleTerm" - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "event": "campaign test", - "properties": { - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 40', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Product List Clicked', + properties: { + list_id: 'Sample Product List', + category: 'Sample Product List', + products: [], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "cn": "sampleName", - "cs": "sampleSource", - "cm": "sampleMedium", - "cc": "sampleContent", - "ck": "sampleTerm", - "cid": "00000000000000000000000000", - "ea": "campaign test", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 27", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "campaign": { - "name": "sampleName", - "source": "sampleSource", - "medium": "sampleMedium", - "content": "sampleContent", - "term": "sampleTerm" - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "event": "campaign test", - "properties": { - "testDimension": true, - "testMetric": true - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ni: 1, + ea: 'Product List Clicked', + ec: 'Sample Product List', + pa: 'click', + el: 'event', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + il1nm: 'Sample Product List', + uid: '12345', + cid: '00000000000000000000000000', + qt: 124893881700, + }, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ul": "en-US", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "cn": "sampleName", - "cs": "sampleSource", - "cm": "sampleMedium", - "cc": "sampleContent", - "ck": "sampleTerm", - "cid": "00000000000000000000000000", - "ea": "campaign test", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 28", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.2" - }, - "traits": { - "abc": "1234" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.2" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36", - "locale": "en-GB", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "page": { - "path": "/tests/html/ecomm_test.html", - "referrer": "http://0.0.0.0:1112/tests/html/", - "search": "", - "title": "GA Ecommerce Test", - "url": "http://0.0.0.0:1112/tests/html/ecomm_test.html" - } - }, - "type": "identify", - "messageId": "bc8a6af8-37fd-46a9-9592-ea29a256435f", - "originalTimestamp": "2020-06-22T11:30:32.493Z", - "anonymousId": "38e169a1-3234-46f7-9ceb-c1a6a69005fe", - "userId": "123", - "integrations": { - "All": true - }, - "sentAt": "2020-06-22T11:30:32.494Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 41', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Cancelled', + properties: { + order_id: 'rudderstackorder1', + total: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "User Enriched", - "dt": "GA Ecommerce Test", - "ec": "All", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.1.2", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "uid": "123", - "cid": "38e169a1-3234-46f7-9ceb-c1a6a69005fe", - "ni": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36", - "ul": "en-GB", - "qt": 103120167507, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "38e169a1-3234-46f7-9ceb-c1a6a69005fe" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 29", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "page", - "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "integrations": { - "All": true - }, - "name": "ApplicationLoaded", - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'refund', + ev: 100, + tr: 99.99, + pr1id: '1', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr2id: '2', + pr2cd1: 'other product', + pr2nm: 'other product', + pr2pr: 24.75, + ea: 'Order Cancelled', + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ti: 'rudderstackorder1', + ts: 13.99, + tt: 20.99, + cu: 'INR', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + pr1qt: 1, + pr2qt: 3, + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "v": "1", - "t": "pageview", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "uip": "0.0.0.0", - "qt": 124893881701, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 30", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "page", - "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "properties": { - "path": "/abc", - "referrer": "", - "search": "?xyz=1", - "title": "", - "url": "https://www.example.com/abc" - }, - "integrations": { - "All": true - }, - "name": "ApplicationLoaded", - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 42', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Cancelled', + properties: { + order_id: 'rudderstackorder1', + value: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "v": "1", - "t": "pageview", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "uip": "0.0.0.0", - "dh": "www.example.com", - "dl": "https://www.example.com/abc", - "dp": "%2Fabc%3Fxyz%3D1", - "qt": 124893881701, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 31", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "integrations": { - "All": true - }, - "event": "sample event", - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'refund', + tr: 99.99, + pr1id: '1', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr2id: '2', + pr2cd1: 'other product', + pr2nm: 'other product', + pr2pr: 24.75, + ea: 'Order Cancelled', + ev: 100, + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ti: 'rudderstackorder1', + ts: 13.99, + tt: 20.99, + cu: 'INR', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + pr1qt: 1, + pr2qt: 3, + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ea": "sample event", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "uip": "0.0.0.0", - "qt": 124893881701, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 32", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Refunded", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 43', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Cancelled', + properties: { + order_id: 'rudderstackorder1', + revenue: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "refund", - "ev": 100, - "pr1id": "p-298", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr1qt": 1, - "pr2id": "p-299", - "pr2cd1": "other product", - "pr2nm": "other product", - "pr2pr": 24.75, - "pr2qt": 3, - "ea": "Order Refunded", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "ti": "rudderstackorder1", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 33", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Refunded", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + pa: 'refund', + tr: 99.99, + pr1id: '1', + pr1cd1: 'my product', + pr1nm: 'my product', + pr1pr: 24.75, + pr2id: '2', + pr2cd1: 'other product', + pr2nm: 'other product', + pr2pr: 24.75, + ea: 'Order Cancelled', + ev: 100, + ec: 'EnhancedEcommerce', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + ti: 'rudderstackorder1', + ts: 13.99, + tt: 20.99, + cu: 'INR', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + pr1qt: 1, + pr2qt: 3, + ni: 1, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ev": 100, - "pa": "refund", - "ti": "rudderstackorder1", - "ea": "Order Refunded", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 34", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Refunded", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 44', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Order Cancelled', + properties: { + order_id: 'rudderstackorder1', + revenue: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ev": 100, - "pa": "refund", - "ti": "rudderstackorder1", - "ea": "Order Refunded", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 35", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Refunded", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + error: 'No product information supplied for transaction event', + statTags: { + destType: 'GA360', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ev": 100, - "pa": "refund", - "pr1id": "1", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr1qt": 1, - "pr2id": "2", - "pr2cd1": "other product", - "pr2nm": "other product", - "pr2pr": 24.75, - "pr2qt": 3, - "ea": "Order Refunded", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "ti": "rudderstackorder1", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 36", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Cart Shared", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 45', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Cart Viewed', + properties: { + order_id: 'rudderstackorder1', + revenue: 99.99, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + product_id: '1', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + product_id: '2', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ev": 100, - "ea": "Cart Shared", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "st": " 1 2", - "ul": "en-US", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 37", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Product Shared", - "properties": { - "product_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "url": "https://www.example.com/abc" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'Cart Viewed', + ev: 100, + ec: 'EnhancedEcommerce', + pa: 'detail', + v: '1', + t: 'event', + el: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + cid: '00000000000000000000000000', + uid: '12345', + ul: 'en-US', + ni: 1, + pr1cd1: 'my product', + pr1id: '1', + pr1nm: 'my product', + pr1pr: 24.75, + pr1qt: 1, + pr2cd1: 'other product', + pr2id: '2', + pr2nm: 'other product', + pr2pr: 24.75, + pr2qt: 3, + qt: 124893881700, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ev": 100, - "ea": "Product Shared", - "ec": "All", - "ni": 1, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "st": "https://www.example.com/abc", - "dh": "www.example.com", - "dl": "https://www.example.com/abc", - "dp": "%2Fabc", - "ul": "en-US", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 38", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Product List Clicked", - "properties": { - "list_id": "Sample Product List", - "category": "Sample Product List", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 46', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + name1: 'Test', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '00000000000000000000000000', + userId: '123456', + integrations: { + All: true, + }, + traits: { + name1: 'Test', + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + serverSideIdentifyEventCategory: 'name', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "Product List Clicked", - "ec": "Sample Product List", - "pa": "click", - "il1pi1id": "1", - "pr1cd1": "my product", - "il1pi1nm": "my product", - "il1pi1pr": 24.75, - "il1pi2id": "2", - "pr2cd1": "other product", - "il1pi2nm": "other product", - "il1pi2pr": 24.75, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "il1nm": "Sample Product List", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "ni": 1, - "il1pi2qt": 3, - "il1pi1qt": 1, - "ul": "en-US", - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 39", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Product List Clicked", - "properties": { - "list_id": "Sample Product List", - "category": "Sample Product List", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + error: 'server side identify is not on', + statTags: { + destType: 'GA360', + errorCategory: 'dataValidation', + errorType: 'configuration', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "Product List Clicked", - "ec": "Sample Product List", - "pa": "click", - "il1pi1id": "p-298", - "pr1cd1": "my product", - "il1pi1nm": "my product", - "il1pi1pr": 24.75, - "il1pi2id": "p-299", - "pr2cd1": "other product", - "il1pi2nm": "other product", - "il1pi2pr": 24.75, - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "il1nm": "Sample Product List", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "ul": "en-US", - "il1pi2qt": 3, - "il1pi1qt": 1, - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 40", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Product List Clicked", - "properties": { - "list_id": "Sample Product List", - "category": "Sample Product List", - "products": [] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 47', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'screen', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + name: 'homescreen', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ni": 1, - "ea": "Product List Clicked", - "ec": "Sample Product List", - "pa": "click", - "el": "event", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "il1nm": "Sample Product List", - "uid": "12345", - "cid": "00000000000000000000000000", - "qt": 124893881700 - }, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 41", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Cancelled", - "properties": { - "order_id": "rudderstackorder1", - "total": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + cd1: 'homescreen', + v: '1', + t: 'screenview', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + cid: '00000000000000000000000000', + cd: 'homescreen', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + uid: '12345', + ul: 'en-US', + uip: '0.0.0.0', + qt: 124893881701, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '00000000000000000000000000', + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "refund", - "ev": 100, - "tr": 99.99, - "pr1id": "1", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr2id": "2", - "pr2cd1": "other product", - "pr2nm": "other product", - "pr2pr": 24.75, - "ea": "Order Cancelled", - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ti": "rudderstackorder1", - "ts": 13.99, - "tt": 20.99, - "cu": "INR", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "pr1qt": 1, - "pr2qt": 3, - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 42", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Cancelled", - "properties": { - "order_id": "rudderstackorder1", - "value": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 48', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'newtype', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + name: 'homescreen', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'cat1', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "refund", - "tr": 99.99, - "pr1id": "1", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr2id": "2", - "pr2cd1": "other product", - "pr2nm": "other product", - "pr2pr": 24.75, - "ea": "Order Cancelled", - "ev": 100, - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ti": "rudderstackorder1", - "ts": 13.99, - "tt": 20.99, - "cu": "INR", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "pr1qt": 1, - "pr2qt": 3, - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 43", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Cancelled", - "properties": { - "order_id": "rudderstackorder1", - "revenue": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Message type newtype not supported', + statTags: { + destType: 'GA360', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "pa": "refund", - "tr": 99.99, - "pr1id": "1", - "pr1cd1": "my product", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr2id": "2", - "pr2cd1": "other product", - "pr2nm": "other product", - "pr2pr": 24.75, - "ea": "Order Cancelled", - "ev": 100, - "ec": "EnhancedEcommerce", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "ti": "rudderstackorder1", - "ts": 13.99, - "tt": 20.99, - "cu": "INR", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "pr1qt": 1, - "pr2qt": 3, - "ni": 1, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 44", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Order Cancelled", - "properties": { - "order_id": "rudderstackorder1", - "revenue": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 49', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + name: 'Test', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + userId: '12345', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'name', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "No product information supplied for transaction event", - "statTags": { - "destType": "GA360", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 45", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Cart Viewed", - "properties": { - "order_id": "rudderstackorder1", - "revenue": 99.99, - "shipping": 13.99, - "tax": 20.99, - "currency": "INR", - "products": [ - { - "quantity": 1, - "price": 24.75, - "name": "my product", - "sku": "p-298", - "product_id": "1" - }, - { - "quantity": 3, - "price": 24.75, - "name": "other product", - "sku": "p-299", - "product_id": "2" - } - ] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + userId: '12345', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'action1', + ec: 'Test', + ni: 1, + cd1: 'Test', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + uid: '12345', + cid: '827ccb0eea8a706c4c34a16891f84e7b', + uip: '0.0.0.0', + qt: 124901802438, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "Cart Viewed", - "ev": 100, - "ec": "EnhancedEcommerce", - "pa": "detail", - "v": "1", - "t": "event", - "el": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "cid": "00000000000000000000000000", - "uid": "12345", - "ul": "en-US", - "ni": 1, - "pr1cd1": "my product", - "pr1id": "1", - "pr1nm": "my product", - "pr1pr": 24.75, - "pr1qt": 1, - "pr2cd1": "other product", - "pr2id": "2", - "pr2nm": "other product", - "pr2pr": 24.75, - "pr2qt": 3, - "qt": 124893881700, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 46", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "traits": { - "name1": "Test" - }, - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "properties": { - "plan": "standard plan", - "name": "rudder test" - }, - "type": "identify", - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "00000000000000000000000000", - "userId": "123456", - "integrations": { - "All": true - }, - "traits": { - "name1": "Test" - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "serverSideIdentifyEventCategory": "name", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 50', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + name: 'Test', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + userId: '12345', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'name', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + disableMd5: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "server side identify is not on", - "statTags": { - "destType": "GA360", - "errorCategory": "dataValidation", - "errorType": "configuration", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 47", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "screen", - "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "properties": { - "name": "homescreen" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + userId: '12345', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'action1', + ec: 'Test', + ni: 1, + cd1: 'Test', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + uid: '12345', + uip: '0.0.0.0', + qt: 124901802438, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "cd1": "homescreen", - "v": "1", - "t": "screenview", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "cid": "00000000000000000000000000", - "cd": "homescreen", - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "uid": "12345", - "ul": "en-US", - "uip": "0.0.0.0", - "qt": 124893881701, - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "00000000000000000000000000" - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 48", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "newtype", - "messageId": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", - "originalTimestamp": "2019-10-14T11:15:18.299Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "properties": { - "name": "homescreen" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "cat1", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 51', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + name: 'Test', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + userId: '12345', + integrations: { + All: true, + GA: { + clientId: 'clientId', + }, + 'Google Analytics': { + clientId: 'clientId', + }, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'name', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Message type newtype not supported", - "statTags": { - "destType": "GA360", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 49", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "traits": { - "name": "Test" - }, - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "properties": { - "plan": "standard plan", - "name": "rudder test" - }, - "type": "identify", - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "userId": "12345", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "name", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + userId: '12345', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'action1', + ec: 'Test', + ni: 1, + cd1: 'Test', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + uid: '12345', + cid: 'clientId', + uip: '0.0.0.0', + qt: 124901802438, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "userId": "12345", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "action1", - "ec": "Test", - "ni": 1, - "cd1": "Test", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "uid": "12345", - "cid": "827ccb0eea8a706c4c34a16891f84e7b", - "uip": "0.0.0.0", - "qt": 124901802438 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {} - }, - "statusCode": 200 - } - ] - } - } + }, }, { - "name": "ga360", - "description": "Test 50", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "traits": { - "name": "Test" - }, - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "properties": { - "plan": "standard plan", - "name": "rudder test" - }, - "type": "identify", - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "userId": "12345", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "name", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "disableMd5": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + name: 'ga360', + description: 'Test 52', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + externalId: [ + { + id: 'externalClientId', + type: 'gaExternalId', + }, + ], + traits: { + name: 'Test', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + properties: { + plan: 'standard plan', + name: 'rudder test', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + userId: '12345', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + trackingID: 'UA-165994240-1', + doubleClick: true, + enhancedLinkAttribution: true, + classic: true, + ignoredReferrers: '', + serverClassic: false, + includeSearch: true, + trackCategorizedPages: true, + trackNamedPages: true, + sampleRate: '100', + siteSpeedSampleRate: '1', + setAllMappedProps: true, + enableServerSideIdentify: true, + serverSideIdentifyEventCategory: 'name', + serverSideIdentifyEventAction: 'action1', + anonymizeIp: true, + domain: 'domain', + enhancedEcommerce: true, + nonInteraction: true, + optimize: 'abc123', + sendUserId: true, + useGoogleAmpClientId: true, + 'web-useNativeSDK': true, + dimensions: [ + { + from: 'name', + to: 'dimension1', + }, + { + from: 'custom2', + to: 'dimension2', + }, + ], + metrics: [ + { + from: 'email', + to: 'metric1', + }, + { + from: 'trait2', + to: 'metric2', + }, + ], + resetCustomDimensionsOnPage: [ + { + resetCustomDimensionsOnPage: 'abc', + }, + { + resetCustomDimensionsOnPage: 'xyz', + }, + ], + contentGroupings: [ + { + from: 'plan', + to: 'contentGroup1', + }, + { + from: 'prop2', + to: 'contentGroup2', + }, + ], + }, + Enabled: true, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "userId": "12345", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "action1", - "ec": "Test", - "ni": 1, - "cd1": "Test", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "uid": "12345", - "uip": "0.0.0.0", - "qt": 124901802438 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {} - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "ga360", - "description": "Test 51", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "traits": { - "name": "Test" - }, - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "properties": { - "plan": "standard plan", - "name": "rudder test" - }, - "type": "identify", - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "userId": "12345", - "integrations": { - "All": true, - "GA": { - "clientId": "clientId" - }, - "Google Analytics": { - "clientId": "clientId" - } - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "name", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + userId: '12345', + method: 'POST', + endpoint: 'https://www.google-analytics.com/collect', + headers: {}, + params: { + ea: 'action1', + ec: 'Test', + ni: 1, + cd1: 'Test', + v: '1', + t: 'event', + tid: 'UA-165994240-1', + ds: 'web', + an: 'RudderLabs JavaScript SDK', + av: '1.0.0', + aiid: 'com.rudderlabs.javascript', + npa: 1, + aip: 1, + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ul: 'en-US', + uid: '12345', + cid: 'externalClientId', + uip: '0.0.0.0', + qt: 124901802438, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + statusCode: 200, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "userId": "12345", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "action1", - "ec": "Test", - "ni": 1, - "cd1": "Test", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "uid": "12345", - "cid": "clientId", - "uip": "0.0.0.0", - "qt": 124901802438 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {} - }, - "statusCode": 200 - } - ] - } - } + }, }, - { - "name": "ga360", - "description": "Test 52", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "channel": "web", - "context": { - "externalId": [ - { - "id": "externalClientId", - "type": "gaExternalId" - } - ], - "traits": { - "name": "Test" - }, - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "properties": { - "plan": "standard plan", - "name": "rudder test" - }, - "type": "identify", - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "userId": "12345", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "trackingID": "UA-165994240-1", - "doubleClick": true, - "enhancedLinkAttribution": true, - "classic": true, - "ignoredReferrers": "", - "serverClassic": false, - "includeSearch": true, - "trackCategorizedPages": true, - "trackNamedPages": true, - "sampleRate": "100", - "siteSpeedSampleRate": "1", - "setAllMappedProps": true, - "enableServerSideIdentify": true, - "serverSideIdentifyEventCategory": "name", - "serverSideIdentifyEventAction": "action1", - "anonymizeIp": true, - "domain": "domain", - "enhancedEcommerce": true, - "nonInteraction": true, - "optimize": "abc123", - "sendUserId": true, - "useGoogleAmpClientId": true, - "web-useNativeSDK": true, - "dimensions": [ - { - "from": "name", - "to": "dimension1" - }, - { - "from": "custom2", - "to": "dimension2" - } - ], - "metrics": [ - { - "from": "email", - "to": "metric1" - }, - { - "from": "trait2", - "to": "metric2" - } - ], - "resetCustomDimensionsOnPage": [ - { - "resetCustomDimensionsOnPage": "abc" - }, - { - "resetCustomDimensionsOnPage": "xyz" - } - ], - "contentGroupings": [ - { - "from": "plan", - "to": "contentGroup1" - }, - { - "from": "prop2", - "to": "contentGroup2" - } - ] - }, - "Enabled": true - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "userId": "12345", - "method": "POST", - "endpoint": "https://www.google-analytics.com/collect", - "headers": {}, - "params": { - "ea": "action1", - "ec": "Test", - "ni": 1, - "cd1": "Test", - "v": "1", - "t": "event", - "tid": "UA-165994240-1", - "ds": "web", - "an": "RudderLabs JavaScript SDK", - "av": "1.0.0", - "aiid": "com.rudderlabs.javascript", - "npa": 1, - "aip": 1, - "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "ul": "en-US", - "uid": "12345", - "cid": "externalClientId", - "uip": "0.0.0.0", - "qt": 124901802438 - }, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {} - }, - "statusCode": 200 - } - ] - } - } - } -].map((d) => ({ ...d, mockFns })) +].map((d) => ({ ...d, mockFns })); diff --git a/test/integrations/destinations/ga4/dataDelivery/business.ts b/test/integrations/destinations/ga4/dataDelivery/business.ts new file mode 100644 index 00000000000..80271abbdbb --- /dev/null +++ b/test/integrations/destinations/ga4/dataDelivery/business.ts @@ -0,0 +1,350 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { + generateMetadata, + generateProxyV0Payload, + generateProxyV1Payload, +} from '../../../testUtils'; +import { JSON_MIME_TYPE } from '../../../../../src/v0/util/constant'; + +const headers = { + HOST: 'www.google-analytics.com', + 'Content-Type': JSON_MIME_TYPE, +}; + +const params = { + api_secret: 'dymmyApiSecret', +}; + +const validRequest = { + events: [ + { + name: 'sign_up', + params: { + method: 'google', + engagement_time_msec: 1, + }, + }, + ], + user_id: 'dummyUserId', + client_id: 'dummyClientId', + non_personalized_ads: true, +}; + +const invalidEventNameRequest = { + events: [ + { + name: 'campaign@details', + params: { + term: 'summer+travel', + medium: 'cpc', + source: 'google', + content: 'logo link', + campaign: 'Summer_fun', + campaign_id: 'google_1234', + engagement_time_msec: 1, + }, + }, + ], + user_id: 'dummyUserId', + client_id: 'dummyClientId', + non_personalized_ads: true, +}; + +const invalidParameterValueRequest = { + events: [ + { + name: 'add_to_cart', + params: { + currency: 'USD', + value: 7.77, + engagement_time_msec: 1, + items: [ + { + item_id: '507f1f77bcf86cd799439011', + item_name: 'Monopoly: 3rd Edition', + coupon: 'SUMMER_FUN', + item_category: 'Apparel', + item_brand: 'Google', + item_variant: 'green', + price: '$19', + quantity: 2, + affiliation: 'Google Merchandise Store', + currency: 'USD', + item_list_id: 'related_products', + item_list_name: 'Related Products', + location_id: 'L_12345', + }, + ], + }, + }, + ], + user_id: 'dummyUserId', + client_id: 'dummyClientId', + non_personalized_ads: true, +}; + +const invalidParamMessage = + 'Validation of item.price should prevent conversion from unsupported value [string_value: "$19"]'; +const invalidParameterErrorMessage = `Validation Server Response Handler:: Validation Error for ga4 of field path :undefined | INTERNAL_ERROR-${invalidParamMessage}`; +const invalidEventNameErrorMessage = + 'Validation Server Response Handler:: Validation Error for ga4 of field path :events | NAME_INVALID-Event at index: [0] has invalid name [campaign@details]. Only alphanumeric characters and underscores are allowed.'; + +const metadataArray = [generateMetadata(1)]; + +const expectedStatTags = { + destType: 'GA4', + destinationId: 'default-destinationId', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'default-workspaceId', +}; + +export const testScenariosForV0API = [ + { + id: 'ga4_v0_scenario_1', + name: 'ga4', + description: + '[Proxy v0 API] :: Test for a valid request - where the destination responds with 200 without any error', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + headers, + params, + JSON: validRequest, + endpoint: 'https://www.google-analytics.com/debug/mp/collect', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + destinationResponse: { + response: { + validationMessages: [], + }, + status: 200, + }, + message: '[GA4 Response Handler] - Request Processed Successfully', + status: 200, + }, + }, + }, + }, + }, + { + id: 'ga4_v0_scenario_2', + name: 'ga4', + description: + '[Proxy v0 API] :: Test for a invalid event name - where the destination responds with 200 with error for invalid event name', + successCriteria: 'Should return 400 with error and destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + headers, + params, + JSON: invalidEventNameRequest, + endpoint: 'https://www.google-analytics.com/debug/mp/collect', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: + 'Event at index: [0] has invalid name [campaign@details]. Only alphanumeric characters and underscores are allowed.', + message: invalidEventNameErrorMessage, + statTags: expectedStatTags, + status: 400, + }, + }, + }, + }, + }, + { + id: 'ga4_v0_scenario_3', + name: 'ga4', + description: + '[Proxy v0 API] :: Test for a invalid parameter value - where the destination responds with 200 with error for invalid parameter value', + successCriteria: 'Should return 400 with error and destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + headers, + params, + JSON: invalidParameterValueRequest, + endpoint: 'https://www.google-analytics.com/debug/mp/collect', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: invalidParamMessage, + message: invalidParameterErrorMessage, + statTags: expectedStatTags, + status: 400, + }, + }, + }, + }, + }, +]; + +export const testScenariosForV1API: ProxyV1TestData[] = [ + { + id: 'ga4_v1_scenario_1', + name: 'ga4', + description: + '[Proxy v1 API] :: Test for a valid request - where the destination responds with 200 without any error', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers, + params, + JSON: validRequest, + endpoint: 'https://www.google-analytics.com/debug/mp/collect', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: '[GA4 Response Handler] - Request Processed Successfully', + response: [ + { + error: '{"validationMessages":[]}', + metadata: generateMetadata(1), + statusCode: 200, + }, + ], + status: 200, + }, + }, + }, + }, + }, + { + id: 'ga4_v1_scenario_2', + name: 'ga4', + description: + '[Proxy v1 API] :: Test for a invalid event name - where the destination responds with 200 with error for invalid event name', + successCriteria: 'Should return 400 with error and destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers, + params, + JSON: invalidEventNameRequest, + endpoint: 'https://www.google-analytics.com/debug/mp/collect', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: invalidEventNameErrorMessage, + response: [ + { + error: invalidEventNameErrorMessage, + metadata: generateMetadata(1), + statusCode: 400, + }, + ], + statTags: expectedStatTags, + status: 400, + }, + }, + }, + }, + }, + { + id: 'ga4_v1_scenario_3', + name: 'ga4', + description: + '[Proxy v1 API] :: Test for a invalid parameter value - where the destination responds with 200 with error for invalid parameter value', + successCriteria: 'Should return 200 with error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers, + params, + JSON: invalidParameterValueRequest, + endpoint: 'https://www.google-analytics.com/debug/mp/collect', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: invalidParameterErrorMessage, + response: [ + { + error: invalidParameterErrorMessage, + metadata: generateMetadata(1), + statusCode: 400, + }, + ], + statTags: expectedStatTags, + status: 400, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/ga4/dataDelivery/data.ts b/test/integrations/destinations/ga4/dataDelivery/data.ts new file mode 100644 index 00000000000..51827a38e27 --- /dev/null +++ b/test/integrations/destinations/ga4/dataDelivery/data.ts @@ -0,0 +1,3 @@ +import { testScenariosForV0API, testScenariosForV1API } from './business'; + +export const data = [...testScenariosForV0API, ...testScenariosForV1API]; diff --git a/test/integrations/destinations/ga4/network.ts b/test/integrations/destinations/ga4/network.ts new file mode 100644 index 00000000000..b5c8dc8e8e7 --- /dev/null +++ b/test/integrations/destinations/ga4/network.ts @@ -0,0 +1,139 @@ +const headers = { + HOST: 'www.google-analytics.com', + 'Content-Type': 'application/json', +}; + +const params = { + api_secret: 'dymmyApiSecret', +}; + +const dataDeliveryMocksData = [ + { + description: 'Mock response from destination depicting a valid request', + httpReq: { + method: 'post', + url: 'https://www.google-analytics.com/debug/mp/collect', + data: { + events: [ + { + name: 'sign_up', + params: { + method: 'google', + engagement_time_msec: 1, + }, + }, + ], + user_id: 'dummyUserId', + client_id: 'dummyClientId', + non_personalized_ads: true, + }, + headers, + params, + }, + httpRes: { + data: { + validationMessages: [], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response from destination depicting a invalid event name request', + httpReq: { + method: 'post', + url: 'https://www.google-analytics.com/debug/mp/collect', + data: { + events: [ + { + name: 'campaign@details', + params: { + term: 'summer+travel', + medium: 'cpc', + source: 'google', + content: 'logo link', + campaign: 'Summer_fun', + campaign_id: 'google_1234', + engagement_time_msec: 1, + }, + }, + ], + user_id: 'dummyUserId', + client_id: 'dummyClientId', + non_personalized_ads: true, + }, + headers, + params, + }, + httpRes: { + data: { + validationMessages: [ + { + fieldPath: 'events', + description: + 'Event at index: [0] has invalid name [campaign@details]. Only alphanumeric characters and underscores are allowed.', + validationCode: 'NAME_INVALID', + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response from destination depicting a invalid parameter value request', + httpReq: { + method: 'post', + url: 'https://www.google-analytics.com/debug/mp/collect', + data: { + events: [ + { + name: 'add_to_cart', + params: { + currency: 'USD', + value: 7.77, + engagement_time_msec: 1, + items: [ + { + item_id: '507f1f77bcf86cd799439011', + item_name: 'Monopoly: 3rd Edition', + coupon: 'SUMMER_FUN', + item_category: 'Apparel', + item_brand: 'Google', + item_variant: 'green', + price: '$19', + quantity: 2, + affiliation: 'Google Merchandise Store', + currency: 'USD', + item_list_id: 'related_products', + item_list_name: 'Related Products', + location_id: 'L_12345', + }, + ], + }, + }, + ], + user_id: 'dummyUserId', + client_id: 'dummyClientId', + non_personalized_ads: true, + }, + headers, + params, + }, + httpRes: { + data: { + validationMessages: [ + { + description: + 'Validation of item.price should prevent conversion from unsupported value [string_value: "$19"]', + validationCode: 'INTERNAL_ERROR', + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, +]; + +export const networkCallsData = [...dataDeliveryMocksData]; diff --git a/test/integrations/destinations/gainsight/network.ts b/test/integrations/destinations/gainsight/network.ts index c8adf871b9a..4c5a0268474 100644 --- a/test/integrations/destinations/gainsight/network.ts +++ b/test/integrations/destinations/gainsight/network.ts @@ -1,71 +1,71 @@ export const networkCallsData = [ - { - httpReq: { - url: 'https://demo-domain.gainsightcloud.com/v1/data/objects/query/Company', - method: 'POST', - }, - httpRes: { - data: { - "result": true, - "errorCode": null, - "errorDesc": null, - "requestId": "47d9c8be-4912-4610-806c-0eec22b73236", - "data": { - "records": [] - }, - "message": null - }, - status: 200 - }, + { + httpReq: { + url: 'https://demo-domain.gainsightcloud.com/v1/data/objects/query/Company', + method: 'POST', }, - { - httpReq: { - url: 'https://demo-domain.gainsightcloud.com/v1/data/objects/Company', - method: 'POST', + httpRes: { + data: { + result: true, + errorCode: null, + errorDesc: null, + requestId: '47d9c8be-4912-4610-806c-0eec22b73236', + data: { + records: [], }, - httpRes: { - data: { - "result": true, - "errorCode": null, - "errorDesc": null, - "requestId": "3ce46d4a-6a83-4a92-97b3-d9788a296af8", - "data": { - "count": 1, - "errors": null, - "records": [ - { - "Gsid": "1P0203VCESP7AUQMV9E953G" - } - ] - }, - "message": null + message: null, + }, + status: 200, + }, + }, + { + httpReq: { + url: 'https://demo-domain.gainsightcloud.com/v1/data/objects/Company', + method: 'POST', + }, + httpRes: { + data: { + result: true, + errorCode: null, + errorDesc: null, + requestId: '3ce46d4a-6a83-4a92-97b3-d9788a296af8', + data: { + count: 1, + errors: null, + records: [ + { + Gsid: '1P0203VCESP7AUQMV9E953G', }, - status: 200 + ], }, + message: null, + }, + status: 200, }, - { - httpReq: { - url: "https://demo-domain.gainsightcloud.com/v1/data/objects/Company?keys=Name", - method: 'GET', - }, - httpRes: { - data: { - "result": true, - "errorCode": null, - "errorDesc": null, - "requestId": "30630809-40a7-45d2-9673-ac2e80d06f33", - "data": { - "count": 1, - "errors": null, - "records": [ - { - "Gsid": "1P0203VCESP7AUQMV9E953G" - } - ] - }, - "message": null + }, + { + httpReq: { + url: 'https://demo-domain.gainsightcloud.com/v1/data/objects/Company?keys=Name', + method: 'GET', + }, + httpRes: { + data: { + result: true, + errorCode: null, + errorDesc: null, + requestId: '30630809-40a7-45d2-9673-ac2e80d06f33', + data: { + count: 1, + errors: null, + records: [ + { + Gsid: '1P0203VCESP7AUQMV9E953G', }, - status: 200 + ], }, - } + message: null, + }, + status: 200, + }, + }, ]; diff --git a/test/integrations/destinations/gainsight/processor/data.ts b/test/integrations/destinations/gainsight/processor/data.ts index fbeb01f5933..dc4fe25e1b1 100644 --- a/test/integrations/destinations/gainsight/processor/data.ts +++ b/test/integrations/destinations/gainsight/processor/data.ts @@ -1,970 +1,979 @@ export const data = [ - { - "name": "gainsight", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "domain": "demo-domain.gainsightcloud.com", - "accessKey": "sample-access-key", - "personMap": [], - "companyMap": [], - "eventNameMap": [], - "eventVersionMap": [] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "anon_id", - "type": "identify", - "traits": { - "email": "cosmo@krammer.com", - "name": "Cosmo Krammer", - "linkedinUrl": "https://linkedin.com/cosmo-krammer", - "location": "New York", - "emailOptOut": true, - "masterAvatarTypeCode": 10 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "Email": "cosmo@krammer.com", - "Name": "Cosmo Krammer", - "LinkedinUrl": "https://linkedin.com/cosmo-krammer", - "Location": "New York", - "EmailOptOut": true, - "MasterAvatarTypeCode": 10 - } - }, - "type": "REST", - "files": {}, - "method": "PUT", - "params": {}, - "headers": { - "Accesskey": "sample-access-key", - "Content-Type": "application/json" - }, - "version": "1", - "endpoint": "https://demo-domain.gainsightcloud.com/v1.0/api/people", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "gainsight", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "domain": "demo-domain.gainsightcloud.com", - "accessKey": "sample-access-key", - "personMap": [ - { - "from": "age", - "to": "age__gc" - } - ], - "companyMap": [], - "eventNameMap": [], - "eventVersionMap": [] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "anon_id", - "type": "identify", - "traits": { - "email": "cosmo@krammer.com", - "name": "Cosmo Krammer", - "linkedinUrl": "https://linkedin.com/cosmo-krammer", - "location": "New York", - "emailOptOut": true, - "masterAvatarTypeCode": 10, - "age": 35, - "randomKey": "this should be dropped" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "Email": "cosmo@krammer.com", - "Name": "Cosmo Krammer", - "LinkedinUrl": "https://linkedin.com/cosmo-krammer", - "Location": "New York", - "EmailOptOut": true, - "MasterAvatarTypeCode": 10, - "age__gc": 35 - } - }, - "type": "REST", - "files": {}, - "method": "PUT", - "params": {}, - "headers": { - "Accesskey": "sample-access-key", - "Content-Type": "application/json" - }, - "version": "1", - "endpoint": "https://demo-domain.gainsightcloud.com/v1.0/api/people", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "gainsight", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "domain": "demo-domain.gainsightcloud.com", - "accessKey": "sample-access-key", - "personMap": [], - "companyMap": [], - "eventNameMap": [], - "eventVersionMap": [] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "anon_id", - "type": "identify", - "traits": { - "name": "Cosmo Krammer", - "linkedinUrl": "https://linkedin.com/cosmo-krammer", - "location": "New York", - "emailOptOut": true, - "masterAvatarTypeCode": 10 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "email is required for identify", - "statTags": { - "destType": "GAINSIGHT", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "gainsight", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "domain": "demo-domain.gainsightcloud.com", - "accessKey": "sample-access-key", - "sharedSecret": "sample-shared-secret", - "eventNameMap": [ - { - "from": "Ticket Resolved", - "to": "Ticket Resolved Event" - } - ], - "eventVersionMap": [ - { - "from": "Ticket Resolved", - "to": "1.0.0" - } - ], - "topicName": "Ticket Actions", - "tenantId": "sample-tenant-id", - "personMap": [], - "companyMap": [] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "anon_id", - "type": "track", - "event": "Ticket Resolved", - "properties": { - "ticketId": "sample-ticket-id", - "actionEmail": "sample@email.com", - "status": "resovled" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "ticketId": "sample-ticket-id", - "actionEmail": "sample@email.com", - "status": "resovled" - } - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Accesskey": "sample-access-key", - "tenantId": "sample-tenant-id", - "sharedSecret": "sample-shared-secret", - "Content-Type": "application/json", - "topicName": "Ticket Actions", - "eventName": "Ticket Resolved Event", - "eventVersion": "1.0.0" - }, - "version": "1", - "endpoint": "https://demo-domain.gainsightcloud.com/v1.0/api/eventManager/event", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "gainsight", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "domain": "demo-domain.gainsightcloud.com", - "accessKey": "sample-access-key", - "sharedSecret": "sample-shared-secret", - "personMap": [], - "companyMap": [], - "eventNameMap": [], - "eventVersionMap": [] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "traits": { - "email": "krammer@seinfeld.com" - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "anon_id", - "type": "group", - "traits": { - "name": "Kramerica Industries", - "industry": "Sitcom", - "employees": "100", - "status": "complete", - "companyType": "spoof" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "Email": "krammer@seinfeld.com", - "companies": [ - { - "Company_ID": "1P0203VCESP7AUQMV9E953G" - } - ] - } - }, - "type": "REST", - "files": {}, - "method": "PUT", - "params": {}, - "headers": { - "Accesskey": "sample-access-key", - "Content-Type": "application/json" - }, - "version": "1", - "endpoint": "https://demo-domain.gainsightcloud.com/v1.0/api/people", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "gainsight", - "description": "Test 5", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "domain": "demo-domain.gainsightcloud.com", - "accessKey": "sample-access-key", - "sharedSecret": "sample-shared-secret", - "personMap": [], - "companyMap": [], - "eventNameMap": [], - "eventVersionMap": [] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "traits": { - "email": "krammer@seinfeld.com" - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "anon_id", - "type": "group", - "traits": { - "name": "Seinfeld Corps", - "industry": "TV Series", - "employees": "50", - "status": "complete" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "Email": "krammer@seinfeld.com", - "companies": [ - { - "Company_ID": "1P0203VCESP7AUQMV9E953G" - } - ] - } - }, - "type": "REST", - "files": {}, - "method": "PUT", - "params": {}, - "headers": { - "Accesskey": "sample-access-key", - "Content-Type": "application/json" - }, - "version": "1", - "endpoint": "https://demo-domain.gainsightcloud.com/v1.0/api/people", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "gainsight", - "description": "Test 6", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "domain": "demo-domain.gainsightcloud.com", - "accessKey": "sample-access-key", - "personMap": [], - "companyMap": [], - "eventNameMap": [], - "eventVersionMap": [] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "anon_id", - "type": "identify", - "traits": { - "email": "cosmo@krammer.com", - "firstname": "Cosmo", - "lastname": "Krammer", - "linkedinUrl": "https://linkedin.com/cosmo-krammer", - "location": "New York", - "emailOptOut": true, - "masterAvatarTypeCode": 10 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "Email": "cosmo@krammer.com", - "FirstName": "Cosmo", - "LastName": "Krammer", - "Name": "Cosmo Krammer", - "LinkedinUrl": "https://linkedin.com/cosmo-krammer", - "Location": "New York", - "EmailOptOut": true, - "MasterAvatarTypeCode": 10 - } - }, - "type": "REST", - "files": {}, - "method": "PUT", - "params": {}, - "headers": { - "Accesskey": "sample-access-key", - "Content-Type": "application/json" - }, - "version": "1", - "endpoint": "https://demo-domain.gainsightcloud.com/v1.0/api/people", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "gainsight", - "description": "Test 7", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "domain": "demo-domain.gainsightcloud.com", - "accessKey": "sample-access-key", - "sharedSecret": "sample-shared-secret", - "eventNameMap": [ - { - "from": "Ticket Resolved", - "to": "Ticket Resolved Event" - } - ], - "eventVersionMap": [ - { - "from": "Ticket Resolved", - "to": "1.0.0" - } - ], - "topicName": "Ticket Actions", - "tenantId": "sample-tenant-id", - "personMap": [], - "companyMap": [], - "contractId": "externalId-shall-get-precedence" - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "gainsightEventContractId", - "id": "sample-contract-id" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "anon_id", - "type": "track", - "event": "Ticket Resolved", - "properties": { - "ticketId": "sample-ticket-id", - "actionEmail": "sample@email.com", - "status": "resovled" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "ticketId": "sample-ticket-id", - "actionEmail": "sample@email.com", - "status": "resovled" - } - }, - "type": "REST", - "files": {}, - "method": "POST", - "params": {}, - "headers": { - "Accesskey": "sample-access-key", - "tenantId": "sample-tenant-id", - "sharedSecret": "sample-shared-secret", - "Content-Type": "application/json", - "topicName": "Ticket Actions", - "eventName": "Ticket Resolved Event", - "eventVersion": "1.0.0", - "contractId": "sample-contract-id" - }, - "version": "1", - "endpoint": "https://demo-domain.gainsightcloud.com/v1.0/api/eventManager/event", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "gainsight", - "description": "Test 8", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "domain": "demo-domain.gainsightcloud.com", - "accessKey": "sample-access-key", - "personMap": [ - { - "from": "car", - "to": "car__gc" - } - ], - "companyMap": [], - "eventNameMap": [], - "eventVersionMap": [] - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "anon_id", - "type": "identify", - "traits": { - "name": "Bruce Wayne", - "email": "ceo@waynefoundation.com", - "car": "Batmobile", - "comments": "I am Batman!", - "lastName": "Wayne", - "location": "Gotham Central", - "firstName": "Bruce", - "linkedinUrl": "https://www.linkedin.com/in/notyourBatman/" - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {}, - "JSON": { - "Name": "Bruce Wayne", - "Email": "ceo@waynefoundation.com", - "car__gc": "Batmobile", - "Comments": "I am Batman!", - "LastName": "Wayne", - "Location": "Gotham Central", - "FirstName": "Bruce", - "LinkedinUrl": "https://www.linkedin.com/in/notyourBatman/" - } - }, - "type": "REST", - "files": {}, - "method": "PUT", - "params": {}, - "headers": { - "Accesskey": "sample-access-key", - "Content-Type": "application/json" - }, - "version": "1", - "endpoint": "https://demo-domain.gainsightcloud.com/v1.0/api/people", - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - } -] + { + name: 'gainsight', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + domain: 'demo-domain.gainsightcloud.com', + accessKey: 'sample-access-key', + personMap: [], + companyMap: [], + eventNameMap: [], + eventVersionMap: [], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + type: 'identify', + traits: { + email: 'cosmo@krammer.com', + name: 'Cosmo Krammer', + linkedinUrl: 'https://linkedin.com/cosmo-krammer', + location: 'New York', + emailOptOut: true, + masterAvatarTypeCode: 10, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + Email: 'cosmo@krammer.com', + Name: 'Cosmo Krammer', + LinkedinUrl: 'https://linkedin.com/cosmo-krammer', + Location: 'New York', + EmailOptOut: true, + MasterAvatarTypeCode: 10, + }, + }, + type: 'REST', + files: {}, + method: 'PUT', + params: {}, + headers: { + Accesskey: 'sample-access-key', + 'Content-Type': 'application/json', + }, + version: '1', + endpoint: 'https://demo-domain.gainsightcloud.com/v1.0/api/people', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'gainsight', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + domain: 'demo-domain.gainsightcloud.com', + accessKey: 'sample-access-key', + personMap: [ + { + from: 'age', + to: 'age__gc', + }, + ], + companyMap: [], + eventNameMap: [], + eventVersionMap: [], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + type: 'identify', + traits: { + email: 'cosmo@krammer.com', + name: 'Cosmo Krammer', + linkedinUrl: 'https://linkedin.com/cosmo-krammer', + location: 'New York', + emailOptOut: true, + masterAvatarTypeCode: 10, + age: 35, + randomKey: 'this should be dropped', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + Email: 'cosmo@krammer.com', + Name: 'Cosmo Krammer', + LinkedinUrl: 'https://linkedin.com/cosmo-krammer', + Location: 'New York', + EmailOptOut: true, + MasterAvatarTypeCode: 10, + age__gc: 35, + }, + }, + type: 'REST', + files: {}, + method: 'PUT', + params: {}, + headers: { + Accesskey: 'sample-access-key', + 'Content-Type': 'application/json', + }, + version: '1', + endpoint: 'https://demo-domain.gainsightcloud.com/v1.0/api/people', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'gainsight', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + domain: 'demo-domain.gainsightcloud.com', + accessKey: 'sample-access-key', + personMap: [], + companyMap: [], + eventNameMap: [], + eventVersionMap: [], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + type: 'identify', + traits: { + name: 'Cosmo Krammer', + linkedinUrl: 'https://linkedin.com/cosmo-krammer', + location: 'New York', + emailOptOut: true, + masterAvatarTypeCode: 10, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'email is required for identify', + statTags: { + destType: 'GAINSIGHT', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'gainsight', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + domain: 'demo-domain.gainsightcloud.com', + accessKey: 'sample-access-key', + sharedSecret: 'sample-shared-secret', + eventNameMap: [ + { + from: 'Ticket Resolved', + to: 'Ticket Resolved Event', + }, + ], + eventVersionMap: [ + { + from: 'Ticket Resolved', + to: '1.0.0', + }, + ], + topicName: 'Ticket Actions', + tenantId: 'sample-tenant-id', + personMap: [], + companyMap: [], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + type: 'track', + event: 'Ticket Resolved', + properties: { + ticketId: 'sample-ticket-id', + actionEmail: 'sample@email.com', + status: 'resovled', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + ticketId: 'sample-ticket-id', + actionEmail: 'sample@email.com', + status: 'resovled', + }, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + Accesskey: 'sample-access-key', + tenantId: 'sample-tenant-id', + sharedSecret: 'sample-shared-secret', + 'Content-Type': 'application/json', + topicName: 'Ticket Actions', + eventName: 'Ticket Resolved Event', + eventVersion: '1.0.0', + }, + version: '1', + endpoint: 'https://demo-domain.gainsightcloud.com/v1.0/api/eventManager/event', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'gainsight', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + domain: 'demo-domain.gainsightcloud.com', + accessKey: 'sample-access-key', + sharedSecret: 'sample-shared-secret', + personMap: [], + companyMap: [], + eventNameMap: [], + eventVersionMap: [], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + traits: { + email: 'krammer@seinfeld.com', + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + type: 'group', + traits: { + name: 'Kramerica Industries', + industry: 'Sitcom', + employees: '100', + status: 'complete', + companyType: 'spoof', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + Email: 'krammer@seinfeld.com', + companies: [ + { + Company_ID: '1P0203VCESP7AUQMV9E953G', + }, + ], + }, + }, + type: 'REST', + files: {}, + method: 'PUT', + params: {}, + headers: { + Accesskey: 'sample-access-key', + 'Content-Type': 'application/json', + }, + version: '1', + endpoint: 'https://demo-domain.gainsightcloud.com/v1.0/api/people', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'gainsight', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + domain: 'demo-domain.gainsightcloud.com', + accessKey: 'sample-access-key', + sharedSecret: 'sample-shared-secret', + personMap: [], + companyMap: [], + eventNameMap: [], + eventVersionMap: [], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + traits: { + email: 'krammer@seinfeld.com', + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + type: 'group', + traits: { + name: 'Seinfeld Corps', + industry: 'TV Series', + employees: '50', + status: 'complete', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + Email: 'krammer@seinfeld.com', + companies: [ + { + Company_ID: '1P0203VCESP7AUQMV9E953G', + }, + ], + }, + }, + type: 'REST', + files: {}, + method: 'PUT', + params: {}, + headers: { + Accesskey: 'sample-access-key', + 'Content-Type': 'application/json', + }, + version: '1', + endpoint: 'https://demo-domain.gainsightcloud.com/v1.0/api/people', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'gainsight', + description: 'Test 6', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + domain: 'demo-domain.gainsightcloud.com', + accessKey: 'sample-access-key', + personMap: [], + companyMap: [], + eventNameMap: [], + eventVersionMap: [], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + type: 'identify', + traits: { + email: 'cosmo@krammer.com', + firstname: 'Cosmo', + lastname: 'Krammer', + linkedinUrl: 'https://linkedin.com/cosmo-krammer', + location: 'New York', + emailOptOut: true, + masterAvatarTypeCode: 10, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + Email: 'cosmo@krammer.com', + FirstName: 'Cosmo', + LastName: 'Krammer', + Name: 'Cosmo Krammer', + LinkedinUrl: 'https://linkedin.com/cosmo-krammer', + Location: 'New York', + EmailOptOut: true, + MasterAvatarTypeCode: 10, + }, + }, + type: 'REST', + files: {}, + method: 'PUT', + params: {}, + headers: { + Accesskey: 'sample-access-key', + 'Content-Type': 'application/json', + }, + version: '1', + endpoint: 'https://demo-domain.gainsightcloud.com/v1.0/api/people', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'gainsight', + description: 'Test 7', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + domain: 'demo-domain.gainsightcloud.com', + accessKey: 'sample-access-key', + sharedSecret: 'sample-shared-secret', + eventNameMap: [ + { + from: 'Ticket Resolved', + to: 'Ticket Resolved Event', + }, + ], + eventVersionMap: [ + { + from: 'Ticket Resolved', + to: '1.0.0', + }, + ], + topicName: 'Ticket Actions', + tenantId: 'sample-tenant-id', + personMap: [], + companyMap: [], + contractId: 'externalId-shall-get-precedence', + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'gainsightEventContractId', + id: 'sample-contract-id', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + type: 'track', + event: 'Ticket Resolved', + properties: { + ticketId: 'sample-ticket-id', + actionEmail: 'sample@email.com', + status: 'resovled', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + ticketId: 'sample-ticket-id', + actionEmail: 'sample@email.com', + status: 'resovled', + }, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + Accesskey: 'sample-access-key', + tenantId: 'sample-tenant-id', + sharedSecret: 'sample-shared-secret', + 'Content-Type': 'application/json', + topicName: 'Ticket Actions', + eventName: 'Ticket Resolved Event', + eventVersion: '1.0.0', + contractId: 'sample-contract-id', + }, + version: '1', + endpoint: 'https://demo-domain.gainsightcloud.com/v1.0/api/eventManager/event', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'gainsight', + description: 'Test 8', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + domain: 'demo-domain.gainsightcloud.com', + accessKey: 'sample-access-key', + personMap: [ + { + from: 'car', + to: 'car__gc', + }, + ], + companyMap: [], + eventNameMap: [], + eventVersionMap: [], + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + type: 'identify', + traits: { + name: 'Bruce Wayne', + email: 'ceo@waynefoundation.com', + car: 'Batmobile', + comments: 'I am Batman!', + lastName: 'Wayne', + location: 'Gotham Central', + firstName: 'Bruce', + linkedinUrl: 'https://www.linkedin.com/in/notyourBatman/', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + Name: 'Bruce Wayne', + Email: 'ceo@waynefoundation.com', + car__gc: 'Batmobile', + Comments: 'I am Batman!', + LastName: 'Wayne', + Location: 'Gotham Central', + FirstName: 'Bruce', + LinkedinUrl: 'https://www.linkedin.com/in/notyourBatman/', + }, + }, + type: 'REST', + files: {}, + method: 'PUT', + params: {}, + headers: { + Accesskey: 'sample-access-key', + 'Content-Type': 'application/json', + }, + version: '1', + endpoint: 'https://demo-domain.gainsightcloud.com/v1.0/api/people', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/gainsight_px/network.ts b/test/integrations/destinations/gainsight_px/network.ts index d9dd6bbaa0e..99f51d9d8ef 100644 --- a/test/integrations/destinations/gainsight_px/network.ts +++ b/test/integrations/destinations/gainsight_px/network.ts @@ -1,222 +1,251 @@ export const networkCallsData = [ - { - httpReq: { - url: 'https://api.aptrinsic.com/v1/users/sample-user-id', - method: 'GET', - }, - httpRes: { - data: { - "aptrinsicId": "347c4c87-98c7-4ca6-a6da-678ed6924c22", - "identifyId": "sample-user-id", - "type": "USER", - "gender": "MALE", - "email": "user@email.com", - "firstName": "Sample", - "lastName": "User", - "lastSeenDate": 0, - "signUpDate": 1624431528295, - "firstVisitDate": 0, - "title": "engineer", - "phone": "", - "score": 0, - "role": "", - "subscriptionId": "", - "accountId": "", - "numberOfVisits": 1, - "location": { - "countryName": "USA", - "countryCode": "US", - "stateName": "", - "stateCode": "", - "city": "New York", - "street": "", - "postalCode": "", - "continent": "", - "regionName": "", - "timeZone": "", - "coordinates": { - "latitude": 0.0, - "longitude": 0.0 - } - }, - "propertyKeys": ["AP-XABC-123"], - "createDate": 1624431528295, - "lastModifiedDate": 1624431528295, - "customAttributes": null, - "globalUnsubscribe": false, - "sfdcContactId": "", - "lastVisitedUserAgentData": null, - "id": "sample-user-id", - "lastInferredLocation": { - "countryName": "", - "countryCode": "", - "stateName": "", - "stateCode": "", - "city": "", - "street": "", - "postalCode": "", - "continent": "", - "regionName": "", - "timeZone": "", - "coordinates": { - "latitude": 0.0, - "longitude": 0.0 - } - } - }, - status: 200 - }, + { + httpReq: { + url: 'https://api.aptrinsic.com/v1/users/sample-user-id', + method: 'GET', }, - { - httpReq: { - url: 'https://api.aptrinsic.com/v1/accounts/ecorp-id', - method: 'GET', + httpRes: { + data: { + aptrinsicId: '347c4c87-98c7-4ca6-a6da-678ed6924c22', + identifyId: 'sample-user-id', + type: 'USER', + gender: 'MALE', + email: 'user@email.com', + firstName: 'Sample', + lastName: 'User', + lastSeenDate: 0, + signUpDate: 1624431528295, + firstVisitDate: 0, + title: 'engineer', + phone: '', + score: 0, + role: '', + subscriptionId: '', + accountId: '', + numberOfVisits: 1, + location: { + countryName: 'USA', + countryCode: 'US', + stateName: '', + stateCode: '', + city: 'New York', + street: '', + postalCode: '', + continent: '', + regionName: '', + timeZone: '', + coordinates: { + latitude: 0.0, + longitude: 0.0, + }, }, - httpRes: { - data: { - "id": "ecorp-id", - "name": "ECorp", - "trackedSubscriptionId": "", - "sfdcId": "", - "lastSeenDate": 0, - "dunsNumber": "", - "industry": "software", - "numberOfEmployees": 400, - "sicCode": "", - "website": "www.ecorp.com", - "naicsCode": "", - "plan": "premium", - "location": { - "countryName": "", - "countryCode": "", - "stateName": "", - "stateCode": "", - "city": "", - "street": "", - "postalCode": "", - "continent": "", - "regionName": "", - "timeZone": "", - "coordinates": { - "latitude": 0.0, - "longitude": 0.0 - } - }, - "numberOfUsers": 0, - "propertyKeys": ["AP-XABC-123"], - "createDate": 1624261864923, - "lastModifiedDate": 1624261864923, - "customAttributes": null, - "parentGroupId": "" - }, - status: 200 + propertyKeys: ['AP-XABC-123'], + createDate: 1624431528295, + lastModifiedDate: 1624431528295, + customAttributes: null, + globalUnsubscribe: false, + sfdcContactId: '', + lastVisitedUserAgentData: null, + id: 'sample-user-id', + lastInferredLocation: { + countryName: '', + countryCode: '', + stateName: '', + stateCode: '', + city: '', + street: '', + postalCode: '', + continent: '', + regionName: '', + timeZone: '', + coordinates: { + latitude: 0.0, + longitude: 0.0, + }, }, + }, + status: 200, }, - { - httpReq: { - url: 'https://api.aptrinsic.com/v1/accounts/ecorp-id', - method: 'PUT', - }, - httpRes: { - data: { - "id": "ecorp-id", - "name": "ECorp", - "trackedSubscriptionId": "", - "sfdcId": "", - "lastSeenDate": 0, - "dunsNumber": "", - "industry": "software", - "numberOfEmployees": 400, - "sicCode": "", - "website": "www.ecorp.com", - "naicsCode": "", - "plan": "premium", - "location": { - "countryName": "", - "countryCode": "", - "stateName": "", - "stateCode": "", - "city": "", - "street": "", - "postalCode": "", - "continent": "", - "regionName": "", - "timeZone": "", - "coordinates": { - "latitude": 0.0, - "longitude": 0.0 - } - }, - "numberOfUsers": 0, - "propertyKeys": ["AP-XABC-123"], - "createDate": 1624261864923, - "lastModifiedDate": 1624261864923, - "customAttributes": null, - "parentGroupId": "" - }, - status: 204 + }, + { + httpReq: { + url: 'https://api.aptrinsic.com/v1/accounts/ecorp-id', + method: 'GET', + }, + httpRes: { + data: { + id: 'ecorp-id', + name: 'ECorp', + trackedSubscriptionId: '', + sfdcId: '', + lastSeenDate: 0, + dunsNumber: '', + industry: 'software', + numberOfEmployees: 400, + sicCode: '', + website: 'www.ecorp.com', + naicsCode: '', + plan: 'premium', + location: { + countryName: '', + countryCode: '', + stateName: '', + stateCode: '', + city: '', + street: '', + postalCode: '', + continent: '', + regionName: '', + timeZone: '', + coordinates: { + latitude: 0.0, + longitude: 0.0, + }, }, + numberOfUsers: 0, + propertyKeys: ['AP-XABC-123'], + createDate: 1624261864923, + lastModifiedDate: 1624261864923, + customAttributes: null, + parentGroupId: '', + }, + status: 200, + }, + }, + { + httpReq: { + url: 'https://api.aptrinsic.com/v1/accounts/ecorp-id', + method: 'PUT', }, - { - httpReq: { - url: 'https://api.aptrinsic.com/v1/users/absent-id', - method: 'GET', + httpRes: { + data: { + id: 'ecorp-id', + name: 'ECorp', + trackedSubscriptionId: '', + sfdcId: '', + lastSeenDate: 0, + dunsNumber: '', + industry: 'software', + numberOfEmployees: 400, + sicCode: '', + website: 'www.ecorp.com', + naicsCode: '', + plan: 'premium', + location: { + countryName: '', + countryCode: '', + stateName: '', + stateCode: '', + city: '', + street: '', + postalCode: '', + continent: '', + regionName: '', + timeZone: '', + coordinates: { + latitude: 0.0, + longitude: 0.0, + }, }, - httpRes: { - data: { - externalapierror: { - status: "NOT_FOUND", - message: "User was not found for parameters {id=absent-id}", - debugMessage: null, - subErrors: null - } - }, - status: 404 + numberOfUsers: 0, + propertyKeys: ['AP-XABC-123'], + createDate: 1624261864923, + lastModifiedDate: 1624261864923, + customAttributes: null, + parentGroupId: '', + }, + status: 204, + }, + }, + { + httpReq: { + url: 'https://api.aptrinsic.com/v1/users/absent-id', + method: 'GET', + }, + httpRes: { + data: { + externalapierror: { + status: 'NOT_FOUND', + message: 'User was not found for parameters {id=absent-id}', + debugMessage: null, + subErrors: null, }, + }, + status: 404, + }, + }, + { + httpReq: { + url: 'https://api.aptrinsic.com/v1/users/stanley-kubrick', + method: 'GET', }, - { - httpReq: { - url: 'https://api.aptrinsic.com/v1/users/stanley-kubrick', - method: 'GET', + httpRes: { + data: { + id: 'ecorp-id', + name: 'ECorp', + trackedSubscriptionId: '', + sfdcId: '', + lastSeenDate: 0, + dunsNumber: '', + industry: 'software', + numberOfEmployees: 400, + sicCode: '', + website: 'www.ecorp.com', + naicsCode: '', + plan: 'premium', + location: { + countryName: '', + countryCode: '', + stateName: '', + stateCode: '', + city: '', + street: '', + postalCode: '', + continent: '', + regionName: '', + timeZone: '', + coordinates: { + latitude: 0.0, + longitude: 0.0, + }, }, - httpRes: { - data: { - "id": "ecorp-id", - "name": "ECorp", - "trackedSubscriptionId": "", - "sfdcId": "", - "lastSeenDate": 0, - "dunsNumber": "", - "industry": "software", - "numberOfEmployees": 400, - "sicCode": "", - "website": "www.ecorp.com", - "naicsCode": "", - "plan": "premium", - "location": { - "countryName": "", - "countryCode": "", - "stateName": "", - "stateCode": "", - "city": "", - "street": "", - "postalCode": "", - "continent": "", - "regionName": "", - "timeZone": "", - "coordinates": { - "latitude": 0.0, - "longitude": 0.0 - } - }, - "numberOfUsers": 0, - "propertyKeys": ["AP-XABC-123"], - "createDate": 1624261864923, - "lastModifiedDate": 1624261864923, - "customAttributes": null, - "parentGroupId": "" - }, - status: 200 + numberOfUsers: 0, + propertyKeys: ['AP-XABC-123'], + createDate: 1624261864923, + lastModifiedDate: 1624261864923, + customAttributes: null, + parentGroupId: '', + }, + status: 200, + }, + }, + // Axios Error + { + httpReq: { + url: 'https://api.aptrinsic.com/v1/users/myUId', + headers: { 'X-APTRINSIC-API-KEY': 'sample-api-key', 'Content-Type': 'application/json' }, + method: 'GET', + }, + httpRes: { + message: 'Request failed with status code 403', + name: 'AxiosError', + stack: + 'AxiosError: Request failed with status code 403\n at settle (/Users/saisankeerth/rudderstack/rudder-transformer/node_modules/axios/lib/core/settle.js:19:12)\n at IncomingMessage.handleStreamEnd (/Users/saisankeerth/rudderstack/rudder-transformer/node_modules/axios/lib/adapters/http.js:589:11)\n at IncomingMessage.emit (node:events:529:35)\n at IncomingMessage.emit (node:domain:489:12)\n at endReadableNT (node:internal/streams/readable:1400:12)\n at processTicksAndRejections (node:internal/process/task_queues:82:21)', + config: { + headers: { + Accept: 'application/json, text/plain, */*', + 'Content-Type': 'application/json', + 'X-APTRINSIC-API-KEY': 'sample-api-key', + 'User-Agent': 'axios/1.6.5', + 'Accept-Encoding': 'gzip, compress, deflate, br', }, - } + method: 'get', + dummy: 'upgrade required', // keyword + url: 'https://api.aptrinsic.com/v1/users/myUId', + }, + code: 'FORBIDDEN', + status: 403, + data: '\u003c!doctype html\u003e\u003cmeta charset="utf-8"\u003e\u003cmeta name=viewport content="width=device-width, initial-scale=1"\u003e\u003ctitle\u003e403\u003c/title\u003e403 Forbidden', + }, + }, ]; diff --git a/test/integrations/destinations/gainsight_px/router/data.ts b/test/integrations/destinations/gainsight_px/router/data.ts index 7dc131127da..1b3d5be8756 100644 --- a/test/integrations/destinations/gainsight_px/router/data.ts +++ b/test/integrations/destinations/gainsight_px/router/data.ts @@ -1,3 +1,75 @@ +const metadata = { + userId: '9a7820d0-0ff2-4451-b655-682cec15cbd2', + jobId: 1, + sourceId: '1s9eG8UCer6YSKsD8ZlQCyLa3pj', + destinationId: 'desId2', + attemptNum: 0, + receivedAt: '2021-06-25T14:29:52.911+05:30', + createdAt: '2021-06-25T08:59:56.329Z', + firstAttemptedAt: '', + transformAt: 'router', +}; +const destination2 = { + ID: 'desId2', + Name: 'gainsight-px-dest', + DestinationDefinition: { + ID: 'destDef1', + Name: 'GAINSIGHT_PX', + DisplayName: 'Gainsight PX', + Config: { + destConfig: { + defaultConfig: [ + 'apiKey', + 'productTagKey', + 'userAttributeMap', + 'accountAttributeMap', + 'globalContextMap', + ], + }, + excludeKeys: [], + includeKeys: [], + saveDestinationResponse: true, + secretKeys: ['apiKey', 'productTagKey'], + supportedSourceTypes: [ + 'android', + 'ios', + 'web', + 'unity', + 'amp', + 'cloud', + 'reactnative', + 'flutter', + ], + transformAt: 'router', + transformAtV1: 'router', + }, + ResponseRules: {}, + }, + Config: { + accountAttributeMap: [ + { from: 'LAST_INVOICE_DATE', to: 'last_invoice_date' }, + { from: 'LAST_INVOICE_PLAN', to: 'last_invoice_plan' }, + { from: 'LANGUAGE', to: 'language' }, + { from: 'REGION', to: 'region2' }, + { from: 'LAST_INVOICE_CURRENCY', to: 'last_invoice_currency' }, + { from: 'IBR_PLAN', to: 'ibr_plan' }, + { from: 'WH_COUNTRY', to: 'wh_country' }, + { from: 'inboxready_signup_date', to: 'inboxready_signup_date' }, + { from: 'gpt_setup', to: 'gpt_setup' }, + ], + oneTrustCookieCategories: [], + apiKey: 'sample-api-key', + eventDelivery: false, + eventDeliveryTS: 1624472902670, + globalContextMap: [{ from: 'kubrickTest', to: 'value' }], + productTagKey: 'AP-SAMPLE-2', + userAttributeMap: [{ from: 'hobbyCustomField', to: 'hobby' }], + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, +}; + export const data = [ { name: 'gainsight_px', @@ -463,4 +535,85 @@ export const data = [ }, }, }, + { + name: 'gainsight_px', + description: 'Test 1: Group call -- AxiosError thrown', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + type: 'group', + sentAt: '2024-02-16T06:00:54.075Z', + traits: { + name: ',sleep(100)', + REGION: 'MEA', + USERID: 'myUId', + groupId: 'myGId', + IBR_PLAN: 'free_ir', + LANGUAGE: 'EN', + gpt_setup: false, + ACCOUNT_ID: 'myGId', + WH_COUNTRY: 'MA', + LAST_INVOICE_DATE: 1706810675000, + LAST_INVOICE_PLAN: 'foundation_trial', + LAST_INVOICE_CURRENCY: 'USD', + inboxready_signup_date: 1680254544705, + }, + userId: 'myUId', + channel: 'sources', + context: { + sources: { + job_run_id: 'cn7fjonu4d9b3u706u2g', + task_run_id: 'cn7fjonu4d9b3u706u3g', + }, + }, + recordId: '111111', + rudderId: 'dummy-rudder-id', + timestamp: '2024-02-16T06:00:52.581Z', + receivedAt: '2024-02-16T06:00:52.582Z', + request_ip: '10.7.150.126', + anonymousId: 'myUId', + integrations: { limitAPIForGroup: true }, + originalTimestamp: '2024-02-16T06:00:54.075Z', + }, + metadata, + destination: destination2, + }, + ], + destType: 'gainsight_px', + }, + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + error: + '{"message":"error while fetching user: \\"403403 Forbidden\\"","destinationResponse":"403403 Forbidden"}', + statTags: { + destType: 'GAINSIGHT_PX', + destinationId: destination2.ID, + errorCategory: 'network', + errorType: 'aborted', + feature: 'router', + implementation: 'native', + module: 'destination', + }, + statusCode: 403, + metadata: [metadata], + batched: false, + destination: destination2, + }, + ], + }, + }, + }, + }, ]; diff --git a/test/integrations/destinations/gcs_datalake/processor/data.ts b/test/integrations/destinations/gcs_datalake/processor/data.ts index 4f5d144b296..46c77887091 100644 --- a/test/integrations/destinations/gcs_datalake/processor/data.ts +++ b/test/integrations/destinations/gcs_datalake/processor/data.ts @@ -1,191 +1,194 @@ export const data = [ { - name: 'gcs_datalake', - description: 'No Message type', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - "message": { - "receivedAt": "2023-09-29T15:07:16.650Z", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "test@rudderstack.com" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "type": "track", - "messageId": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "originalTimestamp": "2019-10-14T11:15:18.300Z", - "anonymousId": "00000000000000000000000000", - "userId": "12345", - "event": "Product List Clicked", - "properties": { - "list_id": "Sample Product List", - "category": "Sample Product List", - "products": [] - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T11:15:53.296Z" - }, - "destination": { - "Config": { - "bucketName": "ps-data-mdm-prod-rudderstack", - "prefix": "", - "namespace": "", - "credentials": "randomcreds", - "syncFrequency": "30", - "tableSuffix": "", - "timeWindowLayout": "2006/01/02/15" - }, - "Enabled": true - } - }, - ], - method: 'POST', + name: 'gcs_datalake', + description: 'No Message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + receivedAt: '2023-09-29T15:07:16.650Z', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'Product List Clicked', + properties: { + list_id: 'Sample Product List', + category: 'Sample Product List', + products: [], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + bucketName: 'ps-data-mdm-prod-rudderstack', + prefix: '', + namespace: '', + credentials: 'randomcreds', + syncFrequency: '30', + tableSuffix: '', + timeWindowLayout: '2006/01/02/15', + }, + Enabled: true, + }, }, - pathSuffix: '', + ], + method: 'POST', }, - output: { - response: { - status: 200, - body: [ - { - "output": { - "metadata": { - "table": "tracks", - "columns": { - "uuid_ts": "datetime", - "context_app_build": "string", - "context_app_name": "string", - "context_app_namespace": "string", - "context_app_version": "string", - "context_traits_email": "string", - "context_library_name": "string", - "context_library_version": "string", - "context_user_agent": "string", - "context_locale": "string", - "context_screen_density": "int", - "event_text": "string", - "id": "string", - "anonymous_id": "string", - "user_id": "string", - "sent_at": "datetime", - "received_at": "datetime", - "original_timestamp": "datetime", - "channel": "string", - "event": "string" - }, - "receivedAt": "2023-09-29T15:07:16.650Z" - }, - "data": { - "context_app_build": "1.0.0", - "context_app_name": "RudderLabs JavaScript SDK", - "context_app_namespace": "com.rudderlabs.javascript", - "context_app_version": "1.0.0", - "context_traits_email": "test@rudderstack.com", - "context_library_name": "RudderLabs JavaScript SDK", - "context_library_version": "1.0.0", - "context_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "context_locale": "en-US", - "context_screen_density": 2, - "event_text": "Product List Clicked", - "id": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "anonymous_id": "00000000000000000000000000", - "user_id": "12345", - "sent_at": "2019-10-14T11:15:53.296Z", - "received_at": "2023-09-29T15:07:16.650Z", - "original_timestamp": "2019-10-14T11:15:18.300Z", - "channel": "web", - "event": "product_list_clicked" - }, - "userId": "" - }, - "statusCode": 200 - }, - { - "output": { - "metadata": { - "table": "product_list_clicked", - "columns": { - "uuid_ts": "datetime", - "list_id": "string", - "category": "string", - "context_app_build": "string", - "context_app_name": "string", - "context_app_namespace": "string", - "context_app_version": "string", - "context_traits_email": "string", - "context_library_name": "string", - "context_library_version": "string", - "context_user_agent": "string", - "context_locale": "string", - "context_screen_density": "int", - "event_text": "string", - "id": "string", - "anonymous_id": "string", - "user_id": "string", - "sent_at": "datetime", - "received_at": "datetime", - "original_timestamp": "datetime", - "channel": "string", - "event": "string" - }, - "receivedAt": "2023-09-29T15:07:16.650Z" - }, - "data": { - "list_id": "Sample Product List", - "category": "Sample Product List", - "context_app_build": "1.0.0", - "context_app_name": "RudderLabs JavaScript SDK", - "context_app_namespace": "com.rudderlabs.javascript", - "context_app_version": "1.0.0", - "context_traits_email": "test@rudderstack.com", - "context_library_name": "RudderLabs JavaScript SDK", - "context_library_version": "1.0.0", - "context_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "context_locale": "en-US", - "context_screen_density": 2, - "event_text": "Product List Clicked", - "id": "ec5481b6-a926-4d2e-b293-0b3a77c4d3be", - "anonymous_id": "00000000000000000000000000", - "user_id": "12345", - "sent_at": "2019-10-14T11:15:53.296Z", - "received_at": "2023-09-29T15:07:16.650Z", - "original_timestamp": "2019-10-14T11:15:18.300Z", - "channel": "web", - "event": "product_list_clicked" - }, - "userId": "" - }, - "statusCode": 200 - } - ], + pathSuffix: '', + }, + output: { + response: { + status: 200, + body: [ + { + output: { + metadata: { + table: 'tracks', + columns: { + uuid_ts: 'datetime', + context_app_build: 'string', + context_app_name: 'string', + context_app_namespace: 'string', + context_app_version: 'string', + context_traits_email: 'string', + context_library_name: 'string', + context_library_version: 'string', + context_user_agent: 'string', + context_locale: 'string', + context_screen_density: 'int', + event_text: 'string', + id: 'string', + anonymous_id: 'string', + user_id: 'string', + sent_at: 'datetime', + received_at: 'datetime', + original_timestamp: 'datetime', + channel: 'string', + event: 'string', + }, + receivedAt: '2023-09-29T15:07:16.650Z', + }, + data: { + context_app_build: '1.0.0', + context_app_name: 'RudderLabs JavaScript SDK', + context_app_namespace: 'com.rudderlabs.javascript', + context_app_version: '1.0.0', + context_traits_email: 'test@rudderstack.com', + context_library_name: 'RudderLabs JavaScript SDK', + context_library_version: '1.0.0', + context_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + context_locale: 'en-US', + context_screen_density: 2, + event_text: 'Product List Clicked', + id: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + anonymous_id: '00000000000000000000000000', + user_id: '12345', + sent_at: '2019-10-14T11:15:53.296Z', + received_at: '2023-09-29T15:07:16.650Z', + original_timestamp: '2019-10-14T11:15:18.300Z', + channel: 'web', + event: 'product_list_clicked', + }, + userId: '', + }, + statusCode: 200, }, + { + output: { + metadata: { + table: 'product_list_clicked', + columns: { + uuid_ts: 'datetime', + list_id: 'string', + category: 'string', + context_app_build: 'string', + context_app_name: 'string', + context_app_namespace: 'string', + context_app_version: 'string', + context_traits_email: 'string', + context_library_name: 'string', + context_library_version: 'string', + context_user_agent: 'string', + context_locale: 'string', + context_screen_density: 'int', + event_text: 'string', + id: 'string', + anonymous_id: 'string', + user_id: 'string', + sent_at: 'datetime', + received_at: 'datetime', + original_timestamp: 'datetime', + channel: 'string', + event: 'string', + }, + receivedAt: '2023-09-29T15:07:16.650Z', + }, + data: { + list_id: 'Sample Product List', + category: 'Sample Product List', + context_app_build: '1.0.0', + context_app_name: 'RudderLabs JavaScript SDK', + context_app_namespace: 'com.rudderlabs.javascript', + context_app_version: '1.0.0', + context_traits_email: 'test@rudderstack.com', + context_library_name: 'RudderLabs JavaScript SDK', + context_library_version: '1.0.0', + context_user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + context_locale: 'en-US', + context_screen_density: 2, + event_text: 'Product List Clicked', + id: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + anonymous_id: '00000000000000000000000000', + user_id: '12345', + sent_at: '2019-10-14T11:15:53.296Z', + received_at: '2023-09-29T15:07:16.650Z', + original_timestamp: '2019-10-14T11:15:18.300Z', + channel: 'web', + event: 'product_list_clicked', + }, + userId: '', + }, + statusCode: 200, + }, + ], }, - } + }, + }, ]; diff --git a/test/integrations/destinations/google_adwords_enhanced_conversions/dataDelivery/business.ts b/test/integrations/destinations/google_adwords_enhanced_conversions/dataDelivery/business.ts new file mode 100644 index 00000000000..0cee1418e1b --- /dev/null +++ b/test/integrations/destinations/google_adwords_enhanced_conversions/dataDelivery/business.ts @@ -0,0 +1,284 @@ +import { + generateMetadata, + generateProxyV0Payload, + generateProxyV1Payload, +} from '../../../testUtils'; +import { ProxyV1TestData } from '../../../testTypes'; + +const headers = { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + 'login-customer-id': '0987654321', +}; + +const params = { + event: 'Product Added', + customerId: '1234567899', + destination: 'google_adwords_enhanced_conversions', +}; + +const validRequestPaylod = { + partialFailure: true, + conversionAdjustments: [ + { + gclidDateTimePair: { + gclid: 'gclid1234', + conversionDateTime: '2022-01-01 12:32:45-08:00', + }, + restatementValue: { + adjustedValue: 10, + currency: 'INR', + }, + order_id: '10000', + adjustmentDateTime: '2022-01-01 12:32:45-08:00', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + userIdentifiers: [ + { + addressInfo: { + hashedFirstName: 'a8cfcd74832004951b4408cdb0a5dbcd8c7e52d43f7fe244bf720582e05241da', + hashedLastName: '1c574b17eefa532b6d61c963550a82d2d3dfca4a7fb69e183374cfafd5328ee4', + state: 'UK', + city: 'London', + hashedStreetAddress: '9a4d2e50828448f137f119a3ebdbbbab8d6731234a67595fdbfeb2a2315dd550', + }, + }, + ], + adjustmentType: 'ENHANCEMENT', + }, + ], +}; + +const commonRequestParameters = { + headers, + params, + JSON: validRequestPaylod, +}; + +const expectedStatTags = { + destType: 'GOOGLE_ADWORDS_ENHANCED_CONVERSIONS', + destinationId: 'default-destinationId', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'default-workspaceId', +}; + +export const testScenariosForV0API = [ + { + id: 'gaec_v0_scenario_1', + name: 'google_adwords_enhanced_conversions', + description: + '[Proxy v0 API] :: Test for a valid request with a successful 200 response from the destination', + successCriteria: 'Should return 200 with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: + 'https://googleads.googleapis.com/v15/customers/1234567899:uploadConversionAdjustments', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + destinationResponse: { + response: [ + { + results: [ + { + adjustmentDateTime: '2021-01-01 12:32:45-08:00', + adjustmentType: 'ENHANCEMENT', + conversionAction: 'customers/7693729833/conversionActions/874224905', + gclidDateTimePair: { + conversionDateTime: '2021-01-01 12:32:45-08:00', + gclid: '1234', + }, + orderId: '12345', + }, + ], + }, + ], + status: 200, + }, + message: 'Request Processed Successfully', + status: 200, + }, + }, + }, + }, + }, + { + id: 'gaec_v0_scenario_2', + name: 'google_adwords_enhanced_conversions', + description: + '[Proxy v0 API] :: Test for a partial failure request with a 200 response from the destination', + successCriteria: 'Should return 400 with partial failure error', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + params: { + event: 'Product Added', + customerId: '1234567888', + destination: 'google_adwords_enhanced_conversions', + }, + endpoint: + 'https://googleads.googleapis.com/v15/customers/1234567888:uploadConversionAdjustments', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: { + code: 3, + details: [ + { + '@type': 'type.googleapis.com/google.ads.googleads.v15.errors.GoogleAdsFailure', + errors: [ + { + errorCode: { + conversionAdjustmentUploadError: 'CONVERSION_ALREADY_ENHANCED', + }, + location: { + fieldPathElements: [ + { + fieldName: 'conversion_adjustments', + index: 0, + }, + ], + }, + message: + 'Conversion already has enhancements with the same Order ID and conversion action. Make sure your data is correctly configured and try again.', + }, + ], + }, + ], + message: + 'Conversion already has enhancements with the same Order ID and conversion action. Make sure your data is correctly configured and try again., at conversion_adjustments[0]', + }, + message: + '[Google Adwords Enhanced Conversions]:: partialFailureError - {"code":3,"message":"Conversion already has enhancements with the same Order ID and conversion action. Make sure your data is correctly configured and try again., at conversion_adjustments[0]","details":[{"@type":"type.googleapis.com/google.ads.googleads.v15.errors.GoogleAdsFailure","errors":[{"errorCode":{"conversionAdjustmentUploadError":"CONVERSION_ALREADY_ENHANCED"},"message":"Conversion already has enhancements with the same Order ID and conversion action. Make sure your data is correctly configured and try again.","location":{"fieldPathElements":[{"fieldName":"conversion_adjustments","index":0}]}}]}]}', + statTags: expectedStatTags, + status: 400, + }, + }, + }, + }, + }, +]; + +export const testScenariosForV1API: ProxyV1TestData[] = [ + { + id: 'gaec_v1_scenario_1', + name: 'google_adwords_enhanced_conversions', + description: + '[Proxy v1 API] :: Test for a valid request with a successful 200 response from the destination', + successCriteria: 'Should return 200 with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: + 'https://googleads.googleapis.com/v15/customers/1234567899:uploadConversionAdjustments', + }, + [generateMetadata(1)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + response: [ + { + error: + '[{"results":[{"adjustmentType":"ENHANCEMENT","conversionAction":"customers/7693729833/conversionActions/874224905","adjustmentDateTime":"2021-01-01 12:32:45-08:00","gclidDateTimePair":{"gclid":"1234","conversionDateTime":"2021-01-01 12:32:45-08:00"},"orderId":"12345"}]}]', + metadata: generateMetadata(1), + statusCode: 200, + }, + ], + status: 200, + }, + }, + }, + }, + }, + { + id: 'gaec_v1_scenario_2', + name: 'google_adwords_enhanced_conversions', + description: + '[Proxy v1 API] :: Test for a partial failure request with a 200 response from the destination', + successCriteria: 'Should return 400 with partial failure error', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + params: { + event: 'Product Added', + customerId: '1234567888', + destination: 'google_adwords_enhanced_conversions', + }, + endpoint: + 'https://googleads.googleapis.com/v15/customers/1234567888:uploadConversionAdjustments', + }, + [generateMetadata(1)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: + '[Google Adwords Enhanced Conversions]:: partialFailureError - {"code":3,"message":"Conversion already has enhancements with the same Order ID and conversion action. Make sure your data is correctly configured and try again., at conversion_adjustments[0]","details":[{"@type":"type.googleapis.com/google.ads.googleads.v15.errors.GoogleAdsFailure","errors":[{"errorCode":{"conversionAdjustmentUploadError":"CONVERSION_ALREADY_ENHANCED"},"message":"Conversion already has enhancements with the same Order ID and conversion action. Make sure your data is correctly configured and try again.","location":{"fieldPathElements":[{"fieldName":"conversion_adjustments","index":0}]}}]}]}', + response: [ + { + error: + '[Google Adwords Enhanced Conversions]:: partialFailureError - {"code":3,"message":"Conversion already has enhancements with the same Order ID and conversion action. Make sure your data is correctly configured and try again., at conversion_adjustments[0]","details":[{"@type":"type.googleapis.com/google.ads.googleads.v15.errors.GoogleAdsFailure","errors":[{"errorCode":{"conversionAdjustmentUploadError":"CONVERSION_ALREADY_ENHANCED"},"message":"Conversion already has enhancements with the same Order ID and conversion action. Make sure your data is correctly configured and try again.","location":{"fieldPathElements":[{"fieldName":"conversion_adjustments","index":0}]}}]}]}', + metadata: generateMetadata(1), + statusCode: 400, + }, + ], + statTags: expectedStatTags, + status: 400, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/google_adwords_enhanced_conversions/dataDelivery/data.ts b/test/integrations/destinations/google_adwords_enhanced_conversions/dataDelivery/data.ts index b544baaebdc..709ab6d2a8a 100644 --- a/test/integrations/destinations/google_adwords_enhanced_conversions/dataDelivery/data.ts +++ b/test/integrations/destinations/google_adwords_enhanced_conversions/dataDelivery/data.ts @@ -1,307 +1,9 @@ +import { v0oauthScenarios, v1oauthScenarios } from './oauth'; +import { testScenariosForV0API, testScenariosForV1API } from './business'; + export const data = [ - { - name: 'google_adwords_enhanced_conversions', - description: 'Test 0', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: - 'https://googleads.googleapis.com/v15/customers/1234567890:uploadConversionAdjustments', - headers: { - Authorization: 'Bearer abcd1234', - 'Content-Type': 'application/json', - 'developer-token': 'ijkl91011', - 'login-customer-id': '0987654321', - }, - params: { - event: 'Product Added', - customerId: '1234567890', - destination: 'google_adwords_enhanced_conversions', - }, - body: { - JSON: { - partialFailure: true, - conversionAdjustments: [ - { - gclidDateTimePair: { - gclid: 'gclid1234', - conversionDateTime: '2022-01-01 12:32:45-08:00', - }, - restatementValue: { - adjustedValue: 10, - currency: 'INR', - }, - order_id: '10000', - adjustmentDateTime: '2022-01-01 12:32:45-08:00', - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - userIdentifiers: [ - { - addressInfo: { - hashedFirstName: - 'a8cfcd74832004951b4408cdb0a5dbcd8c7e52d43f7fe244bf720582e05241da', - hashedLastName: - '1c574b17eefa532b6d61c963550a82d2d3dfca4a7fb69e183374cfafd5328ee4', - state: 'UK', - city: 'London', - hashedStreetAddress: - '9a4d2e50828448f137f119a3ebdbbbab8d6731234a67595fdbfeb2a2315dd550', - }, - }, - ], - adjustmentType: 'ENHANCEMENT', - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - }, - method: 'POST', - }, - }, - output: { - response: { - status: 401, - body: { - output: { - message: - '""Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project." during Google_adwords_enhanced_conversions response transformation"', - authErrorCategory: 'REFRESH_TOKEN', - destinationResponse: [ - { - error: { - code: 401, - message: - 'Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.', - status: 'UNAUTHENTICATED', - }, - }, - ], - statTags: { - destType: 'GOOGLE_ADWORDS_ENHANCED_CONVERSIONS', - errorCategory: 'network', - destinationId: 'Non-determininable', - workspaceId: 'Non-determininable', - errorType: 'aborted', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', - }, - status: 401, - }, - }, - }, - }, - }, - { - name: 'google_adwords_enhanced_conversions', - description: 'Test 1', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: - 'https://googleads.googleapis.com/v15/customers/1234567899:uploadConversionAdjustments', - headers: { - Authorization: 'Bearer abcd1234', - 'Content-Type': 'application/json', - 'developer-token': 'ijkl91011', - 'login-customer-id': '0987654321', - }, - params: { - event: 'Product Added', - customerId: '1234567899', - destination: 'google_adwords_enhanced_conversions', - }, - body: { - JSON: { - partialFailure: true, - conversionAdjustments: [ - { - gclidDateTimePair: { - gclid: 'gclid1234', - conversionDateTime: '2022-01-01 12:32:45-08:00', - }, - restatementValue: { - adjustedValue: 10, - currency: 'INR', - }, - order_id: '10000', - adjustmentDateTime: '2022-01-01 12:32:45-08:00', - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - userIdentifiers: [ - { - addressInfo: { - hashedFirstName: - 'a8cfcd74832004951b4408cdb0a5dbcd8c7e52d43f7fe244bf720582e05241da', - hashedLastName: - '1c574b17eefa532b6d61c963550a82d2d3dfca4a7fb69e183374cfafd5328ee4', - state: 'UK', - city: 'London', - hashedStreetAddress: - '9a4d2e50828448f137f119a3ebdbbbab8d6731234a67595fdbfeb2a2315dd550', - }, - }, - ], - adjustmentType: 'ENHANCEMENT', - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - }, - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: { - output: { - destinationResponse: { - response: [ - { - results: [ - { - adjustmentDateTime: '2021-01-01 12:32:45-08:00', - adjustmentType: 'ENHANCEMENT', - conversionAction: 'customers/7693729833/conversionActions/874224905', - gclidDateTimePair: { - conversionDateTime: '2021-01-01 12:32:45-08:00', - gclid: '1234', - }, - orderId: '12345', - }, - ], - }, - ], - status: 200, - }, - message: 'Request Processed Successfully', - status: 200, - }, - }, - }, - }, - }, - { - name: 'google_adwords_enhanced_conversions', - description: 'Test 2', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: - 'https://googleads.googleapis.com/v15/customers/1234567891:uploadConversionAdjustments', - headers: { - Authorization: 'Bearer abcd1234', - 'Content-Type': 'application/json', - 'developer-token': 'ijkl91011', - 'login-customer-id': '0987654321', - }, - params: { - event: 'Product Added', - customerId: '1234567891', - destination: 'google_adwords_enhanced_conversions', - }, - body: { - JSON: { - partialFailure: true, - conversionAdjustments: [ - { - gclidDateTimePair: { - gclid: 'gclid1234', - conversionDateTime: '2022-01-01 12:32:45-08:00', - }, - restatementValue: { - adjustedValue: 10, - currency: 'INR', - }, - order_id: '10000', - adjustmentDateTime: '2022-01-01 12:32:45-08:00', - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - userIdentifiers: [ - { - addressInfo: { - hashedFirstName: - 'a8cfcd74832004951b4408cdb0a5dbcd8c7e52d43f7fe244bf720582e05241da', - hashedLastName: - '1c574b17eefa532b6d61c963550a82d2d3dfca4a7fb69e183374cfafd5328ee4', - state: 'UK', - city: 'London', - hashedStreetAddress: - '9a4d2e50828448f137f119a3ebdbbbab8d6731234a67595fdbfeb2a2315dd550', - }, - }, - ], - adjustmentType: 'ENHANCEMENT', - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - }, - method: 'POST', - }, - }, - output: { - response: { - status: 400, - body: { - output: { - destinationResponse: [ - { - results: [ - { - conversionAction: { - id: 123434342, - }, - }, - ], - }, - ], - message: '" during Google_adwords_enhanced_conversions response transformation', - statTags: { - destType: 'GOOGLE_ADWORDS_ENHANCED_CONVERSIONS', - destinationId: 'Non-determininable', - errorCategory: 'network', - errorType: 'aborted', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', - workspaceId: 'Non-determininable', - }, - status: 400, - }, - }, - }, - }, - }, + ...v0oauthScenarios, + ...v1oauthScenarios, + ...testScenariosForV0API, + ...testScenariosForV1API, ]; diff --git a/test/integrations/destinations/google_adwords_enhanced_conversions/dataDelivery/oauth.ts b/test/integrations/destinations/google_adwords_enhanced_conversions/dataDelivery/oauth.ts new file mode 100644 index 00000000000..70d9eeaf330 --- /dev/null +++ b/test/integrations/destinations/google_adwords_enhanced_conversions/dataDelivery/oauth.ts @@ -0,0 +1,276 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { + generateProxyV1Payload, + generateProxyV0Payload, + generateMetadata, +} from '../../../testUtils'; + +const requestPayload = { + partialFailure: true, + conversionAdjustments: [ + { + gclidDateTimePair: { + gclid: 'gclid1234', + conversionDateTime: '2022-01-01 12:32:45-08:00', + }, + restatementValue: { + adjustedValue: 10, + currency: 'INR', + }, + order_id: '10000', + adjustmentDateTime: '2022-01-01 12:32:45-08:00', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + userIdentifiers: [ + { + addressInfo: { + hashedFirstName: 'a8cfcd74832004951b4408cdb0a5dbcd8c7e52d43f7fe244bf720582e05241da', + hashedLastName: '1c574b17eefa532b6d61c963550a82d2d3dfca4a7fb69e183374cfafd5328ee4', + state: 'UK', + city: 'London', + hashedStreetAddress: '9a4d2e50828448f137f119a3ebdbbbab8d6731234a67595fdbfeb2a2315dd550', + }, + }, + ], + adjustmentType: 'ENHANCEMENT', + }, + ], +}; + +const headers = { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + 'login-customer-id': '0987654321', +}; + +const params = { + event: 'Product Added', + customerId: '1234567890', + destination: 'google_adwords_enhanced_conversions', +}; + +const commonRequestParameters = { + params, + headers, + JSON: requestPayload, +}; + +const expectedStatTags = { + destType: 'GOOGLE_ADWORDS_ENHANCED_CONVERSIONS', + destinationId: 'default-destinationId', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'default-workspaceId', +}; + +export const v0oauthScenarios = [ + { + id: 'gaec_v0_oauth_scenario_1', + name: 'google_adwords_enhanced_conversions', + description: + '[Proxy v0 API] :: Oauth where valid credentials are missing as mock response from destination', + successCriteria: + 'Since the error from the destination is 401 - the proxy should return 500 with authErrorCategory as REFRESH_TOKEN', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: + 'https://googleads.googleapis.com/v15/customers/1234567890:uploadConversionAdjustments', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 401, + body: { + output: { + authErrorCategory: 'REFRESH_TOKEN', + destinationResponse: [ + { + error: { + code: 401, + message: + 'Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.', + status: 'UNAUTHENTICATED', + }, + }, + ], + message: + '""Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project." during Google_adwords_enhanced_conversions response transformation"', + statTags: expectedStatTags, + status: 401, + }, + }, + }, + }, + }, + { + id: 'gaec_v0_oauth_scenario_2', + name: 'google_adwords_enhanced_conversions', + description: + '[Proxy v0 API] :: Oauth where caller does not have permission mock response from destination', + successCriteria: + 'Since the error from the destination is 403 - the proxy should return 403 with error', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + JSON: { + query: `SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = 'Product Added'`, + }, + headers, + params: { + event: 'Product Added', + customerId: '1234567910', + destination: 'google_adwords_enhanced_conversions', + }, + endpoint: + 'https://googleads.googleapis.com/v15/customers/1234567910/googleAds:searchStream', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 403, + body: { + output: { + authErrorCategory: 'AUTH_STATUS_INACTIVE', + destinationResponse: [ + { + error: { + code: 403, + errors: [ + { + domain: 'global', + message: 'The caller does not have permission', + reason: 'forbidden', + }, + ], + message: 'The caller does not have permission', + status: 'PERMISSION_DENIED', + }, + }, + ], + message: + '""The caller does not have permission" during Google_adwords_enhanced_conversions response transformation"', + statTags: expectedStatTags, + status: 403, + }, + }, + }, + }, + }, +]; + +export const v1oauthScenarios = [ + { + id: 'gaec_v1_oauth_scenario_1', + name: 'google_adwords_enhanced_conversions', + description: + '[Proxy v1 API] :: Oauth where valid credentials are missing as mock response from destination', + successCriteria: + 'Since the error from the destination is 401 - the proxy should return 500 with authErrorCategory as REFRESH_TOKEN', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + ...commonRequestParameters, + endpoint: + 'https://googleads.googleapis.com/v15/customers/1234567890:uploadConversionAdjustments', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 401, + body: { + output: { + authErrorCategory: 'REFRESH_TOKEN', + message: + '""Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project." during Google_adwords_enhanced_conversions response transformation"', + response: [ + { + error: + '""Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project." during Google_adwords_enhanced_conversions response transformation"', + metadata: generateMetadata(1), + statusCode: 401, + }, + ], + statTags: expectedStatTags, + status: 401, + }, + }, + }, + }, + }, + { + id: 'gaec_v1_oauth_scenario_2', + name: 'google_adwords_enhanced_conversions', + description: + '[Proxy v1 API] :: Oauth where caller does not have permission mock response from destination', + successCriteria: + 'Since the error from the destination is 403 - the proxy should return 403 with error', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + JSON: { + query: `SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = 'Product Added'`, + }, + headers, + params: { + event: 'Product Added', + customerId: '1234567910', + destination: 'google_adwords_enhanced_conversions', + }, + endpoint: + 'https://googleads.googleapis.com/v15/customers/1234567910/googleAds:searchStream', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 403, + body: { + output: { + authErrorCategory: 'AUTH_STATUS_INACTIVE', + message: + '""The caller does not have permission" during Google_adwords_enhanced_conversions response transformation"', + response: [ + { + error: + '""The caller does not have permission" during Google_adwords_enhanced_conversions response transformation"', + metadata: generateMetadata(1), + statusCode: 403, + }, + ], + statTags: expectedStatTags, + status: 403, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/google_adwords_enhanced_conversions/network.ts b/test/integrations/destinations/google_adwords_enhanced_conversions/network.ts index 672cd73bf7b..69b3a6103a1 100644 --- a/test/integrations/destinations/google_adwords_enhanced_conversions/network.ts +++ b/test/integrations/destinations/google_adwords_enhanced_conversions/network.ts @@ -273,4 +273,146 @@ export const networkCallsData = [ status: 400, }, }, + { + httpReq: { + url: 'https://googleads.googleapis.com/v15/customers/1234567888/googleAds:searchStream', + data: { + query: `SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = 'Product Added'`, + }, + params: { destination: 'google_adwords_enhanced_conversion' }, + headers: { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + 'login-customer-id': '0987654321', + }, + method: 'POST', + }, + httpRes: { + data: [ + { + results: [ + { + conversionAction: { + id: 123434345, + }, + }, + ], + }, + ], + status: 200, + }, + }, + { + httpReq: { + url: 'https://googleads.googleapis.com/v15/customers/1234567888:uploadConversionAdjustments', + data: { + conversionAdjustments: [ + { + adjustmentDateTime: '2022-01-01 12:32:45-08:00', + adjustmentType: 'ENHANCEMENT', + conversionAction: 'customers/1234567888/conversionActions/123434345', + gclidDateTimePair: { + conversionDateTime: '2022-01-01 12:32:45-08:00', + gclid: 'gclid1234', + }, + order_id: '10000', + restatementValue: { adjustedValue: 10, currency: 'INR' }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + userIdentifiers: [ + { + addressInfo: { + hashedFirstName: + 'a8cfcd74832004951b4408cdb0a5dbcd8c7e52d43f7fe244bf720582e05241da', + hashedLastName: + '1c574b17eefa532b6d61c963550a82d2d3dfca4a7fb69e183374cfafd5328ee4', + state: 'UK', + city: 'London', + hashedStreetAddress: + '9a4d2e50828448f137f119a3ebdbbbab8d6731234a67595fdbfeb2a2315dd550', + }, + }, + ], + }, + ], + partialFailure: true, + }, + params: { destination: 'google_adwords_enhanced_conversion' }, + headers: { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + 'login-customer-id': '0987654321', + }, + method: 'POST', + }, + httpRes: { + status: 200, + data: { + partialFailureError: { + code: 3, + message: + 'Conversion already has enhancements with the same Order ID and conversion action. Make sure your data is correctly configured and try again., at conversion_adjustments[0]', + details: [ + { + '@type': 'type.googleapis.com/google.ads.googleads.v15.errors.GoogleAdsFailure', + errors: [ + { + errorCode: { + conversionAdjustmentUploadError: 'CONVERSION_ALREADY_ENHANCED', + }, + message: + 'Conversion already has enhancements with the same Order ID and conversion action. Make sure your data is correctly configured and try again.', + location: { + fieldPathElements: [ + { + fieldName: 'conversion_adjustments', + index: 0, + }, + ], + }, + }, + ], + }, + ], + }, + }, + }, + }, + { + httpReq: { + url: 'https://googleads.googleapis.com/v15/customers/1234567910/googleAds:searchStream', + data: { + query: `SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = 'Product Added'`, + }, + params: { destination: 'google_adwords_enhanced_conversion' }, + headers: { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + 'login-customer-id': '0987654321', + }, + method: 'POST', + }, + httpRes: { + data: [ + { + error: { + code: 403, + message: 'The caller does not have permission', + errors: [ + { + message: 'The caller does not have permission', + domain: 'global', + reason: 'forbidden', + }, + ], + status: 'PERMISSION_DENIED', + }, + }, + ], + status: 403, + }, + }, ]; diff --git a/test/integrations/destinations/google_adwords_enhanced_conversions/router/data.ts b/test/integrations/destinations/google_adwords_enhanced_conversions/router/data.ts index 62ee03c46d3..dff0f772d31 100644 --- a/test/integrations/destinations/google_adwords_enhanced_conversions/router/data.ts +++ b/test/integrations/destinations/google_adwords_enhanced_conversions/router/data.ts @@ -1,248 +1,347 @@ -export const data = [ +const events = [ + { + metadata: { + secret: { + access_token: 'abcd1234', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 1, + userId: 'u1', + }, + destination: { + Config: { + rudderAccountId: '25u5whFH7gVTnCiAjn4ykoCLGoC', + customerId: '1234567890', + subAccount: true, + loginCustomerId: '11', + listOfConversions: [{ conversions: 'Page View' }, { conversions: 'Product Added' }], + authStatus: 'active', + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + phone: '912382193', + firstName: 'John', + lastName: 'Gomes', + city: 'London', + state: 'UK', + streetAddress: '71 Cherry Court SOUTHAMPTON SO53 5PD UK', + }, + library: { name: 'RudderLabs JavaScript SDK', version: '1.0.0' }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { name: '', version: '' }, + screen: { density: 2 }, + }, + event: 'Page View', + type: 'track', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + gclid: 'gclid1234', + conversionDateTime: '2022-01-01 12:32:45-08:00', + adjustedValue: '10', + currency: 'INR', + adjustmentDateTime: '2022-01-01 12:32:45-08:00', + partialFailure: true, + campaignId: '1', + templateId: '0', + order_id: 10000, + total: 1000, + products: [ + { + product_id: '507f1f77bcf86cd799439011', + sku: '45790-32', + name: 'Monopoly: 3rd Edition', + price: '19', + position: '1', + category: 'cars', + url: 'https://www.example.com/product/path', + image_url: 'https://www.example.com/product/path.jpg', + quantity: '2', + }, + { + product_id: '507f1f77bcf86cd7994390112', + sku: '45790-322', + name: 'Monopoly: 3rd Edition2', + price: '192', + quantity: 22, + position: '12', + category: 'Cars2', + url: 'https://www.example.com/product/path2', + image_url: 'https://www.example.com/product/path.jpg2', + }, + ], + }, + integrations: { All: true }, + name: 'ApplicationLoaded', + sentAt: '2019-10-14T11:15:53.296Z', + }, + }, + { + metadata: { + secret: { + access_token: 'abcd1234', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 2, + userId: 'u1', + }, + destination: { + Config: { + rudderAccountId: '25u5whFH7gVTnCiAjn4ykoCLGoC', + customerId: '1234567890', + subAccount: true, + loginCustomerId: '', + listOfConversions: [{ conversions: 'Page View' }, { conversions: 'Product Added' }], + authStatus: 'active', + }, + }, + message: { + type: 'identify', + traits: { status: 'elizabeth' }, + userId: 'emrichardson820+22822@gmail.com', + channel: 'sources', + context: { + sources: { + job_id: '24c5HJxHomh6YCngEOCgjS5r1KX/Syncher', + task_id: 'vw_rs_mailchimp_mocked_hg_data', + version: 'v1.8.1', + batch_id: 'f252c69d-c40d-450e-bcd2-2cf26cb62762', + job_run_id: 'c8el40l6e87v0c4hkbl0', + task_run_id: 'c8el40l6e87v0c4hkblg', + }, + externalId: [ + { + id: 'emrichardson820+22822@gmail.com', + type: 'MAILCHIMP-92e1f1ad2c', + identifierType: 'email_address', + }, + ], + mappedToDestination: 'true', + }, + recordId: '1', + rudderId: '4d5d0ed0-9db8-41cc-9bb0-a032f6bfa97a', + messageId: 'b3bee036-fc26-4f6d-9867-c17f85708a82', + }, + }, + { + metadata: { secret: {}, jobId: 3, userId: 'u1' }, + destination: { + Config: { + rudderAccountId: '25u5whFH7gVTnCiAjn4ykoCLGoC', + customerId: '1234567890', + subAccount: true, + loginCustomerId: '11', + listOfConversions: [{ conversions: 'Page View' }, { conversions: 'Product Added' }], + authStatus: 'active', + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + phone: '912382193', + firstName: 'John', + lastName: 'Gomes', + city: 'London', + state: 'UK', + streetAddress: '71 Cherry Court SOUTHAMPTON SO53 5PD UK', + }, + library: { name: 'RudderLabs JavaScript SDK', version: '1.0.0' }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { name: '', version: '' }, + screen: { density: 2 }, + }, + event: 'Page View', + type: 'track', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + originalTimestamp: '2019-10-14T11:15:18.299Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + gclid: 'gclid1234', + conversionDateTime: '2022-01-01 12:32:45-08:00', + adjustedValue: '10', + currency: 'INR', + adjustmentDateTime: '2022-01-01 12:32:45-08:00', + partialFailure: true, + campaignId: '1', + templateId: '0', + order_id: 10000, + total: 1000, + products: [ + { + product_id: '507f1f77bcf86cd799439011', + sku: '45790-32', + name: 'Monopoly: 3rd Edition', + price: '19', + position: '1', + category: 'cars', + url: 'https://www.example.com/product/path', + image_url: 'https://www.example.com/product/path.jpg', + quantity: '2', + }, + { + product_id: '507f1f77bcf86cd7994390112', + sku: '45790-322', + name: 'Monopoly: 3rd Edition2', + price: '192', + quantity: 22, + position: '12', + category: 'Cars2', + url: 'https://www.example.com/product/path2', + image_url: 'https://www.example.com/product/path.jpg2', + }, + ], + }, + integrations: { All: true }, + name: 'ApplicationLoaded', + sentAt: '2019-10-14T11:15:53.296Z', + }, + }, +]; + +const invalidRtTfCases = [ { name: 'google_adwords_enhanced_conversions', - description: 'Test 0', + description: 'Test 1 - should abort events, invalid router transform structure', feature: 'router', module: 'destination', version: 'v0', input: { request: { body: { - input: [ + input: events[0], + destType: 'google_adwords_enhanced_conversions', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ { - metadata: { - secret: { - access_token: 'abcd1234', - refresh_token: 'efgh5678', - developer_token: 'ijkl91011', - }, - jobId: 1, - userId: 'u1', - }, - destination: { - Config: { - rudderAccountId: '25u5whFH7gVTnCiAjn4ykoCLGoC', - customerId: '1234567890', - subAccount: true, - loginCustomerId: '11', - listOfConversions: [ - { conversions: 'Page View' }, - { conversions: 'Product Added' }, - ], - authStatus: 'active', - }, - }, - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - phone: '912382193', - firstName: 'John', - lastName: 'Gomes', - city: 'London', - state: 'UK', - streetAddress: '71 Cherry Court SOUTHAMPTON SO53 5PD UK', - }, - library: { name: 'RudderLabs JavaScript SDK', version: '1.0.0' }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - ip: '0.0.0.0', - os: { name: '', version: '' }, - screen: { density: 2 }, - }, - event: 'Page View', - type: 'track', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - gclid: 'gclid1234', - conversionDateTime: '2022-01-01 12:32:45-08:00', - adjustedValue: '10', - currency: 'INR', - adjustmentDateTime: '2022-01-01 12:32:45-08:00', - partialFailure: true, - campaignId: '1', - templateId: '0', - order_id: 10000, - total: 1000, - products: [ - { - product_id: '507f1f77bcf86cd799439011', - sku: '45790-32', - name: 'Monopoly: 3rd Edition', - price: '19', - position: '1', - category: 'cars', - url: 'https://www.example.com/product/path', - image_url: 'https://www.example.com/product/path.jpg', - quantity: '2', - }, - { - product_id: '507f1f77bcf86cd7994390112', - sku: '45790-322', - name: 'Monopoly: 3rd Edition2', - price: '192', - quantity: 22, - position: '12', - category: 'Cars2', - url: 'https://www.example.com/product/path2', - image_url: 'https://www.example.com/product/path.jpg2', - }, - ], + error: 'Invalid event array', + metadata: [ + { + destType: 'google_adwords_enhanced_conversions', }, - integrations: { All: true }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, + ], + batched: false, + statusCode: 400, }, + ], + }, + }, + }, + }, + { + name: 'google_adwords_enhanced_conversions', + description: + 'Test 2 - should abort events, invalid router transform structure without destType in payload & empty object as input', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: {}, + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ { - metadata: { - secret: { - access_token: 'abcd1234', - refresh_token: 'efgh5678', - developer_token: 'ijkl91011', - }, - jobId: 2, - userId: 'u1', - }, - destination: { - Config: { - rudderAccountId: '25u5whFH7gVTnCiAjn4ykoCLGoC', - customerId: '1234567890', - subAccount: true, - loginCustomerId: '', - listOfConversions: [ - { conversions: 'Page View' }, - { conversions: 'Product Added' }, - ], - authStatus: 'active', - }, - }, - message: { - type: 'identify', - traits: { status: 'elizabeth' }, - userId: 'emrichardson820+22822@gmail.com', - channel: 'sources', - context: { - sources: { - job_id: '24c5HJxHomh6YCngEOCgjS5r1KX/Syncher', - task_id: 'vw_rs_mailchimp_mocked_hg_data', - version: 'v1.8.1', - batch_id: 'f252c69d-c40d-450e-bcd2-2cf26cb62762', - job_run_id: 'c8el40l6e87v0c4hkbl0', - task_run_id: 'c8el40l6e87v0c4hkblg', - }, - externalId: [ - { - id: 'emrichardson820+22822@gmail.com', - type: 'MAILCHIMP-92e1f1ad2c', - identifierType: 'email_address', - }, - ], - mappedToDestination: 'true', + error: 'Invalid event array', + metadata: [ + { + destType: undefined, }, - recordId: '1', - rudderId: '4d5d0ed0-9db8-41cc-9bb0-a032f6bfa97a', - messageId: 'b3bee036-fc26-4f6d-9867-c17f85708a82', - }, + ], + batched: false, + statusCode: 400, }, + ], + }, + }, + }, + }, + { + name: 'google_adwords_enhanced_conversions', + description: + 'Test 3 - should abort events, invalid router transform structure without input & destType', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: {}, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ { - metadata: { secret: {}, jobId: 3, userId: 'u1' }, - destination: { - Config: { - rudderAccountId: '25u5whFH7gVTnCiAjn4ykoCLGoC', - customerId: '1234567890', - subAccount: true, - loginCustomerId: '11', - listOfConversions: [ - { conversions: 'Page View' }, - { conversions: 'Product Added' }, - ], - authStatus: 'active', - }, - }, - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - phone: '912382193', - firstName: 'John', - lastName: 'Gomes', - city: 'London', - state: 'UK', - streetAddress: '71 Cherry Court SOUTHAMPTON SO53 5PD UK', - }, - library: { name: 'RudderLabs JavaScript SDK', version: '1.0.0' }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - locale: 'en-US', - ip: '0.0.0.0', - os: { name: '', version: '' }, - screen: { density: 2 }, - }, - event: 'Page View', - type: 'track', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - gclid: 'gclid1234', - conversionDateTime: '2022-01-01 12:32:45-08:00', - adjustedValue: '10', - currency: 'INR', - adjustmentDateTime: '2022-01-01 12:32:45-08:00', - partialFailure: true, - campaignId: '1', - templateId: '0', - order_id: 10000, - total: 1000, - products: [ - { - product_id: '507f1f77bcf86cd799439011', - sku: '45790-32', - name: 'Monopoly: 3rd Edition', - price: '19', - position: '1', - category: 'cars', - url: 'https://www.example.com/product/path', - image_url: 'https://www.example.com/product/path.jpg', - quantity: '2', - }, - { - product_id: '507f1f77bcf86cd7994390112', - sku: '45790-322', - name: 'Monopoly: 3rd Edition2', - price: '192', - quantity: 22, - position: '12', - category: 'Cars2', - url: 'https://www.example.com/product/path2', - image_url: 'https://www.example.com/product/path.jpg2', - }, - ], + error: 'Invalid event array', + metadata: [ + { + destType: undefined, }, - integrations: { All: true }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, + ], + batched: false, + statusCode: 400, }, ], + }, + }, + }, + }, +]; + +export const data = [ + { + name: 'google_adwords_enhanced_conversions', + description: 'Test 0', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: events, destType: 'google_adwords_enhanced_conversions', }, method: 'POST', @@ -405,4 +504,5 @@ export const data = [ }, }, }, + ...invalidRtTfCases, ]; diff --git a/test/integrations/destinations/google_adwords_offline_conversions/dataDelivery/business.ts b/test/integrations/destinations/google_adwords_offline_conversions/dataDelivery/business.ts new file mode 100644 index 00000000000..87aafea0afa --- /dev/null +++ b/test/integrations/destinations/google_adwords_offline_conversions/dataDelivery/business.ts @@ -0,0 +1,669 @@ +import { + generateMetadata, + generateProxyV0Payload, + generateProxyV1Payload, +} from '../../../testUtils'; + +const transactionAttribute = { + CUSTOM_KEY: 'CUSTOM_VALUE', + currency_code: 'INR', + order_id: 'order id', + store_attribute: { + store_code: 'store code', + }, + transaction_amount_micros: '100000000', + transaction_date_time: '2019-10-14 11:15:18+00:00', +}; + +const createJobPayload = { + job: { + storeSalesMetadata: { + custom_key: 'CUSTOM_KEY', + loyaltyFraction: 1, + transaction_upload_fraction: '1', + }, + type: 'STORE_SALES_UPLOAD_FIRST_PARTY', + }, +}; + +const products = [ + { + product_id: '507f1f77bcf86cd799439011', + quantity: '2', + price: '50', + sku: '45790-32', + name: 'Monopoly: 3rd Edition', + position: '1', + category: 'cars', + url: 'https://www.example.com/product/path', + image_url: 'https://www.example.com/product/path.jpg', + }, +]; + +const headers = { + header1: { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + 'login-customer-id': 'logincustomerid', + }, + header2: { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + }, +}; + +const params = { + param1: { + customerId: '1112223333', + event: 'Sign-up - click', + }, + param2: { + event: 'Sign-up - click', + customerId: '1234567891', + customVariables: [ + { + from: 'Value', + to: 'revenue', + }, + { + from: 'total', + to: 'cost', + }, + ], + properties: { + gbraid: 'gbraid', + wbraid: 'wbraid', + externalAttributionCredit: 10, + externalAttributionModel: 'externalAttributionModel', + conversionCustomVariable: 'conversionCustomVariable', + Value: 'value', + merchantId: '9876merchantId', + feedCountryCode: 'feedCountryCode', + feedLanguageCode: 'feedLanguageCode', + localTransactionCost: 20, + products, + userIdentifierSource: 'FIRST_PARTY', + conversionEnvironment: 'WEB', + gclid: 'gclid', + conversionDateTime: '2022-01-01 12:32:45-08:00', + conversionValue: '1', + currency: 'GBP', + orderId: 'PL-123QR', + }, + }, + param3: {}, + param4: {}, +}; + +params['param3'] = { ...params.param2, customVariables: [] }; + +params['param4'] = { ...params.param3, customerId: '1234567893', conversionEnvironment: 'APP' }; + +const validRequestPayload1 = { + addConversionPayload: { + enable_partial_failure: false, + enable_warnings: false, + operations: [ + { + create: { + transaction_attribute: transactionAttribute, + userIdentifiers: [ + { + hashedEmail: '6db61e6dcbcf2390e4a46af426f26a133a3bee45021422fc7ae86e9136f14110', + userIdentifierSource: 'UNSPECIFIED', + }, + ], + }, + }, + ], + validate_only: false, + }, + createJobPayload, + event: '1112223333', + executeJobPayload: { + validate_only: false, + }, + isStoreConversion: true, +}; + +const validRequestPayload2 = { + conversions: [ + { + gbraid: 'gbraid', + wbraid: 'wbraid', + externalAttributionData: { + externalAttributionCredit: 10, + externalAttributionModel: 'externalAttributionModel', + }, + cartData: { + merchantId: 9876, + feedCountryCode: 'feedCountryCode', + feedLanguageCode: 'feedLanguageCode', + localTransactionCost: 20, + items: [ + { + productId: '507f1f77bcf86cd799439011', + quantity: 2, + unitPrice: 50, + }, + ], + }, + userIdentifiers: [ + { + userIdentifierSource: 'FIRST_PARTY', + hashedPhoneNumber: '04e1dabb7c1348b72bfa87da179c9697c69af74827649266a5da8cdbb367abcd', + }, + ], + conversionEnvironment: 'WEB', + gclid: 'gclid', + conversionDateTime: '2022-01-01 12:32:45-08:00', + conversionValue: 1, + currencyCode: 'GBP', + orderId: 'PL-123QR', + }, + ], + partialFailure: true, +}; + +const invalidArgumentRequestPayload = { + addConversionPayload: { + enable_partial_failure: false, + enable_warnings: false, + operations: [ + { + create: { + transaction_attribute: transactionAttribute, + userIdentifiers: [ + { + hashedEmail: '6db61e6dcbcf2390e4a46af26f26a133a3bee45021422fc7ae86e9136f14110', + userIdentifierSource: 'UNSPECIFIED', + }, + ], + }, + }, + ], + validate_only: false, + }, + createJobPayload, + event: '1112223333', + executeJobPayload: { + validate_only: false, + }, + isStoreConversion: true, +}; + +const notAllowedToAccessFeatureRequestPayload = { + ...validRequestPayload2, + conversions: [ + { + ...validRequestPayload2.conversions[0], + conversionEnvironment: 'APP', + }, + ], +}; + +const metadataArray = [generateMetadata(1)]; + +const expectedStatTags = { + destType: 'GOOGLE_ADWORDS_OFFLINE_CONVERSIONS', + destinationId: 'default-destinationId', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'default-workspaceId', +}; + +export const testScenariosForV0API = [ + { + id: 'gaoc_v0_scenario_1', + name: 'google_adwords_offline_conversions', + description: + '[Proxy v0 API] :: Test for invalid argument - where the destination responds with 400 with invalid argument error', + successCriteria: 'Should return 400 with error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + headers: headers.header1, + params: params.param1, + JSON: invalidArgumentRequestPayload, + endpoint: + 'https://googleads.googleapis.com/v16/customers/11122233331/offlineUserDataJobs', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 400, + body: { + output: { + status: 400, + message: + '[Google Ads Offline Conversions]:: Request contains an invalid argument. during google_ads_offline_store_conversions Add Conversion', + destinationResponse: { + error: { + code: 400, + details: [ + { + '@type': 'type.googleapis.com/google.ads.googleads.v16.errors.GoogleAdsFailure', + errors: [ + { + errorCode: { + offlineUserDataJobError: 'INVALID_SHA256_FORMAT', + }, + message: 'The SHA256 encoded value is malformed.', + location: { + fieldPathElements: [ + { + fieldName: 'operations', + index: 0, + }, + { + fieldName: 'create', + }, + { + fieldName: 'user_identifiers', + index: 0, + }, + { + fieldName: 'hashed_email', + }, + ], + }, + }, + ], + requestId: '68697987', + }, + ], + message: 'Request contains an invalid argument.', + status: 'INVALID_ARGUMENT', + }, + }, + statTags: expectedStatTags, + }, + }, + }, + }, + }, + { + id: 'gaoc_v0_scenario_2', + name: 'google_adwords_offline_conversions', + description: + '[Proxy v0 API] :: Test for a valid operations request with a successful 200 response from the destination', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + headers: headers.header1, + params: params.param1, + JSON: validRequestPayload1, + endpoint: 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: + '[Google Ads Offline Conversions Response Handler] - Request processed successfully', + destinationResponse: { + response: { + name: 'customers/111-222-3333/operations/abcd=', + }, + status: 200, + }, + }, + }, + }, + }, + }, + { + id: 'gaoc_v0_scenario_3', + name: 'google_adwords_offline_conversions', + description: + '[Proxy v0 API] :: Test for a valid request with a successful 200 response from the destination', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + headers: headers.header2, + params: params.param2, + JSON: validRequestPayload2, + endpoint: + 'https://googleads.googleapis.com/v16/customers/1234567891:uploadClickConversions', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: + '[Google Ads Offline Conversions Response Handler] - Request processed successfully', + destinationResponse: { + response: [ + { + adjustmentType: 'ENHANCEMENT', + conversionAction: 'customers/1234567891/conversionActions/874224905', + adjustmentDateTime: '2021-01-01 12:32:45-08:00', + gclidDateTimePair: { + gclid: '1234', + conversionDateTime: '2021-01-01 12:32:45-08:00', + }, + orderId: '12345', + }, + ], + status: 200, + }, + }, + }, + }, + }, + }, + { + id: 'gaoc_v0_scenario_4', + name: 'google_adwords_offline_conversions', + description: + '[Proxy v0 API] :: Test for a valid conversion action request with a successful 200 response from the destination', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + headers: headers.header2, + params: params.param3, + JSON: validRequestPayload2, + endpoint: + 'https://googleads.googleapis.com/v16/customers/1234567891:uploadClickConversions', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + destinationResponse: { + response: [ + { + adjustmentDateTime: '2021-01-01 12:32:45-08:00', + adjustmentType: 'ENHANCEMENT', + conversionAction: 'customers/1234567891/conversionActions/874224905', + gclidDateTimePair: { + conversionDateTime: '2021-01-01 12:32:45-08:00', + gclid: '1234', + }, + orderId: '12345', + }, + ], + status: 200, + }, + message: + '[Google Ads Offline Conversions Response Handler] - Request processed successfully', + status: 200, + }, + }, + }, + }, + }, +]; + +export const testScenariosForV1API = [ + { + id: 'gaoc_v1_scenario_1', + name: 'google_adwords_offline_conversions', + description: + '[Proxy v1 API] :: Test for invalid argument - where the destination responds with 400 with invalid argument error', + successCriteria: 'Should return 400 with error with destination response', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: headers.header1, + params: params.param1, + JSON: invalidArgumentRequestPayload, + endpoint: + 'https://googleads.googleapis.com/v16/customers/11122233331/offlineUserDataJobs', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: + '[Google Ads Offline Conversions]:: Request contains an invalid argument. during google_ads_offline_store_conversions Add Conversion', + response: [ + { + error: + '[Google Ads Offline Conversions]:: Request contains an invalid argument. during google_ads_offline_store_conversions Add Conversion', + metadata: generateMetadata(1), + statusCode: 400, + }, + ], + statTags: expectedStatTags, + status: 400, + }, + }, + }, + }, + }, + { + id: 'gaoc_v1_scenario_2', + name: 'google_adwords_offline_conversions', + description: + '[Proxy v1 API] :: Test for a valid operations request with a successful 200 response from the destination', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: headers.header1, + params: params.param1, + JSON: validRequestPayload1, + endpoint: + 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: + '[Google Ads Offline Conversions Response Handler] - Request processed successfully', + response: [ + { + error: '{"name":"customers/111-222-3333/operations/abcd="}', + metadata: generateMetadata(1), + statusCode: 200, + }, + ], + status: 200, + }, + }, + }, + }, + }, + { + id: 'gaoc_v1_scenario_3', + name: 'google_adwords_offline_conversions', + description: + '[Proxy v1 API] :: Test for a valid request with a successful 200 response from the destination', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: headers.header2, + params: params.param2, + JSON: validRequestPayload2, + endpoint: + 'https://googleads.googleapis.com/v16/customers/1234567891:uploadClickConversions', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: + '[Google Ads Offline Conversions Response Handler] - Request processed successfully', + response: [ + { + error: + '[{"adjustmentType":"ENHANCEMENT","conversionAction":"customers/1234567891/conversionActions/874224905","adjustmentDateTime":"2021-01-01 12:32:45-08:00","gclidDateTimePair":{"gclid":"1234","conversionDateTime":"2021-01-01 12:32:45-08:00"},"orderId":"12345"}]', + metadata: generateMetadata(1), + statusCode: 200, + }, + ], + status: 200, + }, + }, + }, + }, + }, + { + id: 'gaoc_v1_scenario_4', + name: 'google_adwords_offline_conversions', + description: + '[Proxy v1 API] :: Test for a valid conversion action request with a successful 200 response from the destination', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: headers.header2, + params: params.param3, + JSON: validRequestPayload2, + endpoint: + 'https://googleads.googleapis.com/v16/customers/1234567891:uploadClickConversions', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: + '[Google Ads Offline Conversions Response Handler] - Request processed successfully', + response: [ + { + error: + '[{"adjustmentType":"ENHANCEMENT","conversionAction":"customers/1234567891/conversionActions/874224905","adjustmentDateTime":"2021-01-01 12:32:45-08:00","gclidDateTimePair":{"gclid":"1234","conversionDateTime":"2021-01-01 12:32:45-08:00"},"orderId":"12345"}]', + metadata: generateMetadata(1), + statusCode: 200, + }, + ], + status: 200, + }, + }, + }, + }, + }, + { + id: 'gaoc_v1_scenario_5', + name: 'google_adwords_offline_conversions', + description: + '[Proxy v1 API] :: Test for customer is not allowed Test for a valid request with a successful 200 response from the destinationto access feature partial failure error', + successCriteria: 'Should return 400 with error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: headers.header2, + params: params.param4, + JSON: notAllowedToAccessFeatureRequestPayload, + endpoint: + 'https://googleads.googleapis.com/v16/customers/1234567893:uploadClickConversions', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: + '[Google Ads Offline Conversions]:: partialFailureError - Customer is not allowlisted for accessing this feature., at conversions[0].conversion_environment', + response: [ + { + error: + '[Google Ads Offline Conversions]:: partialFailureError - Customer is not allowlisted for accessing this feature., at conversions[0].conversion_environment', + metadata: generateMetadata(1), + statusCode: 400, + }, + ], + statTags: expectedStatTags, + status: 400, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/google_adwords_offline_conversions/dataDelivery/data.ts b/test/integrations/destinations/google_adwords_offline_conversions/dataDelivery/data.ts index 36cd0ad8017..709ab6d2a8a 100644 --- a/test/integrations/destinations/google_adwords_offline_conversions/dataDelivery/data.ts +++ b/test/integrations/destinations/google_adwords_offline_conversions/dataDelivery/data.ts @@ -1,750 +1,9 @@ +import { v0oauthScenarios, v1oauthScenarios } from './oauth'; +import { testScenariosForV0API, testScenariosForV1API } from './business'; + export const data = [ - { - name: 'google_adwords_offline_conversions', - description: 'Test 0', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://googleads.googleapis.com/v14/customers/11122233331/offlineUserDataJobs", - "headers": { - "Authorization": "Bearer abcd1234", - "Content-Type": "application/json", - "developer-token": "ijkl91011", - "login-customer-id": "logincustomerid" - }, - "params": { - "customerId": "1112223333", - "event": "Sign-up - click" - }, - "body": { - "JSON": { - "addConversionPayload": { - "enable_partial_failure": false, - "enable_warnings": false, - "operations": [ - { - "create": { - "transaction_attribute": { - "CUSTOM_KEY": "CUSTOM_VALUE", - "currency_code": "INR", - "order_id": "order id", - "store_attribute": { - "store_code": "store code" - }, - "transaction_amount_micros": "100000000", - "transaction_date_time": "2019-10-14 11:15:18+00:00" - }, - "userIdentifiers": [ - { - "hashedEmail": "6db61e6dcbcf2390e4a46af26f26a133a3bee45021422fc7ae86e9136f14110", - "userIdentifierSource": "UNSPECIFIED" - } - ] - } - } - ], - "validate_only": false - }, - "createJobPayload": { - "job": { - "storeSalesMetadata": { - "custom_key": "CUSTOM_KEY", - "loyaltyFraction": 1, - "transaction_upload_fraction": "1" - }, - "type": "STORE_SALES_UPLOAD_FIRST_PARTY" - } - }, - "event": "1112223333", - "executeJobPayload": { - "validate_only": false - }, - "isStoreConversion": true - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - }, - method: 'POST', - }, - }, - output: { - response: { - status: 400, - body: { - "output": { - "status": 400, - "message": "[Google Ads Offline Conversions]:: Request contains an invalid argument. during google_ads_offline_store_conversions Add Conversion", - "destinationResponse": { - "error": { - "code": 400, - "details": [ - { - "@type": "type.googleapis.com/google.ads.googleads.v14.errors.GoogleAdsFailure", - "errors": [ - { - "errorCode": { - "offlineUserDataJobError": "INVALID_SHA256_FORMAT" - }, - "message": "The SHA256 encoded value is malformed.", - "location": { - "fieldPathElements": [ - { - "fieldName": "operations", - "index": 0 - }, - { - "fieldName": "create" - }, - { - "fieldName": "user_identifiers", - "index": 0 - }, - { - "fieldName": "hashed_email" - } - ] - } - } - ], - "requestId": "68697987" - } - ], - "message": "Request contains an invalid argument.", - "status": "INVALID_ARGUMENT" - } - }, - "statTags": { - "destType": "GOOGLE_ADWORDS_OFFLINE_CONVERSIONS", - "destinationId": "Non-determininable", - "errorCategory": "network", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination", - "workspaceId": "Non-determininable", - } - } - }, - }, - }, - }, - { - name: 'google_adwords_offline_conversions', - description: 'Test 1', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - "body": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://googleads.googleapis.com/v14/customers/1112223333/offlineUserDataJobs", - "headers": { - "Authorization": "Bearer abcd1234", - "Content-Type": "application/json", - "developer-token": "ijkl91011", - "login-customer-id": "logincustomerid" - }, - "params": { - "customerId": "1112223333", - "event": "Sign-up - click" - }, - "body": { - "JSON": { - "addConversionPayload": { - "enable_partial_failure": false, - "enable_warnings": false, - "operations": [ - { - "create": { - "transaction_attribute": { - "CUSTOM_KEY": "CUSTOM_VALUE", - "currency_code": "INR", - "order_id": "order id", - "store_attribute": { - "store_code": "store code" - }, - "transaction_amount_micros": "100000000", - "transaction_date_time": "2019-10-14 11:15:18+00:00" - }, - "userIdentifiers": [ - { - "hashedEmail": "6db61e6dcbcf2390e4a46af426f26a133a3bee45021422fc7ae86e9136f14110", - "userIdentifierSource": "UNSPECIFIED" - } - ] - } - } - ], - "validate_only": false - }, - "createJobPayload": { - "job": { - "storeSalesMetadata": { - "custom_key": "CUSTOM_KEY", - "loyaltyFraction": 1, - "transaction_upload_fraction": "1" - }, - "type": "STORE_SALES_UPLOAD_FIRST_PARTY" - } - }, - "event": "1112223333", - "executeJobPayload": { - "validate_only": false - }, - "isStoreConversion": true - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - } - }, - }, - output: { - response: { - status: 200, - body: { - "output": { - "status": 200, - "message": "[Google Ads Offline Conversions Response Handler] - Request processed successfully", - "destinationResponse": { - "response": { - "name": "customers/111-222-3333/operations/abcd=" - }, - "status": 200 - } - } - }, - }, - }, - }, - { - name: 'google_adwords_offline_conversions', - description: 'Test 2', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - "body": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://googleads.googleapis.com/v14/customers/customerid/offlineUserDataJobs", - "headers": { - "Authorization": "Bearer abcd1234", - "Content-Type": "application/json", - "developer-token": "ijkl91011", - "login-customer-id": "logincustomerid" - }, - "params": { - "customerId": "1112223333", - "event": "Sign-up - click" - }, - "body": { - "JSON": { - "addConversionPayload": { - "enable_partial_failure": false, - "enable_warnings": false, - "operations": [ - { - "create": { - "transaction_attribute": { - "CUSTOM_KEY": "CUSTOM_VALUE", - "currency_code": "INR", - "order_id": "order id", - "store_attribute": { - "store_code": "store code" - }, - "transaction_amount_micros": "100000000", - "transaction_date_time": "2019-10-14 11:15:18+00:00" - }, - "userIdentifiers": [ - { - "hashedEmail": "6db61e6dcbcf2390e4a46af426f26a133a3bee45021422fc7ae86e9136f14110", - "userIdentifierSource": "UNSPECIFIED" - } - ] - } - } - ], - "validate_only": false - }, - "createJobPayload": { - "job": { - "storeSalesMetadata": { - "custom_key": "CUSTOM_KEY", - "loyaltyFraction": 1, - "transaction_upload_fraction": "1" - }, - "type": "STORE_SALES_UPLOAD_FIRST_PARTY" - } - }, - "event": "1112223333", - "executeJobPayload": { - "validate_only": false - }, - "isStoreConversion": true - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - } - }, - }, - output: { - response: { - status: 401, - body: { - "output": { - "status": 401, - "message": "[Google Ads Offline Conversions]:: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project. during google_ads_offline_store_conversions Job Creation", - "authErrorCategory": "REFRESH_TOKEN", - "destinationResponse": { - "error": { - "code": 401, - "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", - "status": "UNAUTHENTICATED" - } - }, - "statTags": { - "destType": "GOOGLE_ADWORDS_OFFLINE_CONVERSIONS", - "destinationId": "Non-determininable", - "errorCategory": "network", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination", - "workspaceId": "Non-determininable" - } - } - } - }, - }, - }, - { - name: 'google_adwords_offline_conversions', - description: 'Test 3', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - "body": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://googleads.googleapis.com/v14/customers/1234567890:uploadClickConversions", - "headers": { - "Authorization": "Bearer abcd1234", - "Content-Type": "application/json", - "developer-token": "ijkl91011" - }, - "params": { - "event": "Sign-up - click", - "customerId": "1234567890", - "customVariables": [ - { - "from": "value", - "to": "revenue" - }, - { - "from": "total", - "to": "cost" - } - ], - "properties": { - "gbraid": "gbraid", - "wbraid": "wbraid", - "externalAttributionCredit": 10, - "externalAttributionModel": "externalAttributionModel", - "conversionCustomVariable": "conversionCustomVariable", - "value": "value", - "merchantId": "9876merchantId", - "feedCountryCode": "feedCountryCode", - "feedLanguageCode": "feedLanguageCode", - "localTransactionCost": 20, - "products": [ - { - "product_id": "507f1f77bcf86cd799439011", - "quantity": "2", - "price": "50", - "sku": "45790-32", - "name": "Monopoly: 3rd Edition", - "position": "1", - "category": "cars", - "url": "https://www.example.com/product/path", - "image_url": "https://www.example.com/product/path.jpg" - } - ], - "userIdentifierSource": "FIRST_PARTY", - "conversionEnvironment": "WEB", - "gclid": "gclid", - "conversionDateTime": "2022-01-01 12:32:45-08:00", - "conversionValue": "1", - "currency": "GBP", - "orderId": "PL-123QR" - } - }, - "body": { - "JSON": { - "conversions": [ - { - "gbraid": "gbraid", - "wbraid": "wbraid", - "externalAttributionData": { - "externalAttributionCredit": 10, - "externalAttributionModel": "externalAttributionModel" - }, - "cartData": { - "merchantId": 9876, - "feedCountryCode": "feedCountryCode", - "feedLanguageCode": "feedLanguageCode", - "localTransactionCost": 20, - "items": [ - { - "productId": "507f1f77bcf86cd799439011", - "quantity": 2, - "unitPrice": 50 - } - ] - }, - "userIdentifiers": [ - { - "userIdentifierSource": "FIRST_PARTY", - "hashedEmail": "6db61e6dcbcf2390e4a46af426f26a133a3bee45021422fc7ae86e9136f14110" - } - ], - "conversionEnvironment": "WEB", - "gclid": "gclid", - "conversionDateTime": "2022-01-01 12:32:45-08:00", - "conversionValue": 1, - "currencyCode": "GBP", - "orderId": "PL-123QR" - } - ], - "partialFailure": true - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - } - }, - }, - output: { - response: { - status: 401, - body: { - "output": { - "status": 401, - "message": "[Google Ads Offline Conversions]:: [{\"error\":{\"code\":401,\"message\":\"Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.\",\"status\":\"UNAUTHENTICATED\"}}] during google_ads_offline_conversions response transformation", - "authErrorCategory": "REFRESH_TOKEN", - "destinationResponse": [ - { - "error": { - "code": 401, - "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", - "status": "UNAUTHENTICATED" - } - } - ], - "statTags": { - "destType": "GOOGLE_ADWORDS_OFFLINE_CONVERSIONS", - "destinationId": "Non-determininable", - "errorCategory": "network", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination", - "workspaceId": "Non-determininable", - } - } - } - }, - }, - }, - { - name: 'google_adwords_offline_conversions', - description: 'Test 4', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://googleads.googleapis.com/v14/customers/1234567891:uploadClickConversions", - "headers": { - "Authorization": "Bearer abcd1234", - "Content-Type": "application/json", - "developer-token": "ijkl91011" - }, - "params": { - "event": "Sign-up - click", - "customerId": "1234567891", - "customVariables": [ - { - "from": "Value", - "to": "revenue" - }, - { - "from": "total", - "to": "cost" - } - ], - "properties": { - "gbraid": "gbraid", - "wbraid": "wbraid", - "externalAttributionCredit": 10, - "externalAttributionModel": "externalAttributionModel", - "conversionCustomVariable": "conversionCustomVariable", - "Value": "value", - "merchantId": "9876merchantId", - "feedCountryCode": "feedCountryCode", - "feedLanguageCode": "feedLanguageCode", - "localTransactionCost": 20, - "products": [ - { - "product_id": "507f1f77bcf86cd799439011", - "quantity": "2", - "price": "50", - "sku": "45790-32", - "name": "Monopoly: 3rd Edition", - "position": "1", - "category": "cars", - "url": "https://www.example.com/product/path", - "image_url": "https://www.example.com/product/path.jpg" - } - ], - "userIdentifierSource": "FIRST_PARTY", - "conversionEnvironment": "WEB", - "gclid": "gclid", - "conversionDateTime": "2022-01-01 12:32:45-08:00", - "conversionValue": "1", - "currency": "GBP", - "orderId": "PL-123QR" - } - }, - "body": { - "JSON": { - "conversions": [ - { - "gbraid": "gbraid", - "wbraid": "wbraid", - "externalAttributionData": { - "externalAttributionCredit": 10, - "externalAttributionModel": "externalAttributionModel" - }, - "cartData": { - "merchantId": 9876, - "feedCountryCode": "feedCountryCode", - "feedLanguageCode": "feedLanguageCode", - "localTransactionCost": 20, - "items": [ - { - "productId": "507f1f77bcf86cd799439011", - "quantity": 2, - "unitPrice": 50 - } - ] - }, - "userIdentifiers": [ - { - "userIdentifierSource": "FIRST_PARTY", - "hashedPhoneNumber": "04e1dabb7c1348b72bfa87da179c9697c69af74827649266a5da8cdbb367abcd" - } - ], - "conversionEnvironment": "WEB", - "gclid": "gclid", - "conversionDateTime": "2022-01-01 12:32:45-08:00", - "conversionValue": 1, - "currencyCode": "GBP", - "orderId": "PL-123QR" - } - ], - "partialFailure": true - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - } - } - }, - output: { - response: { - status: 200, - body: { - "output": { - "status": 200, - "message": "[Google Ads Offline Conversions Response Handler] - Request processed successfully", - "destinationResponse": { - "response": [ - { - "adjustmentType": "ENHANCEMENT", - "conversionAction": "customers/1234567891/conversionActions/874224905", - "adjustmentDateTime": "2021-01-01 12:32:45-08:00", - "gclidDateTimePair": { - "gclid": "1234", - "conversionDateTime": "2021-01-01 12:32:45-08:00" - }, - "orderId": "12345" - } - ], - "status": 200 - } - } - } - }, - }, - }, - { - name: 'google_adwords_offline_conversions', - description: 'Test 5', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://googleads.googleapis.com/v14/customers/1234567891:uploadClickConversions", - "headers": { - "Authorization": "Bearer abcd1234", - "Content-Type": "application/json", - "developer-token": "ijkl91011" - }, - "params": { - "event": "Sign-up - click", - "customerId": "1234567891", - "customVariables": [], - "properties": { - "gbraid": "gbraid", - "wbraid": "wbraid", - "externalAttributionCredit": 10, - "externalAttributionModel": "externalAttributionModel", - "conversionCustomVariable": "conversionCustomVariable", - "value": "value", - "merchantId": "9876merchantId", - "feedCountryCode": "feedCountryCode", - "feedLanguageCode": "feedLanguageCode", - "localTransactionCost": 20, - "products": [ - { - "product_id": "507f1f77bcf86cd799439011", - "quantity": "2", - "price": "50", - "sku": "45790-32", - "name": "Monopoly: 3rd Edition", - "position": "1", - "category": "cars", - "url": "https://www.example.com/product/path", - "image_url": "https://www.example.com/product/path.jpg" - } - ], - "userIdentifierSource": "FIRST_PARTY", - "conversionEnvironment": "WEB", - "gclid": "gclid", - "conversionDateTime": "2022-01-01 12:32:45-08:00", - "conversionValue": "1", - "currency": "GBP", - "orderId": "PL-123QR" - } - }, - "body": { - "JSON": { - "conversions": [ - { - "gbraid": "gbraid", - "wbraid": "wbraid", - "externalAttributionData": { - "externalAttributionCredit": 10, - "externalAttributionModel": "externalAttributionModel" - }, - "cartData": { - "merchantId": 9876, - "feedCountryCode": "feedCountryCode", - "feedLanguageCode": "feedLanguageCode", - "localTransactionCost": 20, - "items": [ - { - "productId": "507f1f77bcf86cd799439011", - "quantity": 2, - "unitPrice": 50 - } - ] - }, - "userIdentifiers": [ - { - "userIdentifierSource": "FIRST_PARTY", - "hashedPhoneNumber": "04e1dabb7c1348b72bfa87da179c9697c69af74827649266a5da8cdbb367abcd" - } - ], - "conversionEnvironment": "WEB", - "gclid": "gclid", - "conversionDateTime": "2022-01-01 12:32:45-08:00", - "conversionValue": 1, - "currencyCode": "GBP", - "orderId": "PL-123QR" - } - ], - "partialFailure": true - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - } - } - }, - output: { - response: { - status: 200, - body: { - "output": { - "destinationResponse": { - "response": [ - { - "adjustmentDateTime": "2021-01-01 12:32:45-08:00", - "adjustmentType": "ENHANCEMENT", - "conversionAction": "customers/1234567891/conversionActions/874224905", - "gclidDateTimePair": { - "conversionDateTime": "2021-01-01 12:32:45-08:00", - "gclid": "1234" - }, - "orderId": "12345" - } - ], - "status": 200 - }, - "message": "[Google Ads Offline Conversions Response Handler] - Request processed successfully", - "status": 200 - } - } - }, - }, - } + ...v0oauthScenarios, + ...v1oauthScenarios, + ...testScenariosForV0API, + ...testScenariosForV1API, ]; diff --git a/test/integrations/destinations/google_adwords_offline_conversions/dataDelivery/oauth.ts b/test/integrations/destinations/google_adwords_offline_conversions/dataDelivery/oauth.ts new file mode 100644 index 00000000000..e14e4109f09 --- /dev/null +++ b/test/integrations/destinations/google_adwords_offline_conversions/dataDelivery/oauth.ts @@ -0,0 +1,263 @@ +import { + generateMetadata, + generateProxyV1Payload, + generateProxyV0Payload, +} from '../../../testUtils'; + +const commonHeaders = { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + 'login-customer-id': 'logincustomerid', +}; + +const commonParams = { + customerId: '1112223333', + event: 'Sign-up - click', +}; + +const commonRequestPayload = { + addConversionPayload: { + enable_partial_failure: false, + enable_warnings: false, + operations: [ + { + create: { + transaction_attribute: { + CUSTOM_KEY: 'CUSTOM_VALUE', + currency_code: 'INR', + order_id: 'order id', + store_attribute: { + store_code: 'store code', + }, + transaction_amount_micros: '100000000', + transaction_date_time: '2019-10-14 11:15:18+00:00', + }, + userIdentifiers: [ + { + hashedEmail: '6db61e6dcbcf2390e4a46af426f26a133a3bee45021422fc7ae86e9136f14110', + userIdentifierSource: 'UNSPECIFIED', + }, + ], + }, + }, + ], + validate_only: false, + }, + createJobPayload: { + job: { + storeSalesMetadata: { + custom_key: 'CUSTOM_KEY', + loyaltyFraction: 1, + transaction_upload_fraction: '1', + }, + type: 'STORE_SALES_UPLOAD_FIRST_PARTY', + }, + }, + event: '1112223333', + executeJobPayload: { + validate_only: false, + }, + isStoreConversion: true, +}; + +const commonRequestParameters = { + headers: commonHeaders, + params: commonParams, + JSON: commonRequestPayload, +}; + +const metadataArray = [generateMetadata(1)]; + +const expectedStatTags = { + destType: 'GOOGLE_ADWORDS_OFFLINE_CONVERSIONS', + destinationId: 'default-destinationId', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'default-workspaceId', +}; + +export const v0oauthScenarios = [ + { + id: 'gaoc_v0_oauth_scenario_1', + name: 'google_adwords_offline_conversions', + description: + '[Proxy v0 API] :: Oauth where valid credentials are missing as mock response from destination', + successCriteria: 'The proxy should return 401 with authErrorCategory as REFRESH_TOKEN', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://googleads.googleapis.com/v16/customers/customerid/offlineUserDataJobs', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 401, + body: { + output: { + status: 401, + message: + '[Google Ads Offline Conversions]:: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project. during google_ads_offline_store_conversions Job Creation', + authErrorCategory: 'REFRESH_TOKEN', + destinationResponse: { + error: { + code: 401, + message: + 'Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.', + status: 'UNAUTHENTICATED', + }, + }, + statTags: expectedStatTags, + }, + }, + }, + }, + }, + { + id: 'gaoc_v0_oauth_scenario_2', + name: 'google_adwords_offline_conversions', + description: + '[Proxy v0 API] :: Oauth where ACCESS_TOKEN_SCOPE_INSUFFICIENT error as mock response from destination', + successCriteria: + 'Since the error from the destination is 403 - the proxy should return 403 with authErrorCategory as AUTH_STATUS_INACTIVE', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://googleads.googleapis.com/v16/customers/1234/offlineUserDataJobs', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 403, + body: { + output: { + authErrorCategory: 'AUTH_STATUS_INACTIVE', + destinationResponse: { + error: { + code: 403, + message: 'Request had insufficient authentication scopes', + status: 'PERMISSION_DENIED', + }, + }, + message: + '[Google Ads Offline Conversions]:: Request had insufficient authentication scopes during google_ads_offline_store_conversions Job Creation', + statTags: expectedStatTags, + status: 403, + }, + }, + }, + }, + }, +]; + +export const v1oauthScenarios = [ + { + id: 'gaoc_v1_oauth_scenario_1', + name: 'google_adwords_offline_conversions', + description: + '[Proxy v1 API] :: Oauth where valid credentials are missing as mock response from destination', + successCriteria: 'The proxy should return 401 with authErrorCategory as REFRESH_TOKEN', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: + 'https://googleads.googleapis.com/v16/customers/customerid/offlineUserDataJobs', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 401, + body: { + output: { + authErrorCategory: 'REFRESH_TOKEN', + message: + '[Google Ads Offline Conversions]:: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project. during google_ads_offline_store_conversions Job Creation', + response: [ + { + error: + '[Google Ads Offline Conversions]:: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project. during google_ads_offline_store_conversions Job Creation', + metadata: generateMetadata(1), + statusCode: 401, + }, + ], + statTags: expectedStatTags, + status: 401, + }, + }, + }, + }, + }, + { + id: 'gaoc_v1_oauth_scenario_2', + name: 'google_adwords_offline_conversions', + description: + '[Proxy v1 API] :: Oauth where ACCESS_TOKEN_SCOPE_INSUFFICIENT error as mock response from destination', + successCriteria: + 'Since the error from the destination is 403 - the proxy should return 403 with authErrorCategory as AUTH_STATUS_INACTIVE', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: 'https://googleads.googleapis.com/v16/customers/1234/offlineUserDataJobs', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 403, + body: { + output: { + authErrorCategory: 'AUTH_STATUS_INACTIVE', + message: + '[Google Ads Offline Conversions]:: Request had insufficient authentication scopes during google_ads_offline_store_conversions Job Creation', + response: [ + { + error: + '[Google Ads Offline Conversions]:: Request had insufficient authentication scopes during google_ads_offline_store_conversions Job Creation', + metadata: generateMetadata(1), + statusCode: 403, + }, + ], + statTags: expectedStatTags, + status: 403, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/google_adwords_offline_conversions/network.ts b/test/integrations/destinations/google_adwords_offline_conversions/network.ts index 375879727b1..4dad9e0d1bf 100644 --- a/test/integrations/destinations/google_adwords_offline_conversions/network.ts +++ b/test/integrations/destinations/google_adwords_offline_conversions/network.ts @@ -1,7 +1,7 @@ export const networkCallsData = [ { httpReq: { - url: 'https://googleads.googleapis.com/v14/customers/11122233331/offlineUserDataJobs:create', + url: 'https://googleads.googleapis.com/v16/customers/11122233331/offlineUserDataJobs:create', data: { job: { storeSalesMetadata: { @@ -30,7 +30,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://googleads.googleapis.com/v14/customers/1112223333/googleAds:searchStream', + url: 'https://googleads.googleapis.com/v16/customers/1112223333/googleAds:searchStream', data: { query: `SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = 'Sign-up - click'`, }, @@ -63,7 +63,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://googleads.googleapis.com/v14/customers/11122233331/offlineUserDataJobs/OFFLINE_USER_DATA_JOB_ID_FOR_ADD_FAILURE:addOperations', + url: 'https://googleads.googleapis.com/v16/customers/11122233331/offlineUserDataJobs/OFFLINE_USER_DATA_JOB_ID_FOR_ADD_FAILURE:addOperations', data: { enable_partial_failure: false, enable_warnings: false, @@ -108,7 +108,7 @@ export const networkCallsData = [ status: 'INVALID_ARGUMENT', details: [ { - '@type': 'type.googleapis.com/google.ads.googleads.v14.errors.GoogleAdsFailure', + '@type': 'type.googleapis.com/google.ads.googleads.v16.errors.GoogleAdsFailure', errors: [ { errorCode: { @@ -144,7 +144,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://googleads.googleapis.com/v14/customers/1112223333/offlineUserDataJobs:create', + url: 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs:create', data: { job: { storeSalesMetadata: { @@ -173,7 +173,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://googleads.googleapis.com/v14/customers/1112223333/offlineUserDataJobs/OFFLINE_USER_DATA_JOB_ID:addOperations', + url: 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs/OFFLINE_USER_DATA_JOB_ID:addOperations', data: { enable_partial_failure: false, enable_warnings: false, @@ -216,7 +216,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://googleads.googleapis.com/v14/customers/1112223333/offlineUserDataJobs/OFFLINE_USER_DATA_JOB_ID:run', + url: 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs/OFFLINE_USER_DATA_JOB_ID:run', data: { validate_only: false }, params: { destination: 'google_adwords_offline_conversion' }, headers: { @@ -235,8 +235,10 @@ export const networkCallsData = [ }, }, { + description: + 'Mock response from destination depicting a request with invalid authentication credentials', httpReq: { - url: 'https://googleads.googleapis.com/v14/customers/customerid/offlineUserDataJobs:create', + url: 'https://googleads.googleapis.com/v16/customers/customerid/offlineUserDataJobs:create', data: { job: { storeSalesMetadata: { @@ -269,8 +271,43 @@ export const networkCallsData = [ }, }, { + description: + 'Mock response from destination depicting a request with invalid authentication scopes', httpReq: { - url: 'https://googleads.googleapis.com/v14/customers/1234567890/googleAds:searchStream', + url: 'https://googleads.googleapis.com/v16/customers/1234/offlineUserDataJobs:create', + data: { + job: { + storeSalesMetadata: { + custom_key: 'CUSTOM_KEY', + loyaltyFraction: 1, + transaction_upload_fraction: '1', + }, + type: 'STORE_SALES_UPLOAD_FIRST_PARTY', + }, + }, + params: { destination: 'google_adwords_offline_conversion' }, + headers: { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + 'login-customer-id': 'logincustomerid', + }, + method: 'POST', + }, + httpRes: { + status: 403, + data: { + error: { + code: 403, + message: 'Request had insufficient authentication scopes', + status: 'PERMISSION_DENIED', + }, + }, + }, + }, + { + httpReq: { + url: 'https://googleads.googleapis.com/v16/customers/1234567890/googleAds:searchStream', data: { query: `SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = 'Sign-up - click'`, }, @@ -298,7 +335,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://googleads.googleapis.com/v14/customers/1234567891/googleAds:searchStream', + url: 'https://googleads.googleapis.com/v16/customers/1234567891/googleAds:searchStream', data: { query: "SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = 'Sign-up - click'", @@ -331,7 +368,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://googleads.googleapis.com/v14/customers/1234567891/googleAds:searchStream', + url: 'https://googleads.googleapis.com/v16/customers/1234567891/googleAds:searchStream', data: { query: 'SELECT conversion_custom_variable.name FROM conversion_custom_variable' }, headers: { Authorization: 'Bearer abcd1234', @@ -365,7 +402,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://googleads.googleapis.com/v14/customers/1234567891:uploadClickConversions', + url: 'https://googleads.googleapis.com/v16/customers/1234567891:uploadClickConversions', data: { conversions: [ { @@ -432,7 +469,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://googleads.googleapis.com/v14/customers/1234567891:uploadClickConversions', + url: 'https://googleads.googleapis.com/v16/customers/1234567891:uploadClickConversions', data: { conversions: [ { @@ -491,4 +528,121 @@ export const networkCallsData = [ status: 200, }, }, + { + httpReq: { + url: 'https://googleads.googleapis.com/v16/customers/1234567893/googleAds:searchStream', + data: { + query: + "SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = 'Sign-up - click'", + }, + headers: { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + }, + method: 'POST', + params: { destination: 'google_adwords_offline_conversion' }, + }, + httpRes: { + data: [ + { + results: [ + { + conversionAction: { + resourceName: 'customers/1234567893/conversionActions/848898417', + id: '848898417', + }, + }, + ], + fieldMask: 'conversionAction.id', + requestId: 'dummyRequestId', + }, + ], + status: 200, + }, + }, + { + httpReq: { + url: 'https://googleads.googleapis.com/v16/customers/1234567893:uploadClickConversions', + data: { + conversions: [ + { + gbraid: 'gbraid', + wbraid: 'wbraid', + externalAttributionData: { + externalAttributionCredit: 10, + externalAttributionModel: 'externalAttributionModel', + }, + cartData: { + merchantId: 9876, + feedCountryCode: 'feedCountryCode', + feedLanguageCode: 'feedLanguageCode', + localTransactionCost: 20, + items: [{ productId: '507f1f77bcf86cd799439011', quantity: 2, unitPrice: 50 }], + }, + userIdentifiers: [ + { + userIdentifierSource: 'FIRST_PARTY', + hashedPhoneNumber: + '04e1dabb7c1348b72bfa87da179c9697c69af74827649266a5da8cdbb367abcd', + }, + ], + conversionEnvironment: 'APP', + gclid: 'gclid', + conversionDateTime: '2022-01-01 12:32:45-08:00', + conversionValue: 1, + currencyCode: 'GBP', + orderId: 'PL-123QR', + conversionAction: 'customers/1234567893/conversionActions/848898417', + }, + ], + partialFailure: true, + }, + headers: { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + }, + method: 'POST', + params: { destination: 'google_adwords_offline_conversion' }, + }, + httpRes: { + status: 200, + data: { + partialFailureError: { + code: 3, + message: + 'Customer is not allowlisted for accessing this feature., at conversions[0].conversion_environment', + details: [ + { + '@type': 'type.googleapis.com/google.ads.googleads.v16.errors.GoogleAdsFailure', + errors: [ + { + errorCode: { + notAllowlistedError: 'CUSTOMER_NOT_ALLOWLISTED_FOR_THIS_FEATURE', + }, + message: 'Customer is not allowlisted for accessing this feature.', + trigger: { + int64Value: '2', + }, + location: { + fieldPathElements: [ + { + fieldName: 'conversions', + index: 0, + }, + { + fieldName: 'conversion_environment', + }, + ], + }, + }, + ], + requestId: 'dummyRequestId', + }, + ], + }, + }, + }, + }, ]; diff --git a/test/integrations/destinations/google_adwords_offline_conversions/processor/data.ts b/test/integrations/destinations/google_adwords_offline_conversions/processor/data.ts index f47deaef67d..decb1e58c77 100644 --- a/test/integrations/destinations/google_adwords_offline_conversions/processor/data.ts +++ b/test/integrations/destinations/google_adwords_offline_conversions/processor/data.ts @@ -176,7 +176,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadClickConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadClickConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -263,6 +263,10 @@ export const data = [ conversionValue: 1, currencyCode: 'GBP', orderId: 'PL-123QR', + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, }, ], partialFailure: true, @@ -465,7 +469,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadClickConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadClickConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -520,6 +524,10 @@ export const data = [ JSON: { conversions: [ { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, gbraid: 'gbraid', wbraid: 'wbraid', externalAttributionData: { @@ -754,7 +762,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadClickConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadClickConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -809,6 +817,10 @@ export const data = [ JSON: { conversions: [ { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, gbraid: 'gbraid', wbraid: 'wbraid', externalAttributionData: { @@ -1043,7 +1055,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadCallConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadCallConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -1099,6 +1111,10 @@ export const data = [ conversions: [ { callerId: 'callerId', + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, callStartDateTime: '2022-08-28 15:01:30+05:30', conversionDateTime: '2022-01-01 12:32:45-08:00', conversionValue: 1, @@ -2015,7 +2031,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadClickConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadClickConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -2072,6 +2088,10 @@ export const data = [ JSON: { conversions: [ { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, gbraid: 'gbraid', wbraid: 'wbraid', externalAttributionData: { @@ -2128,7 +2148,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadCallConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadCallConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -2185,6 +2205,10 @@ export const data = [ JSON: { conversions: [ { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, callerId: 'callerId', callStartDateTime: '2022-08-28 15:01:30+05:30', conversionDateTime: '2022-01-01 12:32:45-08:00', @@ -2350,7 +2374,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadClickConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadClickConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -2379,6 +2403,10 @@ export const data = [ JSON: { conversions: [ { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, gclid: 'gclid', conversionDateTime: '2022-01-01 12:32:45-08:00', userIdentifiers: [ @@ -2546,7 +2574,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadCallConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadCallConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -2575,6 +2603,10 @@ export const data = [ JSON: { conversions: [ { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, callerId: 'callerId', callStartDateTime: '2022-08-28 15:01:30+05:30', conversionDateTime: '2022-01-01 12:32:45-08:00', @@ -2778,7 +2810,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadCallConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadCallConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -2832,6 +2864,10 @@ export const data = [ JSON: { conversions: [ { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, callerId: 'callerId', callStartDateTime: '2022-08-28 15:01:30+05:30', conversionDateTime: '2022-09-20 08:50:04+05:30', @@ -2997,7 +3033,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadClickConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadClickConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -3025,6 +3061,10 @@ export const data = [ JSON: { conversions: [ { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, gclid: 'gclid', conversionDateTime: '2022-01-01 12:32:45-08:00', userIdentifiers: [ @@ -3501,7 +3541,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadClickConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadClickConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -3532,6 +3572,10 @@ export const data = [ JSON: { conversions: [ { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, cartData: { items: [ { @@ -3861,7 +3905,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadClickConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadClickConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -3892,6 +3936,10 @@ export const data = [ JSON: { conversions: [ { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, cartData: { items: [ { @@ -4049,7 +4097,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/1112223333/offlineUserDataJobs', + 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -4077,6 +4125,10 @@ export const data = [ addConversionPayload: { operations: { create: { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, transaction_attribute: { store_attribute: { store_code: 'store code', @@ -4382,7 +4434,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/1112223333/offlineUserDataJobs', + 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -4409,6 +4461,10 @@ export const data = [ addConversionPayload: { operations: { create: { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, transaction_attribute: { store_attribute: { store_code: 'store code', @@ -4577,7 +4633,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/1112223333/offlineUserDataJobs', + 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -4604,6 +4660,10 @@ export const data = [ addConversionPayload: { operations: { create: { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, transaction_attribute: { store_attribute: { store_code: 'store code', @@ -4775,7 +4835,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/1112223333/offlineUserDataJobs', + 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -4802,6 +4862,10 @@ export const data = [ addConversionPayload: { operations: { create: { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, transaction_attribute: { store_attribute: { store_code: 'store code', @@ -4935,7 +4999,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/1112223333/offlineUserDataJobs', + 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -4962,6 +5026,10 @@ export const data = [ addConversionPayload: { operations: { create: { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, transaction_attribute: { store_attribute: { store_code: 'store code', @@ -5091,7 +5159,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/1112223333/offlineUserDataJobs', + 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -5118,6 +5186,10 @@ export const data = [ addConversionPayload: { operations: { create: { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, transaction_attribute: { store_attribute: { store_code: 'store code', @@ -5245,7 +5317,323 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/1112223333/offlineUserDataJobs', + 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs', + headers: { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + 'login-customer-id': 'logincustomerid', + }, + params: { + event: 'Sign-up - click', + customerId: '1112223333', + }, + body: { + JSON: { + event: '1112223333', + isStoreConversion: true, + createJobPayload: { + job: { + type: 'STORE_SALES_UPLOAD_FIRST_PARTY', + storeSalesMetadata: { + loyaltyFraction: '1', + transaction_upload_fraction: '1', + }, + }, + }, + addConversionPayload: { + operations: { + create: { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, + transaction_attribute: { + store_attribute: { + store_code: 'store code', + }, + transaction_amount_micros: '100000000', + currency_code: 'INR', + transaction_date_time: '2019-10-14 16:45:18+05:30', + }, + userIdentifiers: [{}], + }, + }, + enable_partial_failure: false, + enable_warnings: false, + validate_only: false, + }, + executeJobPayload: { + validate_only: false, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + secret: { + access_token: 'abcd1234', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + }, + statusCode: 200, + }, + ], + }, + }, + mockFns: timestampMock, + }, + { + name: 'google_adwords_offline_conversions', + description: 'Test 26 : store conversion consent mapped from UI config', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: {}, + }, + event: 'Product Clicked', + type: 'track', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + item_id: 'item id', + merchant_id: 'merchant id', + currency: 'INR', + revenue: '100', + store_code: 'store code', + gclid: 'gclid', + conversionDateTime: '2019-10-14T11:15:18.299Z', + product_id: '123445', + quantity: 123, + }, + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2019-10-14T11:15:53.296Z', + }, + metadata: { + secret: { + access_token: 'abcd1234', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + }, + destination: { + Config: { + isCustomerAllowed: false, + customerId: '111-222-3333', + subAccount: true, + loginCustomerId: 'login-customer-id', + userDataConsent: 'GRANTED', + personalizationConsent: 'DENIED', + eventsToOfflineConversionsTypeMapping: [ + { + from: 'Product Clicked', + to: 'store', + }, + ], + eventsToConversionsNamesMapping: [ + { + from: 'Product Clicked', + to: 'Sign-up - click', + }, + ], + hashUserIdentifier: true, + defaultUserIdentifier: 'phone', + validateOnly: false, + rudderAccountId: '2EOknn1JNH7WK1MfNkgr4t3u4fGYKkRK', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs', + headers: { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + 'login-customer-id': 'logincustomerid', + }, + params: { + event: 'Sign-up - click', + customerId: '1112223333', + }, + body: { + JSON: { + event: '1112223333', + isStoreConversion: true, + createJobPayload: { + job: { + type: 'STORE_SALES_UPLOAD_FIRST_PARTY', + storeSalesMetadata: { + loyaltyFraction: '1', + transaction_upload_fraction: '1', + }, + }, + }, + addConversionPayload: { + operations: { + create: { + consent: { + adPersonalization: 'DENIED', + adUserData: 'GRANTED', + }, + transaction_attribute: { + store_attribute: { + store_code: 'store code', + }, + transaction_amount_micros: '100000000', + currency_code: 'INR', + transaction_date_time: '2019-10-14 16:45:18+05:30', + }, + userIdentifiers: [{}], + }, + }, + enable_partial_failure: false, + enable_warnings: false, + validate_only: false, + }, + executeJobPayload: { + validate_only: false, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + secret: { + access_token: 'abcd1234', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + }, + statusCode: 200, + }, + ], + }, + }, + mockFns: timestampMock, + }, + { + name: 'google_adwords_offline_conversions', + description: + 'Test 27 : store conversion consent mapped from UI config even though integration object is present', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: {}, + }, + event: 'Product Clicked', + type: 'track', + messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', + anonymousId: '00000000000000000000000000', + userId: '12345', + properties: { + item_id: 'item id', + merchant_id: 'merchant id', + currency: 'INR', + revenue: '100', + store_code: 'store code', + gclid: 'gclid', + conversionDateTime: '2019-10-14T11:15:18.299Z', + product_id: '123445', + quantity: 123, + }, + integrations: { + google_adwords_offline_conversion: { + consent: { + adUserdata: 'UNSPECIFIED', + adPersonalization: 'GRANTED', + }, + }, + }, + name: 'ApplicationLoaded', + sentAt: '2019-10-14T11:15:53.296Z', + }, + metadata: { + secret: { + access_token: 'abcd1234', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + }, + destination: { + Config: { + isCustomerAllowed: false, + customerId: '111-222-3333', + subAccount: true, + loginCustomerId: 'login-customer-id', + userDataConsent: 'GRANTED', + personalizationConsent: 'DENIED', + eventsToOfflineConversionsTypeMapping: [ + { + from: 'Product Clicked', + to: 'store', + }, + ], + eventsToConversionsNamesMapping: [ + { + from: 'Product Clicked', + to: 'Sign-up - click', + }, + ], + hashUserIdentifier: true, + defaultUserIdentifier: 'phone', + validateOnly: false, + rudderAccountId: '2EOknn1JNH7WK1MfNkgr4t3u4fGYKkRK', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://googleads.googleapis.com/v16/customers/1112223333/offlineUserDataJobs', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -5272,6 +5660,10 @@ export const data = [ addConversionPayload: { operations: { create: { + consent: { + adPersonalization: 'DENIED', + adUserData: 'GRANTED', + }, transaction_attribute: { store_attribute: { store_code: 'store code', diff --git a/test/integrations/destinations/google_adwords_offline_conversions/router/data.ts b/test/integrations/destinations/google_adwords_offline_conversions/router/data.ts index 1536af81876..596e7550e57 100644 --- a/test/integrations/destinations/google_adwords_offline_conversions/router/data.ts +++ b/test/integrations/destinations/google_adwords_offline_conversions/router/data.ts @@ -96,6 +96,7 @@ export const data = [ refresh_token: 'efgh5678', developer_token: 'ijkl91011', }, + jobId: 1, userId: 'u1', }, destination: { @@ -211,6 +212,7 @@ export const data = [ refresh_token: 'efgh5678', developer_token: 'ijkl91011', }, + jobId: 2, userId: 'u1', }, destination: { @@ -274,7 +276,7 @@ export const data = [ refresh_token: 'efgh5678', developer_token: 'ijkl91011', }, - jobId: 1, + jobId: 3, userId: 'u1', }, destination: { @@ -350,7 +352,7 @@ export const data = [ refresh_token: 'efgh5678', developer_token: 'ijkl91011', }, - jobId: 2, + jobId: 4, userId: 'u1', }, destination: { @@ -426,7 +428,7 @@ export const data = [ refresh_token: 'efgh5678', developer_token: 'ijkl91011', }, - jobId: 3, + jobId: 5, userId: 'u1', }, destination: { @@ -479,80 +481,142 @@ export const data = [ body: { output: [ { - batchedRequest: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: - 'https://googleads.googleapis.com/v14/customers/7693729833/offlineUserDataJobs', - headers: { - Authorization: 'Bearer abcd1234', - 'Content-Type': 'application/json', - 'developer-token': 'ijkl91011', - }, - params: { event: 'Store sales', customerId: '7693729833' }, - body: { - JSON: { - event: '7693729833', - isStoreConversion: true, - createJobPayload: { - job: { - storeSalesMetadata: { - loyaltyFraction: 1, - transaction_upload_fraction: '1', + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://googleads.googleapis.com/v16/customers/7693729833/offlineUserDataJobs', + headers: { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + }, + params: { event: 'Store sales', customerId: '7693729833' }, + body: { + JSON: { + event: '7693729833', + isStoreConversion: true, + createJobPayload: { + job: { + storeSalesMetadata: { + loyaltyFraction: 1, + transaction_upload_fraction: '1', + }, + type: 'STORE_SALES_UPLOAD_FIRST_PARTY', }, - type: 'STORE_SALES_UPLOAD_FIRST_PARTY', }, - }, - addConversionPayload: { - operations: [ - { - create: { - transaction_attribute: { - store_attribute: { store_code: 'store code' }, - transaction_amount_micros: '100000000', - order_id: 'order id', - currency_code: 'INR', - transaction_date_time: '2019-10-14 16:45:18+05:30', + addConversionPayload: { + operations: [ + { + create: { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, + transaction_attribute: { + store_attribute: { store_code: 'store code' }, + transaction_amount_micros: '100000000', + order_id: 'order id', + currency_code: 'INR', + transaction_date_time: '2019-10-14 16:45:18+05:30', + }, + userIdentifiers: [ + { + hashedEmail: + '6db61e6dcbcf2390e4a46af426f26a133a3bee45021422fc7ae86e9136f14110', + }, + ], }, - userIdentifiers: [ - { - hashedEmail: - '6db61e6dcbcf2390e4a46af426f26a133a3bee45021422fc7ae86e9136f14110', + }, + { + create: { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, + transaction_attribute: { + store_attribute: { store_code: 'store code2' }, + transaction_amount_micros: '100000000', + order_id: 'order id', + currency_code: 'INR', + transaction_date_time: '2019-10-14 16:45:18+05:30', }, - ], + userIdentifiers: [ + { + hashedEmail: + '6db61e6dcbcf2390e4a46af426f26a133a3bee45021422fc7ae86e9136f14110', + }, + ], + }, }, - }, + ], + enable_partial_failure: false, + enable_warnings: false, + validate_only: true, + }, + executeJobPayload: { validate_only: true }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://googleads.googleapis.com/v16/customers/7693729833:uploadCallConversions', + headers: { + Authorization: 'Bearer abcd1234', + 'Content-Type': 'application/json', + 'developer-token': 'ijkl91011', + }, + params: { + event: 'Order Completed', + customerId: '7693729833', + customVariables: [{ from: '', to: '' }], + properties: { + loyaltyFraction: 1, + order_id: 'order id', + currency: 'INR', + revenue: '100', + store_code: 'store code2', + email: 'alex@example.com', + gclid: 'gclid', + product_id: '123445', + quantity: 123, + callerId: '1234', + callStartDateTime: '2019-10-14T11:15:18.299Z', + }, + }, + body: { + JSON: { + conversions: [ { - create: { - transaction_attribute: { - store_attribute: { store_code: 'store code2' }, - transaction_amount_micros: '100000000', - order_id: 'order id', - currency_code: 'INR', - transaction_date_time: '2019-10-14 16:45:18+05:30', - }, - userIdentifiers: [ - { - hashedEmail: - '6db61e6dcbcf2390e4a46af426f26a133a3bee45021422fc7ae86e9136f14110', - }, - ], + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', }, + callerId: '1234', + callStartDateTime: '2019-10-14T11:15:18.299Z', + conversionDateTime: '2019-10-14 16:45:18+05:30', + conversionValue: 100, + currencyCode: 'INR', }, ], - enable_partial_failure: false, - enable_warnings: false, - validate_only: true, + partialFailure: true, }, - executeJobPayload: { validate_only: true }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, + files: {}, }, - files: {}, - }, + ], metadata: [ { secret: { @@ -560,7 +624,7 @@ export const data = [ refresh_token: 'efgh5678', developer_token: 'ijkl91011', }, - jobId: 1, + jobId: 3, userId: 'u1', }, { @@ -569,7 +633,7 @@ export const data = [ refresh_token: 'efgh5678', developer_token: 'ijkl91011', }, - jobId: 2, + jobId: 4, userId: 'u1', }, ], @@ -621,7 +685,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadClickConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadClickConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -670,6 +734,10 @@ export const data = [ JSON: { conversions: [ { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, gbraid: 'gbraid', wbraid: 'wbraid', externalAttributionData: { @@ -714,6 +782,7 @@ export const data = [ refresh_token: 'efgh5678', developer_token: 'ijkl91011', }, + jobId: 1, userId: 'u1', }, ], @@ -753,7 +822,7 @@ export const data = [ type: 'REST', method: 'POST', endpoint: - 'https://googleads.googleapis.com/v14/customers/9625812972:uploadCallConversions', + 'https://googleads.googleapis.com/v16/customers/9625812972:uploadCallConversions', headers: { Authorization: 'Bearer abcd1234', 'Content-Type': 'application/json', @@ -802,6 +871,10 @@ export const data = [ JSON: { conversions: [ { + consent: { + adPersonalization: 'UNSPECIFIED', + adUserData: 'UNSPECIFIED', + }, callerId: 'callerId', callStartDateTime: '2022-08-28 15:01:30+05:30', conversionDateTime: '2022-01-01 12:32:45-08:00', @@ -824,6 +897,7 @@ export const data = [ refresh_token: 'efgh5678', developer_token: 'ijkl91011', }, + jobId: 2, userId: 'u1', }, ], @@ -857,108 +931,6 @@ export const data = [ }, }, }, - { - batchedRequest: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: - 'https://googleads.googleapis.com/v14/customers/7693729833:uploadCallConversions', - headers: { - Authorization: 'Bearer abcd1234', - 'Content-Type': 'application/json', - 'developer-token': 'ijkl91011', - }, - params: { - event: 'Order Completed', - customerId: '7693729833', - customVariables: [{ from: '', to: '' }], - properties: { - loyaltyFraction: 1, - order_id: 'order id', - currency: 'INR', - revenue: '100', - store_code: 'store code2', - email: 'alex@example.com', - gclid: 'gclid', - product_id: '123445', - quantity: 123, - callerId: '1234', - callStartDateTime: '2019-10-14T11:15:18.299Z', - }, - }, - body: { - JSON: { - conversions: [ - { - callerId: '1234', - callStartDateTime: '2019-10-14T11:15:18.299Z', - conversionDateTime: '2019-10-14 16:45:18+05:30', - conversionValue: 100, - currencyCode: 'INR', - }, - ], - partialFailure: true, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - }, - metadata: [ - { - secret: { - access_token: 'abcd1234', - refresh_token: 'efgh5678', - developer_token: 'ijkl91011', - }, - jobId: 2, - userId: 'u1', - }, - ], - batched: false, - statusCode: 200, - destination: { - Config: { - rudderAccountId: '2Hsy2iFyoG5VLDd9wQcggHLMYFA', - customerId: '769-372-9833', - subAccount: false, - UserIdentifierSource: 'FIRST_PARTY', - conversionEnvironment: 'none', - defaultUserIdentifier: 'email', - hashUserIdentifier: true, - validateOnly: true, - eventsToOfflineConversionsTypeMapping: [ - { from: 'Data Reading Guide', to: 'click' }, - { from: 'Order Completed', to: 'store' }, - { from: 'Sign-up - click', to: 'click' }, - { from: 'Outbound click (rudderstack.com)', to: 'click' }, - { from: 'Page view', to: 'click' }, - { from: 'download', to: 'click' }, - { from: 'Product Clicked', to: 'store' }, - { from: 'Order Completed', to: 'call' }, - ], - loginCustomerId: '4219454086', - eventsToConversionsNamesMapping: [ - { from: 'Data Reading Guide', to: 'Data Reading Guide' }, - { from: 'Order Completed', to: 'Order Completed' }, - { from: 'Sign-up - click', to: 'Sign-up - click' }, - { - from: 'Outbound click (rudderstack.com)', - to: 'Outbound click (rudderstack.com)', - }, - { from: 'Page view', to: 'Page view' }, - { from: 'Sign up completed', to: 'Sign-up - click' }, - { from: 'download', to: 'Page view' }, - { from: 'Product Clicked', to: 'Store sales' }, - ], - authStatus: 'active', - oneTrustCookieCategories: [], - customVariables: [{ from: '', to: '' }], - }, - }, - }, { metadata: [ { @@ -967,7 +939,7 @@ export const data = [ refresh_token: 'efgh5678', developer_token: 'ijkl91011', }, - jobId: 3, + jobId: 5, userId: 'u1', }, ], diff --git a/test/integrations/destinations/google_adwords_remarketing_lists/dataDelivery/business.ts b/test/integrations/destinations/google_adwords_remarketing_lists/dataDelivery/business.ts new file mode 100644 index 00000000000..2aefb18fddb --- /dev/null +++ b/test/integrations/destinations/google_adwords_remarketing_lists/dataDelivery/business.ts @@ -0,0 +1,376 @@ +import { + generateMetadata, + generateProxyV0Payload, + generateProxyV1Payload, +} from '../../../testUtils'; + +const commonHeaders = { + Authorization: 'Bearer dummy-access', + 'Content-Type': 'application/json', + 'developer-token': 'dummy-dev-token', +}; + +const commonParams = { + destination: 'google_adwords_remarketing_lists', + listId: '709078448', + customerId: '7693729833', + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, +}; + +const validRequestPayload1 = { + enablePartialFailure: true, + operations: [ + { + create: { + userIdentifiers: [ + { + hashedEmail: '85cc9fefa1eff1baab55d10df0cecff2acb25344867a5d0f96e1b1c5e2f10f05', + }, + { + hashedPhoneNumber: '8846dcb6ab2d73a0e67dbd569fa17cec2d9d391e5b05d1dd42919bc21ae82c45', + }, + { + hashedEmail: '85cc9fefa1eff1baab55d10df0cecff2acb25344867a5d0f96e1b1c5e2f10f05', + }, + { + hashedPhoneNumber: '8846dcb6ab2d73a0e67dbd569fa17cec2d9d391e5b05d1dd42919bc21ae82c45', + }, + { + addressInfo: { + hashedFirstName: 'e56d336922eaab3be8c1244dbaa713e134a8eba50ddbd4f50fd2fe18d72595cd', + }, + }, + ], + }, + }, + ], +}; + +const validRequestPayload2 = { + enablePartialFailure: true, + operations: [ + { + remove: { + userIdentifiers: [ + { + hashedEmail: '85cc9fefa1eff1baab55d10df0cecff2acb25344867a5d0f96e1b1c5e2f10f05', + }, + { + hashedPhoneNumber: '8846dcb6ab2d73a0e67dbd569fa17cec2d9d391e5b05d1dd42919bc21ae82c45', + }, + { + hashedEmail: '85cc9fefa1eff1baab55d10df0cecff2acb25344867a5d0f96e1b1c5e2f10f05', + }, + { + hashedPhoneNumber: '8846dcb6ab2d73a0e67dbd569fa17cec2d9d391e5b05d1dd42919bc21ae82c45', + }, + { + addressInfo: { + hashedFirstName: 'e56d336922eaab3be8c1244dbaa713e134a8eba50ddbd4f50fd2fe18d72595cd', + }, + }, + ], + }, + }, + ], +}; + +const invalidArgumentRequestPayload = { + enablePartialFailure: true, + operations: [ + { + create: { + userIdentifiers: [ + { + hashedEmail: 'abcd@testmail.com', + }, + ], + }, + }, + ], +}; + +const metadataArray = [generateMetadata(1)]; + +const expectedStatTags = { + destType: 'GOOGLE_ADWORDS_REMARKETING_LISTS', + destinationId: 'default-destinationId', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'default-workspaceId', +}; + +export const testScenariosForV0API = [ + { + id: 'garl_v0_scenario_1', + name: 'google_adwords_remarketing_lists', + description: + '[Proxy v0 API] :: Test for a valid request with a successful 200 response from the destination', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + headers: commonHeaders, + params: commonParams, + JSON: validRequestPayload1, + endpoint: 'https://googleads.googleapis.com/v15/customers/7693729833/offlineUserDataJobs', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + destinationResponse: { response: '', status: 200 }, + }, + }, + }, + }, + }, + { + id: 'garl_v0_scenario_2', + name: 'google_adwords_remarketing_lists', + description: + '[Proxy v0 API] :: Test for a invalid argument request with a 400 response from the destination', + successCriteria: 'Should return 400 with invalid argument error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + headers: commonHeaders, + params: commonParams, + JSON: invalidArgumentRequestPayload, + endpoint: 'https://googleads.googleapis.com/v15/customers/7693729834/offlineUserDataJobs', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 400, + body: { + output: { + status: 400, + message: + 'Request contains an invalid argument. during ga_audience response transformation', + destinationResponse: { + error: { + code: 400, + details: [ + { + '@type': 'type.googleapis.com/google.ads.googleads.v9.errors.GoogleAdsFailure', + errors: [ + { + errorCode: { + offlineUserDataJobError: 'INVALID_SHA256_FORMAT', + }, + message: 'The SHA256 encoded value is malformed.', + location: { + fieldPathElements: [ + { fieldName: 'operations', index: 0 }, + { fieldName: 'remove' }, + { fieldName: 'user_identifiers', index: 0 }, + { fieldName: 'hashed_email' }, + ], + }, + }, + ], + }, + ], + message: 'Request contains an invalid argument.', + status: 'INVALID_ARGUMENT', + }, + }, + statTags: expectedStatTags, + }, + }, + }, + }, + }, + { + id: 'garl_v0_scenario_3', + name: 'google_adwords_remarketing_lists', + description: + '[Proxy v0 API] :: Test for a valid request with a successful 200 response from the destination', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + headers: commonHeaders, + params: commonParams, + JSON: validRequestPayload2, + endpoint: 'https://googleads.googleapis.com/v15/customers/7693729833/offlineUserDataJobs', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + destinationResponse: { response: '', status: 200 }, + }, + }, + }, + }, + }, +]; + +export const testScenariosForV1API = [ + { + id: 'garl_v1_scenario_1', + name: 'google_adwords_remarketing_lists', + description: + '[Proxy v1 API] :: Test for a valid request with a successful 200 response from the destination', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: commonHeaders, + params: commonParams, + JSON: validRequestPayload1, + endpoint: + 'https://googleads.googleapis.com/v15/customers/7693729833/offlineUserDataJobs', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + response: [ + { + error: '""', + metadata: generateMetadata(1), + statusCode: 200, + }, + ], + status: 200, + }, + }, + }, + }, + }, + { + id: 'garl_v1_scenario_2', + name: 'google_adwords_remarketing_lists', + description: + '[Proxy v1 API] :: Test for a invalid argument request with a 400 response from the destination', + successCriteria: 'Should return 400 with invalid argument error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: commonHeaders, + params: commonParams, + JSON: invalidArgumentRequestPayload, + endpoint: + 'https://googleads.googleapis.com/v15/customers/7693729834/offlineUserDataJobs', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: + 'Request contains an invalid argument. during ga_audience response transformation', + response: [ + { + error: + 'Request contains an invalid argument. during ga_audience response transformation', + metadata: generateMetadata(1), + statusCode: 400, + }, + ], + statTags: expectedStatTags, + status: 400, + }, + }, + }, + }, + }, + { + id: 'garl_v1_scenario_3', + name: 'google_adwords_remarketing_lists', + description: + '[Proxy v1 API] :: Test for a valid request with a successful 200 response from the destination', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: commonHeaders, + params: commonParams, + JSON: validRequestPayload2, + endpoint: + 'https://googleads.googleapis.com/v15/customers/7693729833/offlineUserDataJobs', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + response: [ + { + error: '""', + metadata: generateMetadata(1), + statusCode: 200, + }, + ], + status: 200, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/google_adwords_remarketing_lists/dataDelivery/data.ts b/test/integrations/destinations/google_adwords_remarketing_lists/dataDelivery/data.ts index 414e46ea19f..51827a38e27 100644 --- a/test/integrations/destinations/google_adwords_remarketing_lists/dataDelivery/data.ts +++ b/test/integrations/destinations/google_adwords_remarketing_lists/dataDelivery/data.ts @@ -1,261 +1,3 @@ -export const data = [ - { - name: 'google_adwords_remarketing_lists', - description: 'Test 0', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://googleads.googleapis.com/v15/customers/7693729833/offlineUserDataJobs', - headers: { - Authorization: 'Bearer dummy-access', - 'Content-Type': 'application/json', - 'developer-token': 'dummy-dev-token', - }, - params: { - destination: 'google_adwords_remarketing_lists', - listId: '709078448', - customerId: '7693729833', - consent: {}, - }, - body: { - JSON: { - enablePartialFailure: true, - operations: [ - { - create: { - userIdentifiers: [ - { - hashedEmail: - '85cc9fefa1eff1baab55d10df0cecff2acb25344867a5d0f96e1b1c5e2f10f05', - }, - { - hashedPhoneNumber: - '8846dcb6ab2d73a0e67dbd569fa17cec2d9d391e5b05d1dd42919bc21ae82c45', - }, - { - hashedEmail: - '85cc9fefa1eff1baab55d10df0cecff2acb25344867a5d0f96e1b1c5e2f10f05', - }, - { - hashedPhoneNumber: - '8846dcb6ab2d73a0e67dbd569fa17cec2d9d391e5b05d1dd42919bc21ae82c45', - }, - { - addressInfo: { - hashedFirstName: - 'e56d336922eaab3be8c1244dbaa713e134a8eba50ddbd4f50fd2fe18d72595cd', - }, - }, - ], - }, - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - }, - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: { - output: { - status: 200, - message: 'Request Processed Successfully', - destinationResponse: { response: '', status: 200 }, - }, - }, - }, - }, - }, - { - name: 'google_adwords_remarketing_lists', - description: 'Test 1', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://googleads.googleapis.com/v15/customers/7693729834/offlineUserDataJobs', - headers: { - Authorization: 'Bearer dummy-access', - 'Content-Type': 'application/json', - 'developer-token': 'dummy-dev-token', - }, - params: { - listId: '709078448', - customerId: '7693729833', - destination: 'google_adwords_remarketing_lists', - consent: {}, - }, - body: { - JSON: { - enablePartialFailure: true, - operations: [ - { - create: { - userIdentifiers: [ - { - hashedEmail: 'abcd@testmail.com', - }, - ], - }, - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - }, - method: 'POST', - }, - }, - output: { - response: { - status: 400, - body: { - output: { - status: 400, - message: - 'Request contains an invalid argument. during ga_audience response transformation', - destinationResponse: { - error: { - code: 400, - details: [ - { - '@type': 'type.googleapis.com/google.ads.googleads.v9.errors.GoogleAdsFailure', - errors: [ - { - errorCode: { - offlineUserDataJobError: 'INVALID_SHA256_FORMAT', - }, - message: 'The SHA256 encoded value is malformed.', - location: { - fieldPathElements: [ - { fieldName: 'operations', index: 0 }, - { fieldName: 'remove' }, - { fieldName: 'user_identifiers', index: 0 }, - { fieldName: 'hashed_email' }, - ], - }, - }, - ], - }, - ], - message: 'Request contains an invalid argument.', - status: 'INVALID_ARGUMENT', - }, - }, - statTags: { - destType: 'GOOGLE_ADWORDS_REMARKETING_LISTS', - errorCategory: 'network', - destinationId: 'Non-determininable', - workspaceId: 'Non-determininable', - errorType: 'aborted', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', - }, - }, - }, - }, - }, - }, - { - name: 'google_adwords_remarketing_lists', - description: 'Test 2', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://googleads.googleapis.com/v15/customers/7693729833/offlineUserDataJobs', - headers: { - Authorization: 'Bearer dummy-access', - 'Content-Type': 'application/json', - 'developer-token': 'dummy-dev-token', - }, - params: { - listId: '709078448', - customerId: '7693729833', - destination: 'google_adwords_remarketing_lists', - consent: {}, - }, - body: { - JSON: { - enablePartialFailure: true, - operations: [ - { - remove: { - userIdentifiers: [ - { - hashedEmail: - '85cc9fefa1eff1baab55d10df0cecff2acb25344867a5d0f96e1b1c5e2f10f05', - }, - { - hashedPhoneNumber: - '8846dcb6ab2d73a0e67dbd569fa17cec2d9d391e5b05d1dd42919bc21ae82c45', - }, - { - hashedEmail: - '85cc9fefa1eff1baab55d10df0cecff2acb25344867a5d0f96e1b1c5e2f10f05', - }, - { - hashedPhoneNumber: - '8846dcb6ab2d73a0e67dbd569fa17cec2d9d391e5b05d1dd42919bc21ae82c45', - }, - { - addressInfo: { - hashedFirstName: - 'e56d336922eaab3be8c1244dbaa713e134a8eba50ddbd4f50fd2fe18d72595cd', - }, - }, - ], - }, - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - }, - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: { - output: { - status: 200, - message: 'Request Processed Successfully', - destinationResponse: { response: '', status: 200 }, - }, - }, - }, - }, - }, -]; +import { testScenariosForV0API, testScenariosForV1API } from './business'; + +export const data = [...testScenariosForV0API, ...testScenariosForV1API]; diff --git a/test/integrations/destinations/google_adwords_remarketing_lists/network.ts b/test/integrations/destinations/google_adwords_remarketing_lists/network.ts index 8e1edd21aa8..8e7c0acbcf7 100644 --- a/test/integrations/destinations/google_adwords_remarketing_lists/network.ts +++ b/test/integrations/destinations/google_adwords_remarketing_lists/network.ts @@ -7,7 +7,10 @@ export const networkCallsData = [ data: { job: { type: 'CUSTOMER_MATCH_USER_LIST', - customerMatchUserListMetadata: { userList: 'customers/7693729833/userLists/709078448' }, + customerMatchUserListMetadata: { + userList: 'customers/7693729833/userLists/709078448', + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, + }, }, }, headers: { @@ -86,7 +89,10 @@ export const networkCallsData = [ data: { job: { type: 'CUSTOMER_MATCH_USER_LIST', - customerMatchUserListMetadata: { userList: 'customers/7693729833/userLists/709078448' }, + customerMatchUserListMetadata: { + userList: 'customers/7693729833/userLists/709078448', + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, + }, }, }, headers: { diff --git a/test/integrations/destinations/google_adwords_remarketing_lists/processor/data.ts b/test/integrations/destinations/google_adwords_remarketing_lists/processor/data.ts index 804efec220a..a846e0370d5 100644 --- a/test/integrations/destinations/google_adwords_remarketing_lists/processor/data.ts +++ b/test/integrations/destinations/google_adwords_remarketing_lists/processor/data.ts @@ -79,7 +79,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -213,7 +213,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -332,7 +332,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -1434,7 +1434,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -2829,7 +2829,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -2909,7 +2909,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -4122,7 +4122,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -5422,7 +5422,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -6799,7 +6799,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -8109,7 +8109,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -9409,7 +9409,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -10804,7 +10804,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -10884,7 +10884,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -11059,7 +11059,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -11137,7 +11137,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -11281,7 +11281,7 @@ export const data = [ params: { listId: 'list111', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -11488,7 +11488,7 @@ export const data = [ params: { listId: 'aud1234', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -11627,7 +11627,7 @@ export const data = [ params: { listId: '830441345', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -11765,7 +11765,7 @@ export const data = [ params: { listId: '830441345', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, }, body: { JSON: { @@ -11836,6 +11836,8 @@ export const data = [ userSchema: ['email', 'phone', 'addressInfo'], isHashRequired: true, typeOfList: 'General', + userDataConsent: 'UNSPECIFIED', + personalizationConsent: 'GRANTED', }, }, message: { @@ -11860,8 +11862,6 @@ export const data = [ event: 'Add_Audience', messageId: 'bd2d67ca-0c9a-4d3b-a2f8-35a3c3f75ba7', properties: { - userDataConsent: 'UNSPECIFIED', - personalizationConsent: 'GRANTED', listData: { add: [ { @@ -11979,6 +11979,8 @@ export const data = [ userSchema: ['email', 'phone', 'addressInfo'], isHashRequired: true, typeOfList: 'General', + userDataConsent: 'RANDOM', + personalizationConsent: 'RANDOM', }, }, message: { @@ -12003,8 +12005,6 @@ export const data = [ event: 'Add_Audience', messageId: 'bd2d67ca-0c9a-4d3b-a2f8-35a3c3f75ba7', properties: { - userDataConsent: 'RANDOM', - personalizationConsent: 'RANDOM', listData: { add: [ { @@ -12048,7 +12048,7 @@ export const data = [ params: { listId: '830441345', customerId: '7693729833', - consent: {}, + consent: { adPersonalization: 'UNKNOWN', adUserData: 'UNKNOWN' }, }, body: { JSON: { diff --git a/test/integrations/destinations/google_adwords_remarketing_lists/router/data.ts b/test/integrations/destinations/google_adwords_remarketing_lists/router/data.ts index 8c122254004..31d5c72694c 100644 --- a/test/integrations/destinations/google_adwords_remarketing_lists/router/data.ts +++ b/test/integrations/destinations/google_adwords_remarketing_lists/router/data.ts @@ -228,7 +228,11 @@ export const data = [ 'Content-Type': 'application/json', 'developer-token': 'ijkl9101', }, - params: { listId: '7090784486', customerId: '7693729833', consent: {} }, + params: { + listId: '7090784486', + customerId: '7693729833', + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, + }, body: { JSON: { enablePartialFailure: true, @@ -305,7 +309,11 @@ export const data = [ 'Content-Type': 'application/json', 'developer-token': 'ijkl9101', }, - params: { listId: '7090784486', customerId: '7693729833', consent: {} }, + params: { + listId: '7090784486', + customerId: '7693729833', + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, + }, body: { JSON: { enablePartialFailure: true, @@ -359,7 +367,11 @@ export const data = [ 'Content-Type': 'application/json', 'developer-token': 'ijkl9101', }, - params: { listId: '7090784486', customerId: '7693729833', consent: {} }, + params: { + listId: '7090784486', + customerId: '7693729833', + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, + }, body: { JSON: { enablePartialFailure: true, @@ -436,7 +448,11 @@ export const data = [ 'Content-Type': 'application/json', 'developer-token': 'ijkl9101', }, - params: { listId: '7090784486', customerId: '7693729833', consent: {} }, + params: { + listId: '7090784486', + customerId: '7693729833', + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, + }, body: { JSON: { enablePartialFailure: true, @@ -484,7 +500,11 @@ export const data = [ 'Content-Type': 'application/json', 'developer-token': 'ijkl9101', }, - params: { listId: '7090784486', customerId: '7693729833', consent: {} }, + params: { + listId: '7090784486', + customerId: '7693729833', + consent: { adPersonalization: 'UNSPECIFIED', adUserData: 'UNSPECIFIED' }, + }, body: { JSON: { enablePartialFailure: true, diff --git a/test/integrations/destinations/heap/processor/data.ts b/test/integrations/destinations/heap/processor/data.ts index 6efa45435c2..f503134148f 100644 --- a/test/integrations/destinations/heap/processor/data.ts +++ b/test/integrations/destinations/heap/processor/data.ts @@ -961,4 +961,105 @@ export const data = [ }, }, }, + { + name: 'heap', + description: 'Test 8 -> Identify: No userId is present', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + appId: '', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + DisplayName: 'Heap.io', + ID: '1WTbl0l5GjOQKOvfmcGwk0T49kV', + Name: 'HEAP', + }, + Enabled: true, + ID: '1WTcDSEOE437e4ePH10BJNELXmE', + Name: 'heap test', + Transformations: [], + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + integrations: { + All: true, + }, + traits: { + email: 'sampath@gmail.com', + }, + messageId: 'fca2e71a-5d30-48e1-ba45-761c16e3820f', + originalTimestamp: '2020-01-16T13:21:59.076Z', + receivedAt: '2020-01-16T18:52:03.871+05:30', + request_ip: '[::1]:62312', + sentAt: '2020-01-16T13:22:03.85Z', + timestamp: '2020-01-16T18:51:59.097+05:30', + type: 'identify', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'userId is required: Workflow: procWorkflow, Step: validateuserId, ChildStep: undefined, OriginalError: userId is required', + statTags: { + destinationId: 'destId', + workspaceId: 'wspId', + destType: 'HEAP', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, ]; diff --git a/test/integrations/destinations/hs/processor/data.ts b/test/integrations/destinations/hs/processor/data.ts index 5eaa109dc42..f45f3a719bf 100644 --- a/test/integrations/destinations/hs/processor/data.ts +++ b/test/integrations/destinations/hs/processor/data.ts @@ -1,3 +1,45 @@ +import { Destination } from '../../../../../src/types'; +import { generateMetadata, generateSimplifiedIdentifyPayload } from '../../../testUtils'; + +const commonOutputHeaders = { + 'Content-Type': 'application/json', + Authorization: 'Bearer dummy-access-token', +}; + +const destination: Destination = { + Config: { + authorizationType: 'newPrivateAppApi', + accessToken: 'dummy-access-token', + hubID: 'dummy-hubId', + apiKey: 'dummy-apikey', + apiVersion: 'newApi', + lookupField: 'email', + hubspotEvents: [], + eventFilteringOption: 'disable', + blacklistedEvents: [ + { + eventName: '', + }, + ], + whitelistedEvents: [ + { + eventName: '', + }, + ], + }, + Enabled: true, + ID: '123', + Name: 'hs', + DestinationDefinition: { + ID: '123', + Name: 'hs', + DisplayName: 'Hubspot', + Config: {}, + }, + WorkspaceID: '123', + Transformations: [], +}; + export const data = [ { name: 'hs', @@ -4769,7 +4811,7 @@ export const data = [ body: [ { error: - '{"message":"rETL - Error during searching object record. Request Rate Limit reached","destinationResponse":{"response":{"status":"error","message":"Request Rate Limit reached","correlationId":"4d39ff11-e121-4514-bcd8-132a9dd1ff50","category":"RATE-LIMIT_REACHED","links":{"api key":"https://app.hubspot.com/l/api-key/"}},"status":429}}', + '{"message":"rETL - Error during searching object record. \\"Request Rate Limit reached\\"","destinationResponse":{"response":{"status":"error","message":"Request Rate Limit reached","correlationId":"4d39ff11-e121-4514-bcd8-132a9dd1ff50","category":"RATE-LIMIT_REACHED","links":{"api key":"https://app.hubspot.com/l/api-key/"}},"status":429}}', metadata: { jobId: 2, }, @@ -5269,4 +5311,66 @@ export const data = [ }, }, }, + { + name: 'hs', + description: 'Test coversion of null to string values', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: generateSimplifiedIdentifyPayload({ + userId: '12345', + context: { + traits: { + email: 'noname@email.com', + firstname: null, + gender: '', + lookupField: 'email', + }, + }, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + userId: '', + method: 'POST', + endpoint: 'https://api.hubapi.com/crm/v3/objects/contacts', + files: {}, + headers: commonOutputHeaders, + operation: 'createContacts', + params: {}, + body: { + FORM: {}, + JSON: { + properties: { + email: 'noname@email.com', + firstname: '', + gender: '', + }, + }, + JSON_ARRAY: {}, + XML: {}, + }, + }, + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, ]; diff --git a/test/integrations/destinations/intercom/dataDelivery/business.ts b/test/integrations/destinations/intercom/dataDelivery/business.ts new file mode 100644 index 00000000000..2490041832a --- /dev/null +++ b/test/integrations/destinations/intercom/dataDelivery/business.ts @@ -0,0 +1,615 @@ +import { + generateMetadata, + generateProxyV0Payload, + generateProxyV1Payload, +} from '../../../testUtils'; + +const commonHeaders = { + 'Content-Type': 'application/json', + Authorization: 'Bearer testApiKey', + Accept: 'application/json', + 'Intercom-Version': '1.4', +}; + +const unauthorizedResponseHeaders = { + 'Content-Type': 'application/json', + Authorization: 'Bearer invalidApiKey', + Accept: 'application/json', + 'Intercom-Version': '1.4', +}; + +const createUserPayload = { + email: 'test_1@test.com', + phone: '9876543210', + name: 'Test Name', + signed_up_at: 1601493060, + last_seen_user_agent: 'unknown', + update_last_request_at: true, + user_id: 'test_user_id_1', + custom_attributes: { + 'address.city': 'Kolkata', + 'address.state': 'West Bengal', + }, +}; + +const conflictUserPayload = { + email: 'test_1@test.com', + name: 'Rudder Labs', + signed_up_at: 1601496060, + last_seen_user_agent: 'unknown', + update_last_request_at: true, + user_id: 'test_user_id_2', + custom_attributes: { + 'address.city': 'Kolkata', + 'address.state': 'West Bengal', + }, +}; + +const updateUserPayload = { + email: 'test_1@test.com', + phone: '9876543211', + name: 'Sample Name', + signed_up_at: 1601493060, + update_last_request_at: true, + user_id: 'test_user_id_1', + custom_attributes: { + 'address.city': 'Kolkata', + 'address.state': 'West Bengal', + }, +}; + +const createCompanyPayload = { + company_id: 'rudderlabs', + name: 'RudderStack', + website: 'www.rudderstack.com', + plan: 'enterprise', + size: 500, + industry: 'CDP', + custom_attributes: { isOpenSource: true }, +}; + +const sendMessagePayload = { + from: { + type: 'user', + id: 'id@1', + }, + body: 'heyy, how are you', + referer: 'https://twitter.com/bob', +}; + +const createUserRequestParameters = { + JSON: createUserPayload, + headers: commonHeaders, +}; + +const updateUserRequestParameters = { + JSON: updateUserPayload, + headers: commonHeaders, +}; + +const createCompanyRequestParameters = { + JSON: createCompanyPayload, + headers: commonHeaders, +}; + +const sendMessageRequestParameters = { + JSON: sendMessagePayload, + headers: commonHeaders, +}; + +const metadataArray = [generateMetadata(1)]; + +export const testScenariosForV0API = [ + { + id: 'intercom_v0_other_scenario_1', + name: 'intercom', + description: + '[Proxy v0 API] :: Scenario to test Invalid Credentials Handling during Destination Authentication', + successCriteria: 'Should return 401 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...createUserRequestParameters, + headers: unauthorizedResponseHeaders, + endpoint: 'https://api.intercom.io/users/test1', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 401, + body: { + output: { + destinationResponse: { + errors: [ + { + code: 'unauthorized', + message: 'Access Token Invalid', + }, + ], + request_id: 'request123', + type: 'error.list', + }, + message: 'Request Processed Successfully', + status: 401, + }, + }, + }, + }, + }, + { + id: 'intercom_v0_other_scenario_2', + name: 'intercom', + description: + '[Proxy v0 API] :: Scenario to test Malformed Payload Response Handling from Destination', + successCriteria: 'Should return 401 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...createCompanyRequestParameters, + endpoint: 'https://api.eu.intercom.io/companies', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 401, + body: { + output: { + destinationResponse: { + errors: [ + { + code: 'parameter_invalid', + message: "Custom attribute 'isOpenSource' does not exist", + }, + ], + request_id: 'request_1', + type: 'error.list', + }, + message: 'Request Processed Successfully', + status: 401, + }, + }, + }, + }, + }, + { + id: 'intercom_v0_other_scenario_3', + name: 'intercom', + description: + '[Proxy v0 API] :: Scenario to test Plan-Restricted Response Handling from Destination', + successCriteria: 'Should return 403 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...sendMessageRequestParameters, + endpoint: 'https://api.intercom.io/messages', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 403, + body: { + output: { + destinationResponse: { + errors: [ + { + code: 'api_plan_restricted', + message: 'Active subscription needed.', + }, + ], + request_id: 'request124', + type: 'error.list', + }, + message: 'Request Processed Successfully', + status: 403, + }, + }, + }, + }, + }, + { + id: 'intercom_v0_other_scenario_4', + name: 'intercom', + description: '[Proxy v0 API] :: Scenario to test Rate Limit Exceeded Handling from Destination', + successCriteria: 'Should return 429 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...updateUserRequestParameters, + endpoint: 'https://api.intercom.io/users/test1', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 429, + body: { + output: { + destinationResponse: { + errors: [ + { + code: 'rate_limit_exceeded', + message: 'The rate limit for the App has been exceeded', + }, + ], + request_id: 'request125', + type: 'error.list', + }, + message: 'Request Processed Successfully', + status: 429, + }, + }, + }, + }, + }, + { + id: 'intercom_v0_other_scenario_5', + name: 'intercom', + description: '[Proxy v0 API] :: Scenario to test Conflict User Handling from Destination', + successCriteria: 'Should return 409 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + JSON: conflictUserPayload, + headers: { + ...commonHeaders, + 'Intercom-Version': '2.10', + }, + endpoint: 'https://api.intercom.io/contacts', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 409, + body: { + output: { + destinationResponse: { + errors: [ + { + code: 'conflict', + message: 'A contact matching those details already exists with id=test1', + }, + ], + request_id: 'request126', + type: 'error.list', + }, + message: 'Request Processed Successfully', + status: 409, + }, + }, + }, + }, + }, + { + id: 'intercom_v0_other_scenario_6', + name: 'intercom', + description: '[Proxy v0 API] :: Scenario to test Unsupported Media Handling from Destination', + successCriteria: 'Should return 406 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + JSON: createUserPayload, + headers: { + ...commonHeaders, + 'Intercom-Version': '2.10', + }, + endpoint: 'https://api.intercom.io/users', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 406, + body: { + output: { + destinationResponse: { + errors: [ + { + code: 'media_type_not_acceptable', + message: 'The Accept header should send a media type of application/json', + }, + ], + type: 'error.list', + }, + message: 'Request Processed Successfully', + status: 406, + }, + }, + }, + }, + }, +]; + +export const testScenariosForV1API = [ + { + id: 'intercom_v1_other_scenario_1', + name: 'intercom', + description: + '[Proxy v1 API] :: Scenario to test Invalid Credentials Handling during Destination Authentication', + successCriteria: 'Should return 401 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...createUserRequestParameters, + headers: unauthorizedResponseHeaders, + endpoint: 'https://api.intercom.io/users/test1', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + response: [ + { + error: + '{"type":"error.list","request_id":"request123","errors":[{"code":"unauthorized","message":"Access Token Invalid"}]}', + metadata: generateMetadata(1), + statusCode: 401, + }, + ], + status: 401, + }, + }, + }, + }, + }, + { + id: 'intercom_v1_other_scenario_2', + name: 'intercom', + description: + '[Proxy v1 API] :: Scenario to test Malformed Payload Response Handling from Destination', + successCriteria: 'Should return 401 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...createCompanyRequestParameters, + endpoint: 'https://api.eu.intercom.io/companies', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + response: [ + { + error: + '{"type":"error.list","request_id":"request_1","errors":[{"code":"parameter_invalid","message":"Custom attribute \'isOpenSource\' does not exist"}]}', + metadata: generateMetadata(1), + statusCode: 401, + }, + ], + status: 401, + }, + }, + }, + }, + }, + { + id: 'intercom_v1_other_scenario_3', + name: 'intercom', + description: + '[Proxy v1 API] :: Scenario to test Plan-Restricted Response Handling from Destination', + successCriteria: 'Should return 403 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...sendMessageRequestParameters, + endpoint: 'https://api.intercom.io/messages', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + response: [ + { + error: + '{"type":"error.list","request_id":"request124","errors":[{"code":"api_plan_restricted","message":"Active subscription needed."}]}', + metadata: generateMetadata(1), + statusCode: 403, + }, + ], + status: 403, + }, + }, + }, + }, + }, + { + id: 'intercom_v1_other_scenario_4', + name: 'intercom', + description: '[Proxy v1 API] :: Scenario to test Rate Limit Exceeded Handling from Destination', + successCriteria: 'Should return 429 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...updateUserRequestParameters, + endpoint: 'https://api.intercom.io/users/test1', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + response: [ + { + error: + '{"type":"error.list","request_id":"request125","errors":[{"code":"rate_limit_exceeded","message":"The rate limit for the App has been exceeded"}]}', + metadata: generateMetadata(1), + statusCode: 429, + }, + ], + status: 429, + }, + }, + }, + }, + }, + { + id: 'intercom_v1_other_scenario_5', + name: 'intercom', + description: '[Proxy v1 API] :: Scenario to test Conflict User Handling from Destination', + successCriteria: 'Should return 409 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + JSON: conflictUserPayload, + headers: { + ...commonHeaders, + 'Intercom-Version': '2.10', + }, + endpoint: 'https://api.intercom.io/contacts', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + response: [ + { + error: + '{"type":"error.list","request_id":"request126","errors":[{"code":"conflict","message":"A contact matching those details already exists with id=test1"}]}', + metadata: generateMetadata(1), + statusCode: 409, + }, + ], + status: 409, + }, + }, + }, + }, + }, + { + id: 'intercom_v1_other_scenario_6', + name: 'intercom', + description: '[Proxy v1 API] :: Scenario to test Unsupported Media Handling from Destination', + successCriteria: 'Should return 406 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + JSON: createUserPayload, + headers: { + ...commonHeaders, + 'Intercom-Version': '2.10', + }, + endpoint: 'https://api.intercom.io/users', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + response: [ + { + error: + '{"errors":[{"code":"media_type_not_acceptable","message":"The Accept header should send a media type of application/json"}],"type":"error.list"}', + metadata: generateMetadata(1), + statusCode: 406, + }, + ], + status: 406, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/intercom/dataDelivery/data.ts b/test/integrations/destinations/intercom/dataDelivery/data.ts index 6b0077ae0f4..e5d2f4696b9 100644 --- a/test/integrations/destinations/intercom/dataDelivery/data.ts +++ b/test/integrations/destinations/intercom/dataDelivery/data.ts @@ -1,90 +1,9 @@ +import { otherScenariosV0, otherScenariosV1 } from './other'; +import { testScenariosForV0API, testScenariosForV1API } from './business'; + export const data = [ - { - "name": "intercom", - "description": "Test 0", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.intercom.io/users/test1", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer intercomApiKey", - "Accept": "application/json", - "Intercom-Version": "1.4" - }, - "params": {}, - "body": { - "JSON": { - "email": "test_1@test.com", - "phone": "9876543210", - "name": "Test Name", - "signed_up_at": 1601493060, - "last_seen_user_agent": "unknown", - "update_last_request_at": true, - "user_id": "test_user_id_1", - "custom_attributes": { - "anonymousId": "58b21c2d-f8d5-4410-a2d0-b268a26b7e33", - "key1": "value1", - "address.city": "Kolkata", - "address.state": "West Bengal", - "originalArray[0].nested_field": "nested value", - "originalArray[0].tags[0]": "tag_1", - "originalArray[0].tags[1]": "tag_2", - "originalArray[0].tags[2]": "tag_3", - "originalArray[1].nested_field": "nested value", - "originalArray[1].tags[0]": "tag_1", - "originalArray[2].nested_field": "nested value" - } - }, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "58b21c2d-f8d5-4410-a2d0-b268a26b7e33" - }, - "method": "POST" - } - }, - "output": { - "response": { - "status": 500, - "body": { - "output": { - "status": 500, - "message": "[Intercom Response Handler] Request failed for destination intercom with status: 408", - "destinationResponse": { - "response": { - "type": "error.list", - "request_id": "000on04msi4jpk7d3u60", - "errors": [ - { - "code": "Request Timeout", - "message": "The server would not wait any longer for the client" - } - ] - }, - "status": 408 - }, - "statTags": { - "destType": "INTERCOM", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "retryable", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } - } -] + ...otherScenariosV0, + ...otherScenariosV1, + ...testScenariosForV0API, + ...testScenariosForV1API, +]; diff --git a/test/integrations/destinations/intercom/dataDelivery/other.ts b/test/integrations/destinations/intercom/dataDelivery/other.ts new file mode 100644 index 00000000000..46cdcac4689 --- /dev/null +++ b/test/integrations/destinations/intercom/dataDelivery/other.ts @@ -0,0 +1,384 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { + generateMetadata, + generateProxyV0Payload, + generateProxyV1Payload, +} from '../../../testUtils'; + +const commonHeaders = { + 'Content-Type': 'application/json', + Authorization: 'Bearer testApiKey', + Accept: 'application/json', + 'Intercom-Version': '1.4', +}; + +const createUserPayload = { + email: 'test_1@test.com', + phone: '9876543210', + name: 'Test Name', + signed_up_at: 1601493060, + last_seen_user_agent: 'unknown', + update_last_request_at: true, + user_id: 'test_user_id_1', + custom_attributes: { + 'address.city': 'Kolkata', + 'address.state': 'West Bengal', + }, +}; + +const commonRequestParameters = { + JSON: createUserPayload, + headers: commonHeaders, +}; + +const expectedStatTags = { + destType: 'INTERCOM', + destinationId: 'default-destinationId', + errorCategory: 'network', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'default-workspaceId', +}; + +const metadataArray = [generateMetadata(1)]; + +export const otherScenariosV0 = [ + { + id: 'intercom_v0_other_scenario_1', + name: 'intercom', + description: '[Proxy v0 API] :: Request Timeout Error Handling from Destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://api.intercom.io/users/test1', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + '[Intercom Response Handler] Request failed for destination intercom with status: 408', + destinationResponse: { + response: { + type: 'error.list', + request_id: '000on04msi4jpk7d3u60', + errors: [ + { + code: 'Request Timeout', + message: 'The server would not wait any longer for the client', + }, + ], + }, + status: 408, + }, + statTags: expectedStatTags, + }, + }, + }, + }, + }, + { + id: 'intercom_v0_other_scenario_2', + name: 'intercom', + description: + '[Proxy v0 API] :: Scenario for testing Service Unavailable error from destination', + successCriteria: 'Should return 503 status code with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://api.intercom.io/users/test2', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 503, + body: { + output: { + status: 503, + message: 'Request Processed Successfully', + destinationResponse: { + type: 'error.list', + request_id: 'request127', + errors: [ + { + code: 'service_unavailable', + message: 'Sorry, the API service is temporarily unavailable', + }, + ], + }, + }, + }, + }, + }, + }, + { + id: 'intercom_v0_other_scenario_3', + name: 'intercom', + description: '[Proxy v0 API] :: Scenario for testing Internal Server error from destination', + successCriteria: 'Should return 500 status code with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://api.intercom.io/users/test3', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + destinationResponse: { + errors: [ + { + code: 'client_error', + message: 'Unknown server error', + }, + ], + request_id: 'request128', + type: 'error.list', + }, + message: 'Request Processed Successfully', + status: 500, + }, + }, + }, + }, + }, + { + id: 'intercom_v0_other_scenario_4', + name: 'intercom', + description: '[Proxy v0 API] :: Scenario for testing Gateway Time Out error from destination', + successCriteria: 'Should return 504 status code with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://api.intercom.io/users/test4', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 504, + body: { + output: { + destinationResponse: { + errors: [ + { + code: 'server_timeout', + message: 'Server timed out when making request', + }, + ], + request_id: 'request129', + type: 'error.list', + }, + message: 'Request Processed Successfully', + status: 504, + }, + }, + }, + }, + }, +]; + +export const otherScenariosV1: ProxyV1TestData[] = [ + { + id: 'intercom_v1_other_scenario_1', + name: 'intercom', + description: '[Proxy v1 API] :: Request Timeout Error Handling from Destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: 'https://api.intercom.io/users/test1', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: + '[Intercom Response Handler] Request failed for destination intercom with status: 408', + response: [ + { + error: + '{"type":"error.list","request_id":"000on04msi4jpk7d3u60","errors":[{"code":"Request Timeout","message":"The server would not wait any longer for the client"}]}', + metadata: generateMetadata(1), + statusCode: 500, + }, + ], + statTags: expectedStatTags, + status: 500, + }, + }, + }, + }, + }, + { + id: 'intercom_v1_other_scenario_2', + name: 'intercom', + description: + '[Proxy v1 API] :: Scenario for testing Service Unavailable error from destination', + successCriteria: 'Should return 503 status code with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: 'https://api.intercom.io/users/test2', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + response: [ + { + error: + '{"type":"error.list","request_id":"request127","errors":[{"code":"service_unavailable","message":"Sorry, the API service is temporarily unavailable"}]}', + metadata: generateMetadata(1), + statusCode: 503, + }, + ], + status: 503, + }, + }, + }, + }, + }, + { + id: 'intercom_v1_other_scenario_3', + name: 'intercom', + description: '[Proxy v1 API] :: Scenario for testing Internal Server error from destination', + successCriteria: 'Should return 500 status code with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: 'https://api.intercom.io/users/test3', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + response: [ + { + error: + '{"type":"error.list","request_id":"request128","errors":[{"code":"client_error","message":"Unknown server error"}]}', + metadata: generateMetadata(1), + statusCode: 500, + }, + ], + status: 500, + }, + }, + }, + }, + }, + { + id: 'intercom_v1_other_scenario_4', + name: 'intercom', + description: '[Proxy v1 API] :: Scenario for testing Gateway Time Out error from destination', + successCriteria: 'Should return 504 status code with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: 'https://api.intercom.io/users/test4', + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + response: [ + { + error: + '{"type":"error.list","request_id":"request129","errors":[{"code":"server_timeout","message":"Server timed out when making request"}]}', + metadata: generateMetadata(1), + statusCode: 504, + }, + ], + status: 504, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/intercom/deleteUsers/data.ts b/test/integrations/destinations/intercom/deleteUsers/data.ts index a45af0a98f4..58285ee683e 100644 --- a/test/integrations/destinations/intercom/deleteUsers/data.ts +++ b/test/integrations/destinations/intercom/deleteUsers/data.ts @@ -19,7 +19,7 @@ export const data = [ }, ], config: { - apiKey: 'API_KEY', + apiKey: 'testApiKey', }, }, ], @@ -57,7 +57,7 @@ export const data = [ }, ], config: { - apiKey: 'API_KEY', + apiKey: 'testApiKey', }, }, ], @@ -140,7 +140,7 @@ export const data = [ body: [ { statusCode: 400, - error: 'api key for deletion not present', + error: 'The access token is not available', }, ], }, diff --git a/test/integrations/destinations/intercom/network.ts b/test/integrations/destinations/intercom/network.ts index e3bba3f2601..5fa8ac6e968 100644 --- a/test/integrations/destinations/intercom/network.ts +++ b/test/integrations/destinations/intercom/network.ts @@ -1,3 +1,48 @@ +const commonHeaders = { + Accept: 'application/json', + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', +}; + +const v0VersionHeaders = { + 'Content-Type': 'application/json', + Authorization: 'Bearer testApiKey', + Accept: 'application/json', + 'Intercom-Version': '1.4', + 'User-Agent': 'RudderLabs', +}; + +const v1VersionHeaders = { + 'Content-Type': 'application/json', + Authorization: 'Bearer testApiKey', + Accept: 'application/json', + 'Intercom-Version': '2.10', + 'User-Agent': 'RudderLabs', +}; + +const userPayload = { + email: 'test_1@test.com', + phone: '9876543210', + name: 'Test Name', + signed_up_at: 1601493060, + last_seen_user_agent: 'unknown', + update_last_request_at: true, + user_id: 'test_user_id_1', + custom_attributes: { + 'address.city': 'Kolkata', + 'address.state': 'West Bengal', + }, +}; + +const companyPayload = { + company_id: 'rudderlabs', + name: 'RudderStack', + website: 'www.rudderstack.com', + plan: 'enterprise', + size: 500, + industry: 'CDP', +}; + const deleteNwData = [ { httpReq: { @@ -6,11 +51,7 @@ const deleteNwData = [ data: { intercom_user_id: '1', }, - headers: { - Accept: 'application/json', - Authorization: 'Bearer API_KEY', - 'Content-Type': 'application/json', - }, + headers: commonHeaders, }, httpRes: { data: { @@ -33,11 +74,7 @@ const deleteNwData = [ data: { intercom_user_id: '12', }, - headers: { - Accept: 'application/json', - Authorization: 'Bearer API_KEY', - 'Content-Type': 'application/json', - }, + headers: commonHeaders, }, httpRes: { status: 200, @@ -54,11 +91,7 @@ const deleteNwData = [ data: { intercom_user_id: '7', }, - headers: { - Accept: 'application/json', - Authorization: 'Bearer API_KEY', - 'Content-Type': 'application/json', - }, + headers: commonHeaders, }, httpRes: { status: 200, @@ -75,11 +108,7 @@ const deleteNwData = [ data: { intercom_user_id: '9', }, - headers: { - Accept: 'application/json', - Authorization: 'Bearer API_KEY', - 'Content-Type': 'application/json', - }, + headers: commonHeaders, }, httpRes: { status: 200, @@ -91,55 +120,482 @@ const deleteNwData = [ }, ]; const deliveryCallsData = [ + { + httpReq: { + method: 'post', + url: 'https://api.intercom.io/contacts/search', + data: { + query: { + operator: 'AND', + value: [{ field: 'email', operator: '=', value: 'test@rudderlabs.com' }], + }, + }, + headers: commonHeaders, + }, + httpRes: { + status: 200, + statusText: 'ok', + data: { + type: 'list', + total_count: 0, + pages: { + type: 'pages', + page: 1, + per_page: 50, + total_pages: 0, + }, + data: [], + }, + }, + }, + { + httpReq: { + method: 'post', + url: 'https://api.intercom.io/contacts/search', + data: { + query: { + operator: 'AND', + value: [{ field: 'email', operator: '=', value: 'test+2@rudderlabs.com' }], + }, + }, + headers: commonHeaders, + }, + httpRes: { + status: 200, + statusText: 'ok', + data: { + type: 'list', + total_count: 1, + pages: { + type: 'pages', + page: 1, + per_page: 50, + total_pages: 1, + }, + data: [ + { + type: 'contact', + id: '7070129940741e45d040', + workspace_id: 'rudderWorkspace', + external_id: 'user@2', + role: 'user', + email: 'test+2@rudderlabs.com', + }, + ], + }, + }, + }, + { + httpReq: { + method: 'post', + url: 'https://api.eu.intercom.io/contacts/search', + data: { + query: { + operator: 'AND', + value: [{ field: 'email', operator: '=', value: 'test+5@rudderlabs.com' }], + }, + }, + headers: commonHeaders, + }, + httpRes: { + status: 200, + statusText: 'ok', + data: { + type: 'list', + total_count: 1, + pages: { + type: 'pages', + page: 1, + per_page: 50, + total_pages: 1, + }, + data: [ + { + type: 'contact', + id: '70701240741e45d040', + workspace_id: 'rudderWorkspace', + external_id: 'user@5', + role: 'user', + email: 'test+5@rudderlabs.com', + }, + ], + }, + }, + }, + { + httpReq: { + method: 'post', + url: 'https://api.intercom.io/contacts/search', + data: { + query: { + operator: 'AND', + value: [{ field: 'phone', operator: '=', value: '+91 9299999999' }], + }, + }, + headers: commonHeaders, + }, + httpRes: { + status: 200, + statusText: 'ok', + data: { + type: 'list', + total_count: 1, + pages: { + type: 'pages', + page: 1, + per_page: 50, + total_pages: 1, + }, + data: [ + { + type: 'contact', + id: '7070129940741e45d040', + workspace_id: 'rudderWorkspace', + external_id: 'user@2', + role: 'user', + email: 'test+2@rudderlabs.com', + }, + ], + }, + }, + }, + { + httpReq: { + method: 'post', + url: 'https://api.intercom.io/contacts/search', + data: { + query: { + operator: 'AND', + value: [{ field: 'email', operator: '=', value: 'test+4@rudderlabs.com' }], + }, + }, + headers: commonHeaders, + }, + httpRes: { + status: 200, + statusText: 'ok', + data: { + type: 'list', + total_count: 0, + pages: { + type: 'pages', + page: 1, + per_page: 50, + total_pages: 0, + }, + data: [], + }, + }, + }, + { + httpReq: { + method: 'post', + url: 'https://api.intercom.io/contacts/search', + data: { + query: { + operator: 'AND', + value: [{ field: 'email', operator: '=', value: 'test+3@rudderlabs.com' }], + }, + }, + headers: { + Accept: 'application/json', + Authorization: 'Bearer invalidApiKey', + 'Content-Type': 'application/json', + }, + }, + httpRes: { + status: 401, + data: { + type: 'error.list', + request_id: 'request_1', + errors: [ + { + code: 'unauthorized', + message: 'Access Token Invalid', + }, + ], + }, + }, + }, + { + httpReq: { + method: 'post', + url: 'https://api.eu.intercom.io/companies', + data: companyPayload, + headers: commonHeaders, + }, + httpRes: { + status: 200, + data: { + type: 'company', + company_id: 'rudderlabs', + id: '657264e9018c0a647s45', + name: 'RudderStack', + website: 'www.rudderstack.com', + plan: 'enterprise', + size: 500, + industry: 'CDP', + remote_created_at: 1374138000, + created_at: 1701930212, + updated_at: 1701930212, + }, + }, + }, + { + httpReq: { + method: 'post', + url: 'https://api.eu.intercom.io/companies', + data: { + ...companyPayload, + custom_attributes: { isOpenSource: true }, + }, + headers: commonHeaders, + }, + httpRes: { + status: 401, + data: { + type: 'error.list', + request_id: 'request_1', + errors: [ + { + code: 'parameter_invalid', + message: "Custom attribute 'isOpenSource' does not exist", + }, + ], + }, + }, + }, + { + httpReq: { + url: 'https://api.intercom.io/users/test1', + data: userPayload, + params: {}, + headers: v0VersionHeaders, + method: 'POST', + }, + httpRes: { + data: { + type: 'error.list', + request_id: '000on04msi4jpk7d3u60', + errors: [ + { + code: 'Request Timeout', + message: 'The server would not wait any longer for the client', + }, + ], + }, + status: 408, + }, + }, + { + httpReq: { + url: 'https://api.intercom.io/users/test1', + data: userPayload, + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer invalidApiKey', + Accept: 'application/json', + 'Intercom-Version': '1.4', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: { + type: 'error.list', + request_id: 'request123', + errors: [ + { + code: 'unauthorized', + message: 'Access Token Invalid', + }, + ], + }, + status: 401, + }, + }, + { + httpReq: { + url: 'https://api.intercom.io/messages', + data: { + from: { + type: 'user', + id: 'id@1', + }, + body: 'heyy, how are you', + referer: 'https://twitter.com/bob', + }, + params: {}, + headers: v0VersionHeaders, + method: 'POST', + }, + httpRes: { + data: { + type: 'error.list', + request_id: 'request124', + errors: [ + { + code: 'api_plan_restricted', + message: 'Active subscription needed.', + }, + ], + }, + status: 403, + }, + }, { httpReq: { url: 'https://api.intercom.io/users/test1', data: { email: 'test_1@test.com', - phone: '9876543210', - name: 'Test Name', + phone: '9876543211', + name: 'Sample Name', signed_up_at: 1601493060, - last_seen_user_agent: 'unknown', update_last_request_at: true, user_id: 'test_user_id_1', custom_attributes: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - key1: 'value1', 'address.city': 'Kolkata', 'address.state': 'West Bengal', - 'originalArray[0].nested_field': 'nested value', - 'originalArray[0].tags[0]': 'tag_1', - 'originalArray[0].tags[1]': 'tag_2', - 'originalArray[0].tags[2]': 'tag_3', - 'originalArray[1].nested_field': 'nested value', - 'originalArray[1].tags[0]': 'tag_1', - 'originalArray[2].nested_field': 'nested value', }, }, params: {}, - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - 'User-Agent': 'RudderLabs', + headers: v0VersionHeaders, + method: 'POST', + }, + httpRes: { + data: { + type: 'error.list', + request_id: 'request125', + errors: [ + { + code: 'rate_limit_exceeded', + message: 'The rate limit for the App has been exceeded', + }, + ], }, + status: 429, + }, + }, + { + httpReq: { + url: 'https://api.intercom.io/contacts', + data: { + email: 'test_1@test.com', + name: 'Rudder Labs', + signed_up_at: 1601496060, + last_seen_user_agent: 'unknown', + update_last_request_at: true, + user_id: 'test_user_id_2', + custom_attributes: { + 'address.city': 'Kolkata', + 'address.state': 'West Bengal', + }, + }, + params: {}, + headers: v1VersionHeaders, method: 'POST', }, httpRes: { data: { type: 'error.list', - request_id: '000on04msi4jpk7d3u60', + request_id: 'request126', errors: [ { - code: 'Request Timeout', - message: 'The server would not wait any longer for the client', + code: 'conflict', + message: 'A contact matching those details already exists with id=test1', }, ], }, - status: 408, + status: 409, + }, + }, + { + httpReq: { + url: 'https://api.intercom.io/users', + data: userPayload, + params: {}, + headers: v1VersionHeaders, + method: 'POST', + }, + httpRes: { + data: { + errors: [ + { + code: 'media_type_not_acceptable', + message: 'The Accept header should send a media type of application/json', + }, + ], + type: 'error.list', + }, + status: 406, + }, + }, + { + httpReq: { + url: 'https://api.intercom.io/users/test2', + data: userPayload, + params: {}, + headers: v0VersionHeaders, + method: 'POST', + }, + httpRes: { + data: { + type: 'error.list', + request_id: 'request127', + errors: [ + { + code: 'service_unavailable', + message: 'Sorry, the API service is temporarily unavailable', + }, + ], + }, + status: 503, + }, + }, + { + httpReq: { + url: 'https://api.intercom.io/users/test3', + data: userPayload, + params: {}, + headers: v0VersionHeaders, + method: 'POST', + }, + httpRes: { + data: { + type: 'error.list', + request_id: 'request128', + errors: [ + { + code: 'client_error', + message: 'Unknown server error', + }, + ], + }, + status: 500, + }, + }, + { + httpReq: { + url: 'https://api.intercom.io/users/test4', + data: userPayload, + params: {}, + headers: v0VersionHeaders, + method: 'POST', + }, + httpRes: { + data: { + type: 'error.list', + request_id: 'request129', + errors: [ + { + code: 'server_timeout', + message: 'Server timed out when making request', + }, + ], + }, + status: 504, }, }, ]; export const networkCallsData = [...deleteNwData, ...deliveryCallsData]; - diff --git a/test/integrations/destinations/intercom/processor/data.ts b/test/integrations/destinations/intercom/processor/data.ts index 14d1884ba28..2c562ed4e99 100644 --- a/test/integrations/destinations/intercom/processor/data.ts +++ b/test/integrations/destinations/intercom/processor/data.ts @@ -1,7 +1,1213 @@ export const data = [ { name: 'intercom', - description: 'Test 0', + description: 'No message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + age: 23, + email: 'adc@test.com', + firstname: 'Test', + birthday: '2022-05-13T12:51:01.470Z', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36', + }, + event: 'Product Searched', + originalTimestamp: '2020-09-22T14:42:44.724Z', + timestamp: '2022-09-22T20:12:44.757+05:30', + userId: 'user@1', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 1, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 1, + }, + statusCode: 400, + error: + 'message Type is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message Type is not present. Aborting', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'INTERCOM', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Unsupported message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + age: 23, + email: 'adc@test.com', + firstname: 'Test', + birthday: '2022-05-13T12:51:01.470Z', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36', + }, + event: 'Product Searched', + type: 'page', + originalTimestamp: '2020-09-22T14:42:44.724Z', + timestamp: '2022-09-22T20:12:44.757+05:30', + userId: 'user@1', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 2, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 2, + }, + statusCode: 400, + error: + 'message type page is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type page is not supported', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'INTERCOM', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Missing required config', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@1', + channel: 'web', + context: { + traits: { + age: 23, + email: 'adc@test.com', + firstName: 'Test', + }, + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 3, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 3, + }, + statusCode: 400, + error: + 'Access Token is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Access Token is not present. Aborting', + statTags: { + errorCategory: 'dataValidation', + errorType: 'configuration', + destType: 'INTERCOM', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Create customer with email as lookup field', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@1', + channel: 'web', + context: { + traits: { + age: 23, + email: 'test@rudderlabs.com', + phone: '+91 9999999999', + firstName: 'Test', + lastName: 'Rudderlabs', + address: 'california usa', + ownerId: '13', + lastSeenAt: '2023-11-10T14:42:44.724Z', + }, + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 4, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + email: 'test@rudderlabs.com', + external_id: 'user@1', + last_seen_at: 1699627364, + name: 'Test Rudderlabs', + owner_id: 13, + phone: '+91 9999999999', + custom_attributes: { + address: 'california usa', + age: 23, + }, + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://api.intercom.io/contacts', + headers: { + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + Accept: 'application/json', + 'Intercom-Version': '2.10', + }, + userId: '', + version: '1', + type: 'REST', + method: 'POST', + files: {}, + params: {}, + }, + metadata: { jobId: 4 }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Update customer with email as lookup field', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@2', + channel: 'web', + context: { + traits: { + age: 32, + email: 'test+2@rudderlabs.com', + phone: '+91 9299999999', + firstName: 'Test', + lastName: 'RudderStack', + ownerId: '14', + }, + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 5, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + email: 'test+2@rudderlabs.com', + external_id: 'user@2', + name: 'Test RudderStack', + owner_id: 14, + phone: '+91 9299999999', + custom_attributes: { + age: 32, + }, + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://api.intercom.io/contacts/7070129940741e45d040', + headers: { + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + Accept: 'application/json', + 'Intercom-Version': '2.10', + }, + userId: '', + version: '1', + type: 'REST', + method: 'PUT', + files: {}, + params: {}, + }, + metadata: { jobId: 5 }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Missing required parameters for an identify call', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'anon@2', + channel: 'web', + context: { + traits: { + age: 32, + phone: '+91 9299999999', + firstName: 'Test', + lastName: 'RudderStack', + ownerId: '14', + role: 'user', + source: 'rudder-sdk', + }, + }, + integrations: { + INTERCOM: { + lookup: 'phone', + }, + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 6, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 6, + }, + statusCode: 400, + error: + 'Either email or userId is required for Identify call: Workflow: procWorkflow, Step: identifyPayloadForLatestVersion, ChildStep: undefined, OriginalError: Either email or userId is required for Identify call', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'INTERCOM', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Unauthorized error while searching contact for an identify call', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@3', + channel: 'web', + context: { + traits: { + phone: '+91 9399999999', + email: 'test+3@rudderlabs.com', + firstName: 'Test', + lastName: 'Rudder', + ownerId: '15', + role: 'admin', + source: 'rudder-android-sdk', + }, + }, + integrations: { + INTERCOM: { + lookup: 'email', + }, + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'invalidApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 7, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 7, + }, + statusCode: 401, + error: + '{"message":"{\\"message\\":\\"Unable to search contact due to : [{\\\\\\"code\\\\\\":\\\\\\"unauthorized\\\\\\",\\\\\\"message\\\\\\":\\\\\\"Access Token Invalid\\\\\\"}]: Workflow: procWorkflow, Step: searchContact, ChildStep: undefined, OriginalError: Unable to search contact due to : [{\\\\\\"code\\\\\\":\\\\\\"unauthorized\\\\\\",\\\\\\"message\\\\\\":\\\\\\"Access Token Invalid\\\\\\"}]\\",\\"destinationResponse\\":{\\"response\\":{\\"type\\":\\"error.list\\",\\"request_id\\":\\"request_1\\",\\"errors\\":[{\\"code\\":\\"unauthorized\\",\\"message\\":\\"Access Token Invalid\\"}]},\\"status\\":401}}","destinationResponse":{"response":{"type":"error.list","request_id":"request_1","errors":[{"code":"unauthorized","message":"Access Token Invalid"}]},"status":401}}', + statTags: { + errorCategory: 'network', + errorType: 'aborted', + destType: 'INTERCOM', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Track call without event name', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@3', + channel: 'web', + context: { + traits: { + age: 32, + email: 'test+3@rudderlabs.com', + phone: '+91 9399999999', + firstName: 'Test', + lastName: 'RudderStack', + ownerId: '15', + }, + }, + properties: { + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + price: { + amount: 3000, + currency: 'USD', + }, + }, + type: 'track', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 8, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 8, + }, + statusCode: 400, + error: + 'Event name is required for track call: Workflow: procWorkflow, Step: trackPayload, ChildStep: undefined, OriginalError: Event name is required for track call', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'INTERCOM', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Successful track call', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@2', + channel: 'web', + context: { + traits: { + age: 32, + email: 'test+2@rudderlabs.com', + phone: '+91 9299999999', + firstName: 'Test', + lastName: 'RudderStack', + ownerId: '14', + }, + }, + properties: { + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + price: { + amount: 3000, + currency: 'USD', + }, + }, + event: 'Product Viewed', + type: 'track', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 9, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + FORM: {}, + JSON: { + created_at: 1700628164, + email: 'test+2@rudderlabs.com', + event_name: 'Product Viewed', + metadata: { + price: { + amount: 3000, + currency: 'USD', + }, + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + }, + user_id: 'user@2', + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://api.intercom.io/events', + headers: { + Accept: 'application/json', + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + 'Intercom-Version': '2.10', + }, + method: 'POST', + type: 'REST', + userId: '', + version: '1', + params: {}, + files: {}, + }, + statusCode: 200, + metadata: { + jobId: 9, + }, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Group call without groupId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@4', + channel: 'web', + context: { + traits: { + email: 'test+4@rudderlabs.com', + phone: '+91 9499999999', + firstName: 'John', + lastName: 'Doe', + ownerId: '16', + }, + }, + traits: { + name: 'RudderStack', + size: 500, + website: 'www.rudderstack.com', + industry: 'CDP', + plan: 'enterprise', + }, + type: 'group', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 10, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 10, + }, + statusCode: 400, + error: + 'groupId is required for group call: Workflow: procWorkflow, Step: groupPayloadForLatestVersion, ChildStep: validateMessageAndPreparePayload, OriginalError: groupId is required for group call', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'INTERCOM', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Successful group call to create or update company', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@4', + groupId: 'rudderlabs', + channel: 'web', + context: { + traits: { + email: 'test+4@rudderlabs.com', + phone: '+91 9499999999', + firstName: 'John', + lastName: 'Doe', + ownerId: '16', + }, + }, + traits: { + name: 'RudderStack', + size: 500, + website: 'www.rudderstack.com', + industry: 'CDP', + plan: 'enterprise', + }, + type: 'group', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 11, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + company_id: 'rudderlabs', + industry: 'CDP', + name: 'RudderStack', + plan: 'enterprise', + size: 500, + website: 'www.rudderstack.com', + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://api.intercom.io/companies', + headers: { + Accept: 'application/json', + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + 'Intercom-Version': '2.10', + }, + method: 'POST', + type: 'REST', + userId: '', + version: '1', + params: {}, + files: {}, + }, + statusCode: 200, + metadata: { + jobId: 11, + }, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Successful group call to add user to company', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@5', + groupId: 'rudderlabs', + channel: 'web', + context: { + traits: { + email: 'test+5@rudderlabs.com', + phone: '+91 9599999999', + firstName: 'John', + lastName: 'Snow', + ownerId: '17', + }, + }, + traits: { + name: 'RudderStack', + size: 500, + website: 'www.rudderstack.com', + industry: 'CDP', + plan: 'enterprise', + }, + type: 'group', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'eu', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 12, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + id: '657264e9018c0a647s45', + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://api.eu.intercom.io/contacts/70701240741e45d040/companies', + headers: { + Accept: 'application/json', + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + 'Intercom-Version': '2.10', + }, + method: 'POST', + type: 'REST', + userId: '', + version: '1', + params: {}, + files: {}, + }, + statusCode: 200, + metadata: { + jobId: 12, + }, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Identify rEtl test', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + externalId: [ + { + id: 'user@1', + type: 'INTERCOM-customer', + identifierType: 'user_id', + }, + ], + mappedToDestination: 'true', + }, + traits: { + email: 'test@rudderlabs.com', + phone: '+91 9999999999', + name: 'Test Rudderlabs', + owner_id: 13, + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 13, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + email: 'test@rudderlabs.com', + name: 'Test Rudderlabs', + phone: '+91 9999999999', + owner_id: 13, + user_id: 'user@1', + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://api.intercom.io/contacts', + headers: { + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + Accept: 'application/json', + 'Intercom-Version': '2.10', + }, + userId: '', + version: '1', + type: 'REST', + method: 'POST', + files: {}, + params: {}, + }, + metadata: { jobId: 13 }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Track rEtl test', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@1', + channel: 'web', + context: { + mappedToDestination: 'true', + }, + traits: { + event_name: 'Product Viewed', + user_id: 'user@1', + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + price: { + amount: 3000, + currency: 'USD', + }, + }, + event: 'Product Viewed', + type: 'track', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 14, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + event_name: 'Product Viewed', + price: { + amount: 3000, + currency: 'USD', + }, + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + user_id: 'user@1', + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://api.intercom.io/events', + headers: { + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + Accept: 'application/json', + 'Intercom-Version': '2.10', + }, + userId: '', + version: '1', + type: 'REST', + method: 'POST', + files: {}, + params: {}, + }, + metadata: { jobId: 14 }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Old version - successful identify call', feature: 'processor', module: 'destination', version: 'v0', @@ -90,12 +1296,21 @@ export const data = [ type: 'identify', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'intercomApiKey', + apiVersion: 'v1', appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, }, }, + metadata: { + jobId: 15, + }, }, ], }, @@ -148,6 +1363,9 @@ export const data = [ userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, statusCode: 200, + metadata: { + jobId: 15, + }, }, ], }, @@ -155,7 +1373,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 1', + description: 'Old version - successful identify call', feature: 'processor', module: 'destination', version: 'v0', @@ -225,12 +1443,21 @@ export const data = [ type: 'identify', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'intercomApiKey', + apiVersion: 'v1', appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, }, }, + metadata: { + jobId: 16, + }, }, ], }, @@ -273,6 +1500,9 @@ export const data = [ userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, statusCode: 200, + metadata: { + jobId: 16, + }, }, ], }, @@ -280,7 +1510,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 2', + description: 'Old version - successful identify call', feature: 'processor', module: 'destination', version: 'v0', @@ -349,12 +1579,21 @@ export const data = [ type: 'identify', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'intercomApiKey', + apiVersion: 'v1', appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, }, }, + metadata: { + jobId: 17, + }, }, ], }, @@ -397,6 +1636,9 @@ export const data = [ userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, statusCode: 200, + metadata: { + jobId: 17, + }, }, ], }, @@ -404,7 +1646,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 3', + description: 'Old version - successful identify call', feature: 'processor', module: 'destination', version: 'v0', @@ -473,12 +1715,21 @@ export const data = [ type: 'identify', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'intercomApiKey', + apiVersion: 'v1', appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, }, }, + metadata: { + jobId: 18, + }, }, ], }, @@ -521,6 +1772,9 @@ export const data = [ userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, statusCode: 200, + metadata: { + jobId: 18, + }, }, ], }, @@ -528,7 +1782,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 4: ERROR - Either of `email` or `userId` is required for Identify call', + description: 'Old Version: Identify call without email and userId', feature: 'processor', module: 'destination', version: 'v0', @@ -596,12 +1850,21 @@ export const data = [ type: 'identify', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'intercomApiKey', + apiVersion: 'v1', appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, }, }, + metadata: { + jobId: 19, + }, }, ], }, @@ -612,15 +1875,19 @@ export const data = [ body: [ { statusCode: 400, - error: 'Either of `email` or `userId` is required for Identify call', + error: + 'Either of `email` or `userId` is required for Identify call: Workflow: procWorkflow, Step: identifyPayloadForOlderVersion, ChildStep: undefined, OriginalError: Either of `email` or `userId` is required for Identify call', statTags: { errorCategory: 'dataValidation', errorType: 'instrumentation', destType: 'INTERCOM', module: 'destination', - implementation: 'native', + implementation: 'cdkV2', feature: 'processor', }, + metadata: { + jobId: 19, + }, }, ], }, @@ -628,7 +1895,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 5', + description: 'Old version - successful identify call', feature: 'processor', module: 'destination', version: 'v0', @@ -707,12 +1974,21 @@ export const data = [ type: 'identify', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'intercomApiKey', + apiVersion: 'v1', appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, }, }, + metadata: { + jobId: 20, + }, }, ], }, @@ -767,6 +2043,9 @@ export const data = [ userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, statusCode: 200, + metadata: { + jobId: 20, + }, }, ], }, @@ -774,7 +2053,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 6', + description: 'Old version - successful identify call', feature: 'processor', module: 'destination', version: 'v0', @@ -853,13 +2132,22 @@ export const data = [ type: 'identify', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'intercomApiKey', + apiVersion: 'v1', appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, updateLastRequestAt: false, }, }, + metadata: { + jobId: 21, + }, }, ], }, @@ -914,6 +2202,9 @@ export const data = [ userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, statusCode: 200, + metadata: { + jobId: 21, + }, }, ], }, @@ -921,7 +2212,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 7', + description: 'Old version - successful identify call', feature: 'processor', module: 'destination', version: 'v0', @@ -995,12 +2286,21 @@ export const data = [ type: 'identify', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'intercomApiKey', + apiVersion: 'v1', appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, }, }, + metadata: { + jobId: 22, + }, }, ], }, @@ -1044,6 +2344,9 @@ export const data = [ userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, statusCode: 200, + metadata: { + jobId: 22, + }, }, ], }, @@ -1051,7 +2354,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 8', + description: 'Old version - successful track call', feature: 'processor', module: 'destination', version: 'v0', @@ -1154,12 +2457,21 @@ export const data = [ type: 'track', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'intercomApiKey', + apiVersion: 'v1', appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, }, }, + metadata: { + jobId: 23, + }, }, ], }, @@ -1222,6 +2534,9 @@ export const data = [ userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, statusCode: 200, + metadata: { + jobId: 23, + }, }, ], }, @@ -1229,7 +2544,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 9', + description: 'Old version - successful track call', feature: 'processor', module: 'destination', version: 'v0', @@ -1300,12 +2615,21 @@ export const data = [ type: 'track', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'intercomApiKey', + apiVersion: 'v1', appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, }, }, + metadata: { + jobId: 24, + }, }, ], }, @@ -1341,6 +2665,9 @@ export const data = [ userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, statusCode: 200, + metadata: { + jobId: 24, + }, }, ], }, @@ -1348,7 +2675,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 10: ERROR - Either of `email` or `userId` is required for Track call', + description: 'Old version : Track call without email or userId', feature: 'processor', module: 'destination', version: 'v0', @@ -1418,30 +2745,187 @@ export const data = [ type: 'track', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'intercomApiKey', + apiVersion: 'v1', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + metadata: { + jobId: 25, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: + 'Either email or userId is required for Track call: Workflow: procWorkflow, Step: trackPayload, ChildStep: undefined, OriginalError: Either email or userId is required for Track call', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'INTERCOM', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + metadata: { + jobId: 25, + }, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Old version : successful identify call', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + channel: 'mobile', + context: { + app: { + build: '1.0', + name: 'Test_Example', + namespace: 'com.example.testapp', + version: '1.0', + }, + externalId: [ + { + id: '10156', + type: 'INTERCOM-customer', + identifierType: 'user_id', + }, + ], + mappedToDestination: 'true', + device: { + id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + manufacturer: 'Apple', + model: 'iPhone', + name: 'iPod touch (7th generation)', + type: 'iOS', + }, + library: { + name: 'test-ios-library', + version: '1.0.7', + }, + locale: 'en-US', + network: { + bluetooth: false, + carrier: 'unavailable', + cellular: false, + wifi: true, + }, + os: { + name: 'iOS', + version: '14.0', + }, + screen: { + density: 2, + height: 320, + width: 568, + }, + timezone: 'Asia/Kolkata', + traits: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + name: 'Test Name', + firstName: 'Test', + lastName: 'Name', + createdAt: '2020-09-30T19:11:00.337Z', + phone: '9876543210', + key1: 'value1', + }, + userAgent: 'unknown', + }, + event: 'Test Event 2', + integrations: { + All: true, + }, + messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', + originalTimestamp: '2020-09-30T19:11:00.337Z', + receivedAt: '2020-10-01T00:41:11.369+05:30', + request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', + sentAt: '2020-09-30T19:11:10.382Z', + timestamp: '2020-10-01T00:41:01.324+05:30', + type: 'identify', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'intercomApiKey', + apiVersion: 'v1', appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, }, }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: 'Either of `email` or `userId` is required for Track call', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'INTERCOM', - module: 'destination', - implementation: 'native', - feature: 'processor', + metadata: { + jobId: 26, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.intercom.io/users', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer intercomApiKey', + Accept: 'application/json', + 'Intercom-Version': '1.4', + }, + params: {}, + body: { + JSON: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + name: 'Test Name', + firstName: 'Test', + lastName: 'Name', + createdAt: '2020-09-30T19:11:00.337Z', + phone: '9876543210', + key1: 'value1', + update_last_request_at: true, + user_id: '10156', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + }, + statusCode: 200, + metadata: { + jobId: 26, }, }, ], @@ -1450,7 +2934,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 11', + description: 'Old version : successful identify call', feature: 'processor', module: 'destination', version: 'v0', @@ -1468,13 +2952,6 @@ export const data = [ namespace: 'com.example.testapp', version: '1.0', }, - externalId: [ - { - identifierType: 'email', - id: 'test@gmail.com', - }, - ], - mappedToDestination: true, device: { id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', manufacturer: 'Apple', @@ -1527,12 +3004,22 @@ export const data = [ type: 'identify', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'intercomApiKey', + apiVersion: 'v1', appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, + sendAnonymousId: true, }, }, + metadata: { + jobId: 27, + }, }, ], }, @@ -1556,14 +3043,15 @@ export const data = [ params: {}, body: { JSON: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - name: 'Test Name', - firstName: 'Test', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', phone: '9876543210', - key1: 'value1', - email: 'test@gmail.com', + name: 'Test Name', + signed_up_at: 1601493060, + last_seen_user_agent: 'unknown', + custom_attributes: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + key1: 'value1', + }, + user_id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', update_last_request_at: true, }, JSON_ARRAY: {}, @@ -1574,6 +3062,9 @@ export const data = [ userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, statusCode: 200, + metadata: { + jobId: 27, + }, }, ], }, @@ -1581,7 +3072,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 12', + description: 'Old version : Identify call without email or userId', feature: 'processor', module: 'destination', version: 'v0', @@ -1651,13 +3142,97 @@ export const data = [ type: 'identify', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'intercomApiKey', + apiVersion: 'v1', appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, - sendAnonymousId: true, + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 28, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: + 'Either of `email` or `userId` is required for Identify call: Workflow: procWorkflow, Step: identifyPayloadForOlderVersion, ChildStep: undefined, OriginalError: Either of `email` or `userId` is required for Identify call', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'INTERCOM', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + metadata: { + jobId: 28, + }, + }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Old version : successful group call', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + groupId: 'test_company_id_wdasda', + traits: { + employees: 450, + plan: 'basic', + userId: 'sdfrsdfsdfsf', + email: 'test@test.com', + name: 'rudderUpdate', + size: '50', + industry: 'IT', + monthlySpend: '2131231', + remoteCreatedAt: '1683017572', + key1: 'val1', + }, + anonymousId: 'sdfrsdfsdfsf', + integrations: { + All: true, + }, + type: 'group', + userId: 'sdfrsdfsdfsf', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'abcd=', + appId: 'asdasdasd', + apiVersion: 'v1', + collectContext: false, }, }, + metadata: { + jobId: 29, + }, }, ], }, @@ -1671,35 +3246,75 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.intercom.io/users', + endpoint: 'https://api.intercom.io/companies', headers: { 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', + Authorization: 'Bearer abcd=', Accept: 'application/json', 'Intercom-Version': '1.4', }, params: {}, body: { JSON: { - phone: '9876543210', - name: 'Test Name', - signed_up_at: 1601493060, - last_seen_user_agent: 'unknown', + company_id: 'test_company_id_wdasda', + name: 'rudderUpdate', + plan: 'basic', + size: 50, + industry: 'IT', + monthly_spend: 2131231, + remote_created_at: 1683017572, custom_attributes: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - key1: 'value1', + employees: 450, + email: 'test@test.com', + key1: 'val1', }, - user_id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - update_last_request_at: true, }, JSON_ARRAY: {}, XML: {}, FORM: {}, }, files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + userId: 'sdfrsdfsdfsf', + }, + statusCode: 200, + metadata: { + jobId: 29, + }, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.intercom.io/users', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer abcd=', + Accept: 'application/json', + 'Intercom-Version': '1.4', + }, + params: {}, + body: { + JSON: { + user_id: 'sdfrsdfsdfsf', + companies: [ + { + company_id: 'test_company_id_wdasda', + name: 'rudderUpdate', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: 'sdfrsdfsdfsf', }, statusCode: 200, + metadata: { + jobId: 29, + }, }, ], }, @@ -1707,7 +3322,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 13: ERROR - Either of `email` or `userId` is required for Identify call', + description: 'Old version : successful group call', feature: 'processor', module: 'destination', version: 'v0', @@ -1716,8 +3331,16 @@ export const data = [ body: [ { message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', + groupId: 'test_company_id', + traits: { + plan: 'basic', + name: 'rudderUpdate', + size: 50, + industry: 'IT', + monthlySpend: '2131231', + email: 'comanyemail@abc.com', + }, + anonymousId: '12312312', context: { app: { build: '1.0', @@ -1753,37 +3376,30 @@ export const data = [ width: 568, }, timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - name: 'Test Name', - firstName: 'Test', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - phone: '9876543210', - key1: 'value1', - }, userAgent: 'unknown', }, - event: 'Test Event 2', integrations: { All: true, }, messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', + type: 'group', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { - apiKey: 'intercomApiKey', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + apiKey: 'abcd=', + apiVersion: 'v1', + appId: 'asdasdasd', collectContext: false, - sendAnonymousId: false, }, }, + metadata: { + jobId: 30, + }, }, ], }, @@ -1793,15 +3409,40 @@ export const data = [ status: 200, body: [ { - statusCode: 400, - error: 'Either of `email` or `userId` is required for Identify call', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'INTERCOM', - module: 'destination', - implementation: 'native', - feature: 'processor', + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.intercom.io/companies', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer abcd=', + Accept: 'application/json', + 'Intercom-Version': '1.4', + }, + params: {}, + body: { + JSON: { + company_id: 'test_company_id', + name: 'rudderUpdate', + plan: 'basic', + size: 50, + industry: 'IT', + monthly_spend: 2131231, + custom_attributes: { + email: 'comanyemail@abc.com', + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '12312312', + }, + statusCode: 200, + metadata: { + jobId: 30, }, }, ], @@ -1810,7 +3451,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 14', + description: 'Old version : successful group call', feature: 'processor', module: 'destination', version: 'v0', @@ -1820,14 +3461,19 @@ export const data = [ { message: { groupId: 'test_company_id_wdasda', + context: { + traits: { + email: 'testUser@test.com', + }, + }, traits: { employees: 450, plan: 'basic', - userId: 'sdfrsdfsdfsf', email: 'test@test.com', name: 'rudderUpdate', size: '50', industry: 'IT', + website: 'url', monthlySpend: '2131231', remoteCreatedAt: '1683017572', key1: 'val1', @@ -1840,12 +3486,21 @@ export const data = [ userId: 'sdfrsdfsdfsf', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'abcd=', + apiVersion: 'v1', appId: 'asdasdasd', collectContext: false, }, }, + metadata: { + jobId: 31, + }, }, ], }, @@ -1873,6 +3528,7 @@ export const data = [ name: 'rudderUpdate', plan: 'basic', size: 50, + website: 'url', industry: 'IT', monthly_spend: 2131231, remote_created_at: 1683017572, @@ -1890,6 +3546,9 @@ export const data = [ userId: 'sdfrsdfsdfsf', }, statusCode: 200, + metadata: { + jobId: 31, + }, }, { output: { @@ -1907,6 +3566,7 @@ export const data = [ body: { JSON: { user_id: 'sdfrsdfsdfsf', + email: 'testUser@test.com', companies: [ { company_id: 'test_company_id_wdasda', @@ -1922,6 +3582,9 @@ export const data = [ userId: 'sdfrsdfsdfsf', }, statusCode: 200, + metadata: { + jobId: 31, + }, }, ], }, @@ -1929,7 +3592,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 15', + description: 'Old version : successful group call', feature: 'processor', module: 'destination', version: 'v0', @@ -1938,66 +3601,53 @@ export const data = [ body: [ { message: { - groupId: 'test_company_id', + groupId: 'test_company_id_wdasda', + context: { + traits: { + email: 'testUser@test.com', + }, + }, traits: { + employees: 450, plan: 'basic', + email: 'test@test.com', name: 'rudderUpdate', - size: 50, + size: '50', industry: 'IT', + website: 'url', monthlySpend: '2131231', - email: 'comanyemail@abc.com', - }, - anonymousId: '12312312', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, + remoteCreatedAt: '1683017572', + key1: 'val1', + key2: { + a: 'a', + b: 'b', }, - timezone: 'Asia/Kolkata', - userAgent: 'unknown', + key3: [1, 2, 3], + key4: null, }, + anonymousId: 'anonId', integrations: { All: true, }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', type: 'group', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { apiKey: 'abcd=', appId: 'asdasdasd', + apiVersion: 'v1', collectContext: false, + sendAnonymousId: true, }, }, + metadata: { + jobId: 32, + }, }, ], }, @@ -2021,14 +3671,24 @@ export const data = [ params: {}, body: { JSON: { - company_id: 'test_company_id', + company_id: 'test_company_id_wdasda', name: 'rudderUpdate', plan: 'basic', size: 50, + website: 'url', industry: 'IT', monthly_spend: 2131231, + remote_created_at: 1683017572, custom_attributes: { - email: 'comanyemail@abc.com', + employees: 450, + email: 'test@test.com', + key1: 'val1', + 'key2.a': 'a', + 'key2.b': 'b', + 'key3[0]': 1, + 'key3[1]': 2, + 'key3[2]': 3, + key4: null, }, }, JSON_ARRAY: {}, @@ -2036,9 +3696,48 @@ export const data = [ FORM: {}, }, files: {}, - userId: '12312312', + userId: 'anonId', + }, + statusCode: 200, + metadata: { + jobId: 32, + }, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.intercom.io/users', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer abcd=', + Accept: 'application/json', + 'Intercom-Version': '1.4', + }, + params: {}, + body: { + JSON: { + user_id: 'anonId', + email: 'testUser@test.com', + companies: [ + { + company_id: 'test_company_id_wdasda', + name: 'rudderUpdate', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: 'anonId', }, statusCode: 200, + metadata: { + jobId: 32, + }, }, ], }, @@ -2046,7 +3745,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 16', + description: 'Test 0', feature: 'processor', module: 'destination', version: 'v0', @@ -2055,35 +3754,89 @@ export const data = [ body: [ { message: { - groupId: 'test_company_id_wdasda', + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + channel: 'mobile', context: { + app: { + build: '1.0', + name: 'Test_Example', + namespace: 'com.example.testapp', + version: '1.0', + }, + device: { + id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + manufacturer: 'Apple', + model: 'iPhone', + name: 'iPod touch (7th generation)', + type: 'iOS', + }, + library: { + name: 'test-ios-library', + version: '1.0.7', + }, + locale: 'en-US', + network: { + bluetooth: false, + carrier: 'unavailable', + cellular: false, + wifi: true, + }, + os: { + name: 'iOS', + version: '14.0', + }, + screen: { + density: 2, + height: 320, + width: 568, + }, + timezone: 'Asia/Kolkata', traits: { - email: 'testUser@test.com', + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + name: 'Test Name', + firstName: 'Test', + lastName: 'Name', + createdAt: '2020-09-30T19:11:00.337Z', + userId: 'test_user_id_1', + email: 'test_1@test.com', + phone: '9876543210', + key1: 'value1', + address: { + city: 'Kolkata', + state: 'West Bengal', + }, + originalArray: [ + { + nested_field: 'nested value', + tags: ['tag_1', 'tag_2', 'tag_3'], + }, + { + nested_field: 'nested value', + tags: ['tag_1'], + }, + { + nested_field: 'nested value', + }, + ], }, + userAgent: 'unknown', }, - traits: { - employees: 450, - plan: 'basic', - email: 'test@test.com', - name: 'rudderUpdate', - size: '50', - industry: 'IT', - website: 'url', - monthlySpend: '2131231', - remoteCreatedAt: '1683017572', - key1: 'val1', - }, - anonymousId: 'sdfrsdfsdfsf', + event: 'Test Event 2', integrations: { All: true, }, - type: 'group', - userId: 'sdfrsdfsdfsf', + messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', + originalTimestamp: '2020-09-30T19:11:00.337Z', + receivedAt: '2020-10-01T00:41:11.369+05:30', + request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', + sentAt: '2020-09-30T19:11:10.382Z', + timestamp: '2020-10-01T00:41:01.324+05:30', + type: 'identify', }, destination: { Config: { - apiKey: 'abcd=', - appId: 'asdasdasd', + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, }, }, @@ -2093,46 +3846,8 @@ export const data = [ }, output: { response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/companies', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer abcd=', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - company_id: 'test_company_id_wdasda', - name: 'rudderUpdate', - plan: 'basic', - size: 50, - website: 'url', - industry: 'IT', - monthly_spend: 2131231, - remote_created_at: 1683017572, - custom_attributes: { - employees: 450, - email: 'test@test.com', - key1: 'val1', - }, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: 'sdfrsdfsdfsf', - }, - statusCode: 200, - }, + status: 200, + body: [ { output: { version: '1', @@ -2141,28 +3856,40 @@ export const data = [ endpoint: 'https://api.intercom.io/users', headers: { 'Content-Type': 'application/json', - Authorization: 'Bearer abcd=', + Authorization: 'Bearer intercomApiKey', Accept: 'application/json', 'Intercom-Version': '1.4', }, params: {}, body: { JSON: { - user_id: 'sdfrsdfsdfsf', - email: 'testUser@test.com', - companies: [ - { - company_id: 'test_company_id_wdasda', - name: 'rudderUpdate', - }, - ], + user_id: 'test_user_id_1', + email: 'test_1@test.com', + phone: '9876543210', + name: 'Test Name', + signed_up_at: 1601493060, + last_seen_user_agent: 'unknown', + custom_attributes: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + key1: 'value1', + 'address.city': 'Kolkata', + 'address.state': 'West Bengal', + 'originalArray[0].nested_field': 'nested value', + 'originalArray[0].tags[0]': 'tag_1', + 'originalArray[0].tags[1]': 'tag_2', + 'originalArray[0].tags[2]': 'tag_3', + 'originalArray[1].nested_field': 'nested value', + 'originalArray[1].tags[0]': 'tag_1', + 'originalArray[2].nested_field': 'nested value', + }, + update_last_request_at: true, }, JSON_ARRAY: {}, XML: {}, FORM: {}, }, files: {}, - userId: 'sdfrsdfsdfsf', + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, statusCode: 200, }, @@ -2172,7 +3899,7 @@ export const data = [ }, { name: 'intercom', - description: 'Test 17', + description: 'Test 1', feature: 'processor', module: 'destination', version: 'v0', @@ -2181,42 +3908,71 @@ export const data = [ body: [ { message: { - groupId: 'test_company_id_wdasda', + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + channel: 'mobile', context: { - traits: { - email: 'testUser@test.com', + app: { + build: '1.0', + name: 'Test_Example', + namespace: 'com.example.testapp', + version: '1.0', }, - }, - traits: { - employees: 450, - plan: 'basic', - email: 'test@test.com', - name: 'rudderUpdate', - size: '50', - industry: 'IT', - website: 'url', - monthlySpend: '2131231', - remoteCreatedAt: '1683017572', - key1: 'val1', - key2: { - a: 'a', - b: 'b', + device: { + id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + manufacturer: 'Apple', + model: 'iPhone', + name: 'iPod touch (7th generation)', + type: 'iOS', }, - key3: [1, 2, 3], - key4: null, + library: { + name: 'test-ios-library', + version: '1.0.7', + }, + locale: 'en-US', + network: { + bluetooth: false, + carrier: 'unavailable', + cellular: false, + wifi: true, + }, + os: { + name: 'iOS', + version: '14.0', + }, + screen: { + density: 2, + height: 320, + width: 568, + }, + timezone: 'Asia/Kolkata', + traits: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + firstName: 'Test', + lastName: 'Name', + createdAt: '2020-09-30T19:11:00.337Z', + email: 'test_1@test.com', + phone: '9876543210', + key1: 'value1', + }, + userAgent: 'unknown', }, - anonymousId: 'anonId', + event: 'Test Event 2', integrations: { All: true, }, - type: 'group', + messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', + originalTimestamp: '2020-09-30T19:11:00.337Z', + receivedAt: '2020-10-01T00:41:11.369+05:30', + request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', + sentAt: '2020-09-30T19:11:10.382Z', + timestamp: '2020-10-01T00:41:01.324+05:30', + type: 'identify', }, destination: { Config: { - apiKey: 'abcd=', - appId: 'asdasdasd', + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', collectContext: false, - sendAnonymousId: true, }, }, }, @@ -2232,45 +3988,125 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.intercom.io/companies', + endpoint: 'https://api.intercom.io/users', headers: { 'Content-Type': 'application/json', - Authorization: 'Bearer abcd=', + Authorization: 'Bearer intercomApiKey', Accept: 'application/json', 'Intercom-Version': '1.4', }, params: {}, body: { JSON: { - company_id: 'test_company_id_wdasda', - name: 'rudderUpdate', - plan: 'basic', - size: 50, - website: 'url', - industry: 'IT', - monthly_spend: 2131231, - remote_created_at: 1683017572, + email: 'test_1@test.com', + phone: '9876543210', + signed_up_at: 1601493060, + last_seen_user_agent: 'unknown', custom_attributes: { - employees: 450, - email: 'test@test.com', - key1: 'val1', - 'key2.a': 'a', - 'key2.b': 'b', - 'key3[0]': 1, - 'key3[1]': 2, - 'key3[2]': 3, - key4: null, + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + key1: 'value1', }, + update_last_request_at: true, + name: 'Test Name', }, JSON_ARRAY: {}, XML: {}, FORM: {}, }, files: {}, - userId: 'anonId', + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, statusCode: 200, }, + ], + }, + }, + }, + { + name: 'intercom', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + channel: 'mobile', + context: { + app: { + build: '1.0', + name: 'Test_Example', + namespace: 'com.example.testapp', + version: '1.0', + }, + device: { + id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + manufacturer: 'Apple', + model: 'iPhone', + name: 'iPod touch (7th generation)', + type: 'iOS', + }, + library: { + name: 'test-ios-library', + version: '1.0.7', + }, + locale: 'en-US', + network: { + bluetooth: false, + carrier: 'unavailable', + cellular: false, + wifi: true, + }, + os: { + name: 'iOS', + version: '14.0', + }, + screen: { + density: 2, + height: 320, + width: 568, + }, + timezone: 'Asia/Kolkata', + traits: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + lastName: 'Name', + createdAt: '2020-09-30T19:11:00.337Z', + email: 'test_1@test.com', + phone: '9876543210', + key1: 'value1', + }, + userAgent: 'unknown', + }, + event: 'Test Event 2', + integrations: { + All: true, + }, + messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', + originalTimestamp: '2020-09-30T19:11:00.337Z', + receivedAt: '2020-10-01T00:41:11.369+05:30', + request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', + sentAt: '2020-09-30T19:11:10.382Z', + timestamp: '2020-10-01T00:41:01.324+05:30', + type: 'identify', + }, + destination: { + Config: { + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ { output: { version: '1', @@ -2279,28 +4115,30 @@ export const data = [ endpoint: 'https://api.intercom.io/users', headers: { 'Content-Type': 'application/json', - Authorization: 'Bearer abcd=', + Authorization: 'Bearer intercomApiKey', Accept: 'application/json', 'Intercom-Version': '1.4', }, params: {}, body: { JSON: { - user_id: 'anonId', - email: 'testUser@test.com', - companies: [ - { - company_id: 'test_company_id_wdasda', - name: 'rudderUpdate', - }, - ], + email: 'test_1@test.com', + phone: '9876543210', + signed_up_at: 1601493060, + last_seen_user_agent: 'unknown', + custom_attributes: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + key1: 'value1', + }, + update_last_request_at: true, + name: 'Name', }, JSON_ARRAY: {}, XML: {}, FORM: {}, }, files: {}, - userId: 'anonId', + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, statusCode: 200, }, diff --git a/test/integrations/destinations/intercom/router/data.ts b/test/integrations/destinations/intercom/router/data.ts index 766161bac89..2ce8621ca17 100644 --- a/test/integrations/destinations/intercom/router/data.ts +++ b/test/integrations/destinations/intercom/router/data.ts @@ -1,4 +1,379 @@ export const data = [ + { + name: 'intercom', + description: 'Intercom router tests', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + userId: 'user@1', + channel: 'web', + context: { + traits: { + age: 23, + email: 'test@rudderlabs.com', + phone: '+91 9999999999', + firstName: 'Test', + lastName: 'Rudderlabs', + address: 'california usa', + ownerId: '13', + }, + }, + type: 'identify', + integrations: { All: true }, + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiServer: 'standard', + apiVersion: 'v2', + sendAnonymousId: false, + updateLastRequestAt: true, + }, + }, + metadata: { jobId: 1 }, + }, + { + message: { + userId: 'user@3', + channel: 'web', + context: { + traits: { + age: 32, + email: 'test+3@rudderlabs.com', + phone: '+91 9399999999', + firstName: 'Test', + lastName: 'RudderStack', + ownerId: '15', + }, + }, + properties: { + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + price: { + amount: 3000, + currency: 'USD', + }, + }, + event: 'Product Viewed', + type: 'track', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiServer: 'standard', + apiVersion: 'v2', + sendAnonymousId: false, + updateLastRequestAt: false, + }, + }, + metadata: { + jobId: 2, + }, + }, + { + message: { + userId: 'user@5', + groupId: 'rudderlabs', + channel: 'web', + context: { + traits: { + email: 'test+5@rudderlabs.com', + phone: '+91 9599999999', + firstName: 'John', + lastName: 'Snow', + ownerId: '17', + }, + }, + traits: { + name: 'RudderStack', + size: 500, + website: 'www.rudderstack.com', + industry: 'CDP', + plan: 'enterprise', + }, + type: 'group', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'eu', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 3, + }, + }, + { + message: { + userId: 'user@6', + groupId: 'rudderlabs', + channel: 'web', + context: { + traits: { + email: 'test+5@rudderlabs.com', + phone: '+91 9599999999', + firstName: 'John', + lastName: 'Snow', + ownerId: '17', + }, + }, + traits: { + name: 'RudderStack', + size: 500, + website: 'www.rudderstack.com', + industry: 'CDP', + plan: 'enterprise', + isOpenSource: true, + }, + type: 'group', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'eu', + sendAnonymousId: false, + }, + }, + metadata: { + jobId: 4, + }, + }, + ], + destType: 'intercom', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batched: false, + batchedRequest: { + body: { + JSON: { + email: 'test@rudderlabs.com', + external_id: 'user@1', + name: 'Test Rudderlabs', + owner_id: 13, + phone: '+91 9999999999', + custom_attributes: { + address: 'california usa', + age: 23, + }, + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://api.intercom.io/contacts', + files: {}, + headers: { + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + Accept: 'application/json', + 'Intercom-Version': '2.10', + }, + method: 'POST', + params: {}, + type: 'REST', + version: '1', + }, + destination: { + Config: { + apiKey: 'testApiKey', + apiServer: 'standard', + apiVersion: 'v2', + sendAnonymousId: false, + updateLastRequestAt: true, + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: [{ jobId: 1 }], + statusCode: 200, + }, + { + batched: false, + batchedRequest: { + body: { + FORM: {}, + JSON: { + created_at: 1700628164, + email: 'test+3@rudderlabs.com', + event_name: 'Product Viewed', + metadata: { + price: { + amount: 3000, + currency: 'USD', + }, + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + }, + user_id: 'user@3', + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://api.intercom.io/events', + files: {}, + headers: { + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + Accept: 'application/json', + 'Intercom-Version': '2.10', + }, + method: 'POST', + params: {}, + type: 'REST', + version: '1', + }, + destination: { + Config: { + apiKey: 'testApiKey', + apiServer: 'standard', + apiVersion: 'v2', + sendAnonymousId: false, + updateLastRequestAt: false, + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: [{ jobId: 2 }], + statusCode: 200, + }, + { + batched: false, + batchedRequest: { + body: { + JSON: { + id: '657264e9018c0a647s45', + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://api.eu.intercom.io/contacts/70701240741e45d040/companies', + files: {}, + headers: { + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + Accept: 'application/json', + 'Intercom-Version': '2.10', + }, + method: 'POST', + params: {}, + type: 'REST', + version: '1', + }, + destination: { + Config: { + apiKey: 'testApiKey', + apiServer: 'eu', + apiVersion: 'v2', + sendAnonymousId: false, + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: [ + { + jobId: 3, + }, + ], + statusCode: 200, + }, + { + batched: false, + error: + '{"message":"Unable to Create or Update Company due to : [{\\"code\\":\\"parameter_invalid\\",\\"message\\":\\"Custom attribute \'isOpenSource\' does not exist\\"}]","destinationResponse":{"response":{"type":"error.list","request_id":"request_1","errors":[{"code":"parameter_invalid","message":"Custom attribute \'isOpenSource\' does not exist"}]},"status":401}}', + statTags: { + destType: 'INTERCOM', + errorCategory: 'network', + errorType: 'aborted', + feature: 'router', + implementation: 'cdkV2', + module: 'destination', + }, + destination: { + Config: { + apiKey: 'testApiKey', + apiServer: 'eu', + apiVersion: 'v2', + sendAnonymousId: false, + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: [ + { + jobId: 4, + }, + ], + statusCode: 401, + }, + ], + }, + }, + }, + }, { name: 'intercom', description: 'Test 0', @@ -27,7 +402,10 @@ export const data = [ name: 'iPod touch (7th generation)', type: 'iOS', }, - library: { name: 'test-ios-library', version: '1.0.7' }, + library: { + name: 'test-ios-library', + version: '1.0.7', + }, locale: 'en-US', network: { bluetooth: false, @@ -35,8 +413,15 @@ export const data = [ cellular: false, wifi: true, }, - os: { name: 'iOS', version: '14.0' }, - screen: { density: 2, height: 320, width: 568 }, + os: { + name: 'iOS', + version: '14.0', + }, + screen: { + density: 2, + height: 320, + width: 568, + }, timezone: 'Asia/Kolkata', traits: { anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', @@ -52,7 +437,9 @@ export const data = [ userAgent: 'unknown', }, event: 'Test Event 2', - integrations: { All: true }, + integrations: { + All: true, + }, messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', originalTimestamp: '2020-09-30T19:11:00.337Z', receivedAt: '2020-10-01T00:41:11.369+05:30', @@ -61,11 +448,20 @@ export const data = [ timestamp: '2020-10-01T00:41:01.324+05:30', type: 'identify', }, - metadata: { jobId: 1, userId: 'u1' }, + metadata: { + jobId: 1, + }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { - apiKey: 'intercomApiKey', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + apiKey: 'testApiKey', + apiVersion: 'v1', + sendAnonymousId: false, + updateLastRequestAt: false, collectContext: false, }, }, @@ -88,7 +484,10 @@ export const data = [ name: 'iPod touch (7th generation)', type: 'iOS', }, - library: { name: 'test-ios-library', version: '1.0.7' }, + library: { + name: 'test-ios-library', + version: '1.0.7', + }, locale: 'en-US', network: { bluetooth: false, @@ -96,8 +495,15 @@ export const data = [ cellular: false, wifi: true, }, - os: { name: 'iOS', version: '14.0' }, - screen: { density: 2, height: 320, width: 568 }, + os: { + name: 'iOS', + version: '14.0', + }, + screen: { + density: 2, + height: 320, + width: 568, + }, timezone: 'Asia/Kolkata', traits: { anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', @@ -111,7 +517,9 @@ export const data = [ userAgent: 'unknown', }, event: 'Test Event 2', - integrations: { All: true }, + integrations: { + All: true, + }, messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', originalTimestamp: '2020-09-30T19:11:00.337Z', receivedAt: '2020-10-01T00:41:11.369+05:30', @@ -120,15 +528,66 @@ export const data = [ timestamp: '2020-10-01T00:41:01.324+05:30', type: 'identify', }, - metadata: { jobId: 2, userId: 'u1' }, + metadata: { + jobId: 2, + }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { - apiKey: 'intercomApiKey', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + apiKey: 'testApiKey', + apiVersion: 'v1', + sendAnonymousId: false, + updateLastRequestAt: false, collectContext: false, }, }, }, + { + message: { + userId: 'user@5', + groupId: 'rudderlabs', + channel: 'web', + context: { + traits: { + email: 'test+5@rudderlabs.com', + phone: '+91 9599999999', + firstName: 'John', + lastName: 'Snow', + ownerId: '17', + }, + }, + traits: { + name: 'RudderStack', + size: 500, + website: 'www.rudderstack.com', + industry: 'CDP', + plan: 'enterprise', + }, + type: 'group', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v1', + sendAnonymousId: false, + collectContext: false, + }, + }, + metadata: { + jobId: 3, + }, + }, ], destType: 'intercom', }, @@ -147,7 +606,7 @@ export const data = [ endpoint: 'https://api.intercom.io/users', headers: { 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', + Authorization: 'Bearer testApiKey', Accept: 'application/json', 'Intercom-Version': '1.4', }, @@ -159,7 +618,7 @@ export const data = [ name: 'Test Name', signed_up_at: 1601493060, last_seen_user_agent: 'unknown', - update_last_request_at: true, + update_last_request_at: false, user_id: 'test_user_id_1', custom_attributes: { anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', @@ -173,14 +632,25 @@ export const data = [ files: {}, userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, - metadata: [{ jobId: 1, userId: 'u1' }], + metadata: [ + { + jobId: 1, + }, + ], batched: false, statusCode: 200, destination: { Config: { - apiKey: 'intercomApiKey', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + apiKey: 'testApiKey', + apiVersion: 'v1', collectContext: false, + sendAnonymousId: false, + updateLastRequestAt: false, + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, }, }, }, @@ -192,7 +662,7 @@ export const data = [ endpoint: 'https://api.intercom.io/users', headers: { 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', + Authorization: 'Bearer testApiKey', Accept: 'application/json', 'Intercom-Version': '1.4', }, @@ -204,7 +674,7 @@ export const data = [ signed_up_at: 1601493060, name: 'Test Name', last_seen_user_agent: 'unknown', - update_last_request_at: true, + update_last_request_at: false, custom_attributes: { anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', key1: 'value1', @@ -217,17 +687,498 @@ export const data = [ files: {}, userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', }, - metadata: [{ jobId: 2, userId: 'u1' }], + metadata: [ + { + jobId: 2, + }, + ], batched: false, statusCode: 200, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, Config: { - apiKey: 'intercomApiKey', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + apiKey: 'testApiKey', + apiVersion: 'v1', collectContext: false, + sendAnonymousId: false, + updateLastRequestAt: false, }, }, }, + { + batched: false, + batchedRequest: [ + { + body: { + FORM: {}, + JSON: { + company_id: 'rudderlabs', + industry: 'CDP', + name: 'RudderStack', + plan: 'enterprise', + size: 500, + website: 'www.rudderstack.com', + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://api.intercom.io/companies', + files: {}, + headers: { + Accept: 'application/json', + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + 'Intercom-Version': '1.4', + }, + method: 'POST', + params: {}, + type: 'REST', + version: '1', + }, + { + body: { + FORM: {}, + JSON: { + companies: [ + { + company_id: 'rudderlabs', + name: 'RudderStack', + }, + ], + email: 'test+5@rudderlabs.com', + user_id: 'user@5', + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://api.intercom.io/users', + files: {}, + headers: { + Accept: 'application/json', + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + 'Intercom-Version': '1.4', + }, + method: 'POST', + params: {}, + type: 'REST', + version: '1', + }, + ], + destination: { + Config: { + apiKey: 'testApiKey', + apiVersion: 'v1', + collectContext: false, + sendAnonymousId: false, + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: [ + { + jobId: 3, + }, + ], + statusCode: 200, + }, + ], + }, + }, + }, + }, + { + name: 'intercom', + description: 'Test 0', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + channel: 'mobile', + context: { + app: { + build: '1.0', + name: 'Test_Example', + namespace: 'com.example.testapp', + version: '1.0', + }, + device: { + id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + manufacturer: 'Apple', + model: 'iPhone', + name: 'iPod touch (7th generation)', + type: 'iOS', + }, + library: { + name: 'test-ios-library', + version: '1.0.7', + }, + locale: 'en-US', + network: { + bluetooth: false, + carrier: 'unavailable', + cellular: false, + wifi: true, + }, + os: { + name: 'iOS', + version: '14.0', + }, + screen: { + density: 2, + height: 320, + width: 568, + }, + timezone: 'Asia/Kolkata', + traits: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + name: 'Test Name', + firstName: 'Test', + lastName: 'Name', + createdAt: '2020-09-30T19:11:00.337Z', + userId: 'test_user_id_1', + email: 'test_1@test.com', + phone: '9876543210', + key1: 'value1', + }, + userAgent: 'unknown', + }, + event: 'Test Event 2', + integrations: { + All: true, + }, + messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', + originalTimestamp: '2020-09-30T19:11:00.337Z', + receivedAt: '2020-10-01T00:41:11.369+05:30', + request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', + sentAt: '2020-09-30T19:11:10.382Z', + timestamp: '2020-10-01T00:41:01.324+05:30', + type: 'identify', + }, + metadata: { + jobId: 1, + }, + destination: { + Config: { + apiKey: 'testApiKey', + apiVersion: 'v1', + sendAnonymousId: false, + updateLastRequestAt: false, + collectContext: false, + }, + }, + }, + { + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + channel: 'mobile', + context: { + app: { + build: '1.0', + name: 'Test_Example', + namespace: 'com.example.testapp', + version: '1.0', + }, + device: { + id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + manufacturer: 'Apple', + model: 'iPhone', + name: 'iPod touch (7th generation)', + type: 'iOS', + }, + library: { + name: 'test-ios-library', + version: '1.0.7', + }, + locale: 'en-US', + network: { + bluetooth: false, + carrier: 'unavailable', + cellular: false, + wifi: true, + }, + os: { + name: 'iOS', + version: '14.0', + }, + screen: { + density: 2, + height: 320, + width: 568, + }, + timezone: 'Asia/Kolkata', + traits: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + firstName: 'Test', + lastName: 'Name', + createdAt: '2020-09-30T19:11:00.337Z', + email: 'test_1@test.com', + phone: '9876543210', + key1: 'value1', + }, + userAgent: 'unknown', + }, + event: 'Test Event 2', + integrations: { + All: true, + }, + messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', + originalTimestamp: '2020-09-30T19:11:00.337Z', + receivedAt: '2020-10-01T00:41:11.369+05:30', + request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', + sentAt: '2020-09-30T19:11:10.382Z', + timestamp: '2020-10-01T00:41:01.324+05:30', + type: 'identify', + }, + metadata: { + jobId: 2, + }, + destination: { + Config: { + apiKey: 'testApiKey', + apiVersion: 'v1', + sendAnonymousId: false, + updateLastRequestAt: false, + collectContext: false, + }, + }, + }, + { + message: { + userId: 'user@5', + groupId: 'rudderlabs', + channel: 'web', + context: { + traits: { + email: 'test+5@rudderlabs.com', + phone: '+91 9599999999', + firstName: 'John', + lastName: 'Snow', + ownerId: '17', + }, + }, + traits: { + name: 'RudderStack', + size: 500, + website: 'www.rudderstack.com', + industry: 'CDP', + plan: 'enterprise', + }, + type: 'group', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + Config: { + apiKey: 'testApiKey', + apiVersion: 'v1', + sendAnonymousId: false, + collectContext: false, + }, + }, + metadata: { + jobId: 3, + }, + }, + ], + destType: 'intercom', + }, + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.intercom.io/users', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer testApiKey', + Accept: 'application/json', + 'Intercom-Version': '1.4', + }, + params: {}, + body: { + JSON: { + email: 'test_1@test.com', + phone: '9876543210', + name: 'Test Name', + signed_up_at: 1601493060, + last_seen_user_agent: 'unknown', + update_last_request_at: false, + user_id: 'test_user_id_1', + custom_attributes: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + key1: 'value1', + }, + }, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + }, + metadata: [ + { + jobId: 1, + }, + ], + batched: false, + statusCode: 200, + destination: { + Config: { + apiKey: 'testApiKey', + apiVersion: 'v1', + collectContext: false, + sendAnonymousId: false, + updateLastRequestAt: false, + }, + }, + }, + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.intercom.io/users', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer testApiKey', + Accept: 'application/json', + 'Intercom-Version': '1.4', + }, + params: {}, + body: { + JSON: { + email: 'test_1@test.com', + phone: '9876543210', + signed_up_at: 1601493060, + name: 'Test Name', + last_seen_user_agent: 'unknown', + update_last_request_at: false, + custom_attributes: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + key1: 'value1', + }, + }, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + }, + metadata: [ + { + jobId: 2, + }, + ], + batched: false, + statusCode: 200, + destination: { + Config: { + apiKey: 'testApiKey', + apiVersion: 'v1', + collectContext: false, + sendAnonymousId: false, + updateLastRequestAt: false, + }, + }, + }, + { + batched: false, + batchedRequest: [ + { + body: { + FORM: {}, + JSON: { + company_id: 'rudderlabs', + industry: 'CDP', + name: 'RudderStack', + plan: 'enterprise', + size: 500, + website: 'www.rudderstack.com', + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://api.intercom.io/companies', + files: {}, + headers: { + Accept: 'application/json', + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + 'Intercom-Version': '1.4', + }, + method: 'POST', + params: {}, + type: 'REST', + version: '1', + }, + { + body: { + FORM: {}, + JSON: { + companies: [ + { + company_id: 'rudderlabs', + name: 'RudderStack', + }, + ], + email: 'test+5@rudderlabs.com', + user_id: 'user@5', + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://api.intercom.io/users', + files: {}, + headers: { + Accept: 'application/json', + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + 'Intercom-Version': '1.4', + }, + method: 'POST', + params: {}, + type: 'REST', + version: '1', + }, + ], + destination: { + Config: { + apiKey: 'testApiKey', + apiVersion: 'v1', + collectContext: false, + sendAnonymousId: false, + }, + }, + metadata: [ + { + jobId: 3, + }, + ], + statusCode: 200, + }, ], }, }, diff --git a/test/integrations/destinations/iterable/deleteUsers/data.ts b/test/integrations/destinations/iterable/deleteUsers/data.ts new file mode 100644 index 00000000000..79d801f4eee --- /dev/null +++ b/test/integrations/destinations/iterable/deleteUsers/data.ts @@ -0,0 +1,186 @@ +const destType = 'iterable'; + +export const data = [ + { + name: destType, + description: 'Test 0: should fail when config is not being sent', + feature: 'userDeletion', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destType: destType.toUpperCase(), + userAttributes: [ + { + userId: 'rudder1', + }, + ], + }, + ], + }, + }, + output: { + response: { + status: 400, + body: [ + { + statusCode: 400, + error: 'Config for deletion not present', + }, + ], + }, + }, + }, + { + name: destType, + description: 'Test 1: should fail when apiKey is not present in config', + feature: 'userDeletion', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destType: destType.toUpperCase(), + userAttributes: [ + { + userId: 'rudder2', + }, + ], + config: { + apiToken: 'dummyApiKey', + }, + }, + ], + }, + }, + output: { + response: { + status: 400, + body: [ + { + statusCode: 400, + error: 'api key for deletion not present', + }, + ], + }, + }, + }, + { + name: destType, + description: 'Test 2: should fail when one of the user-deletion requests fails', + feature: 'userDeletion', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destType: destType.toUpperCase(), + userAttributes: [ + { + userId: 'rudder1', + }, + { + userId: 'rudder2', + }, + ], + config: { + apiKey: 'dummyApiKey', + }, + }, + ], + }, + }, + output: { + response: { + status: 400, + body: [ + { + statusCode: 400, + error: + 'User deletion request failed for userIds : [{"userId":"rudder2","Reason":"User does not exist. Email: UserId: rudder2"}]', + }, + ], + }, + }, + }, + { + name: destType, + description: 'Test 3: should fail when invalid api key is set in config', + feature: 'userDeletion', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destType: destType.toUpperCase(), + userAttributes: [ + { + userId: 'rudder3', + }, + { + userId: 'rudder4', + }, + ], + config: { + apiKey: 'invalidKey', + }, + }, + ], + }, + }, + output: { + response: { + status: 401, + body: [ + { + error: 'User deletion request failed : Invalid API key', + statusCode: 401, + }, + ], + }, + }, + }, + { + name: destType, + description: 'Test 4: should pass when proper apiKey & valid users are sent to destination', + feature: 'userDeletion', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destType: destType.toUpperCase(), + userAttributes: [ + { + userId: 'rudder5', + }, + { + userId: 'rudder6', + }, + ], + config: { + apiKey: 'dummyApiKey', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 200, + status: 'successful', + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/iterable/network.ts b/test/integrations/destinations/iterable/network.ts new file mode 100644 index 00000000000..39544b26477 --- /dev/null +++ b/test/integrations/destinations/iterable/network.ts @@ -0,0 +1,109 @@ +const deleteNwData = [ + { + httpReq: { + method: 'delete', + url: 'https://api.iterable.com/api/users/byUserId/rudder1', + headers: { + api_key: 'dummyApiKey', + }, + }, + httpRes: { + data: { + msg: 'All users associated with rudder1 were successfully deleted', + code: 'Success', + params: null, + }, + status: 200, + }, + }, + { + httpReq: { + method: 'delete', + url: 'https://api.iterable.com/api/users/byUserId/rudder2', + headers: { + api_key: 'dummyApiKey', + }, + }, + httpRes: { + data: { + msg: 'User does not exist. Email: UserId: rudder2', + code: 'BadParams', + params: null, + }, + status: 400, + }, + }, + { + httpReq: { + method: 'delete', + url: 'https://api.iterable.com/api/users/byUserId/rudder3', + headers: { + api_key: 'invalidKey', + }, + }, + httpRes: { + data: { + msg: 'Invalid API key', + code: 'Success', + params: { + endpoint: '/api/users/byUserId/rudder3', + }, + }, + status: 401, + }, + }, + { + httpReq: { + method: 'delete', + url: 'https://api.iterable.com/api/users/byUserId/rudder4', + headers: { + api_key: 'invalidKey', + }, + }, + httpRes: { + data: { + msg: 'Invalid API key', + code: 'Success', + params: { + endpoint: '/api/users/byUserId/rudder4', + }, + }, + status: 401, + }, + }, + { + httpReq: { + method: 'delete', + url: 'https://api.iterable.com/api/users/byUserId/rudder5', + headers: { + api_key: 'dummyApiKey', + }, + }, + httpRes: { + data: { + msg: 'All users associated with rudder6 were successfully deleted', + code: 'Success', + params: null, + }, + status: 200, + }, + }, + { + httpReq: { + method: 'delete', + url: 'https://api.iterable.com/api/users/byUserId/rudder6', + headers: { + api_key: 'dummyApiKey', + }, + }, + httpRes: { + data: { + msg: 'All users associated with rudder6 were successfully deleted', + code: 'Success', + params: null, + }, + status: 200, + }, + }, +]; +export const networkCallsData = [...deleteNwData]; diff --git a/test/integrations/destinations/klaviyo/network.ts b/test/integrations/destinations/klaviyo/network.ts index aa788a60dad..d76d235c6f3 100644 --- a/test/integrations/destinations/klaviyo/network.ts +++ b/test/integrations/destinations/klaviyo/network.ts @@ -1,75 +1,73 @@ export const networkCallsData = [ - { - httpReq: { - url: 'https://a.klaviyo.com/api/v2/list/XUepkK/subscribe', - method: 'GET', - }, - httpRes: { - status: 200 - }, + { + httpReq: { + url: 'https://a.klaviyo.com/api/v2/list/XUepkK/subscribe', + method: 'GET', }, - { - httpReq: { - url: 'https://a.klaviyo.com/api/v2/list/XUepkK/members', - method: 'GET', - }, - httpRes: { - status: 200 - }, + httpRes: { + status: 200, }, - { - httpReq: { - url: 'https://a.klaviyo.com/api/profiles', - method: 'GET', - data: { - attributes: { - email: "test3@rudderstack.com" - } - } - }, - httpRes: { - status: 409, - data: { - } - }, + }, + { + httpReq: { + url: 'https://a.klaviyo.com/api/v2/list/XUepkK/members', + method: 'GET', }, - { - httpReq: { - url: 'https://a.klaviyo.com/api/profiles', - method: 'GET', - }, - httpRes: { - status: 201, - data: { - data: { - id: '01GW3PHVY0MTCDGS0A1612HARX', - attributes: {} - }, - } - }, + httpRes: { + status: 200, }, - { - httpReq: { - url: 'https://a.klaviyo.com/api/profiles', - method: 'POST', - headers: { Authorization: 'Klaviyo-API-Key dummyPrivateApiKeyforfailure' } - }, - httpRes: { + }, + { + httpReq: { + url: 'https://a.klaviyo.com/api/profiles', + method: 'GET', + data: { + attributes: { + email: 'test3@rudderstack.com', }, + }, + }, + httpRes: { + status: 409, + data: {}, }, - { - httpReq: { - url: 'https://a.klaviyo.com/api/profiles', - method: 'POST', + }, + { + httpReq: { + url: 'https://a.klaviyo.com/api/profiles', + method: 'GET', + }, + httpRes: { + status: 201, + data: { + data: { + id: '01GW3PHVY0MTCDGS0A1612HARX', + attributes: {}, }, - httpRes: { - status: 201, - data: { - data: { - id: '01GW3PHVY0MTCDGS0A1612HARX', - attributes: {} - }, - } + }, + }, + }, + { + httpReq: { + url: 'https://a.klaviyo.com/api/profiles', + method: 'POST', + headers: { Authorization: 'Klaviyo-API-Key dummyPrivateApiKeyforfailure' }, + }, + httpRes: {}, + }, + { + httpReq: { + url: 'https://a.klaviyo.com/api/profiles', + method: 'POST', + }, + httpRes: { + status: 201, + data: { + data: { + id: '01GW3PHVY0MTCDGS0A1612HARX', + attributes: {}, }, - } + }, + }, + }, ]; diff --git a/test/integrations/destinations/klaviyo/processor/ecomTestData.ts b/test/integrations/destinations/klaviyo/processor/ecomTestData.ts index fab4cf85cec..34eff45232a 100644 --- a/test/integrations/destinations/klaviyo/processor/ecomTestData.ts +++ b/test/integrations/destinations/klaviyo/processor/ecomTestData.ts @@ -1,10 +1,23 @@ -import { overrideDestination, transformResultBuilder } from '../../../testUtils'; +import { overrideDestination, transformResultBuilder, generateMetadata } from '../../../testUtils'; +import { ProcessorTestData } from '../../../testTypes'; +import { Destination } from '../../../../../src/types'; -const destination = { +const destination: Destination = { + ID: '123', + Name: 'klaviyo', + DestinationDefinition: { + ID: '123', + Name: 'klaviyo', + DisplayName: 'klaviyo', + Config: {}, + }, Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey', }, + Enabled: true, + WorkspaceID: '123', + Transformations: [], }; const commonTraits = { @@ -26,7 +39,7 @@ const commonOutputHeaders = { revision: '2023-02-22', }; -export const ecomTestData = [ +export const ecomTestData: ProcessorTestData[] = [ { id: 'klaviyo-ecom-test-1', name: 'klaviyo', @@ -64,6 +77,7 @@ export const ecomTestData = [ anonymousId: '9c6bd77ea9da3e68', originalTimestamp: '2021-01-25T15:32:56.409Z', }, + metadata: generateMetadata(1), }, ], }, @@ -108,6 +122,7 @@ export const ecomTestData = [ userId: '', }), statusCode: 200, + metadata: generateMetadata(1), }, ], }, @@ -170,6 +185,7 @@ export const ecomTestData = [ }, anonymousId: '9c6bd77ea9da3e68', }, + metadata: generateMetadata(2), }, ], }, @@ -220,6 +236,7 @@ export const ecomTestData = [ userId: '', }), statusCode: 200, + metadata: generateMetadata(2), }, ], }, @@ -280,6 +297,7 @@ export const ecomTestData = [ }, originalTimestamp: '2021-01-25T15:32:56.409Z', }, + metadata: generateMetadata(3), }, ], }, @@ -336,6 +354,7 @@ export const ecomTestData = [ userId: '', }), statusCode: 200, + metadata: generateMetadata(3), }, ], }, diff --git a/test/integrations/destinations/klaviyo/processor/groupTestData.ts b/test/integrations/destinations/klaviyo/processor/groupTestData.ts index 031c949c4b4..0002f7ce90e 100644 --- a/test/integrations/destinations/klaviyo/processor/groupTestData.ts +++ b/test/integrations/destinations/klaviyo/processor/groupTestData.ts @@ -1,10 +1,27 @@ -import { generateSimplifiedGroupPayload, transformResultBuilder } from '../../../testUtils'; +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; +import { + generateMetadata, + generateSimplifiedGroupPayload, + transformResultBuilder, +} from '../../../testUtils'; -const destination = { +const destination: Destination = { + ID: '123', + Name: 'klaviyo', + DestinationDefinition: { + ID: '123', + Name: 'klaviyo', + DisplayName: 'klaviyo', + Config: {}, + }, Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey', }, + Enabled: true, + WorkspaceID: '123', + Transformations: [], }; const headers = { @@ -16,7 +33,7 @@ const headers = { const commonEndpoint = 'https://a.klaviyo.com/api/profile-subscription-bulk-create-jobs'; -export const groupTestData = [ +export const groupTestData: ProcessorTestData[] = [ { id: 'klaviyo-group-test-1', name: 'klaviyo', @@ -47,6 +64,7 @@ export const groupTestData = [ }, timestamp: '2020-01-21T00:21:34.208Z', }), + metadata: generateMetadata(1), }, ], }, @@ -74,6 +92,7 @@ export const groupTestData = [ userId: '', }), statusCode: 200, + metadata: generateMetadata(1), }, ], }, @@ -109,6 +128,7 @@ export const groupTestData = [ }, timestamp: '2020-01-21T00:21:34.208Z', }), + metadata: generateMetadata(2), }, ], }, @@ -126,8 +146,11 @@ export const groupTestData = [ feature: 'processor', implementation: 'native', module: 'destination', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', }, statusCode: 400, + metadata: generateMetadata(2), }, ], }, diff --git a/test/integrations/destinations/klaviyo/processor/identifyTestData.ts b/test/integrations/destinations/klaviyo/processor/identifyTestData.ts index 8b5503fad97..0dd47511330 100644 --- a/test/integrations/destinations/klaviyo/processor/identifyTestData.ts +++ b/test/integrations/destinations/klaviyo/processor/identifyTestData.ts @@ -3,13 +3,27 @@ import { overrideDestination, transformResultBuilder, generateSimplifiedIdentifyPayload, + generateMetadata, } from '../../../testUtils'; +import { ProcessorTestData } from '../../../testTypes'; +import { Destination } from '../../../../../src/types'; -const destination = { +const destination: Destination = { + ID: '123', + Name: 'klaviyo', + DestinationDefinition: { + ID: '123', + Name: 'klaviyo', + DisplayName: 'klaviyo', + Config: {}, + }, Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey', }, + Enabled: true, + WorkspaceID: '123', + Transformations: [], }; const commonTraits = { @@ -33,6 +47,8 @@ const commonTraits = { }, }; +const commonTraits2 = { ...commonTraits, street: '63, Shibuya' }; + const commonOutputUserProps = { external_id: 'user@1', email: 'test@rudderstack.com', @@ -53,6 +69,12 @@ const commonOutputUserProps = { }, }; +const commonOutputUserProps2 = { + ...commonOutputUserProps, + location: { ...commonOutputUserProps.location, address1: '63, Shibuya' }, + properties: { ...commonOutputUserProps.properties, street: '63, Shibuya' }, +}; + const commonOutputSubscriptionProps = { list_id: 'XUepkK', subscriptions: [ @@ -81,7 +103,7 @@ const originalTimestamp = '2021-01-03T17:02:53.193Z'; const commonUserUpdateEndpoint = 'https://a.klaviyo.com/api/profiles/01GW3PHVY0MTCDGS0A1612HARX'; const subscribeEndpoint = 'https://a.klaviyo.com/api/profile-subscription-bulk-create-jobs'; -export const identifyData = [ +export const identifyData: ProcessorTestData[] = [ { id: 'klaviyo-identify-test-1', name: 'klaviyo', @@ -102,12 +124,13 @@ export const identifyData = [ destination, message: generateSimplifiedIdentifyPayload({ context: { - traits: commonTraits, + traits: commonTraits2, }, anonymousId, userId, sentAt, }), + metadata: generateMetadata(1), }, ], }, @@ -125,12 +148,13 @@ export const identifyData = [ JSON: { data: { type: 'profile', - attributes: commonOutputUserProps, + attributes: commonOutputUserProps2, id: '01GW3PHVY0MTCDGS0A1612HARX', }, }, }), statusCode: 200, + metadata: generateMetadata(1), }, { output: transformResultBuilder({ @@ -146,6 +170,7 @@ export const identifyData = [ }, }), statusCode: 200, + metadata: generateMetadata(1), }, ], }, @@ -171,7 +196,7 @@ export const identifyData = [ userId, context: { traits: { - ...commonTraits, + ...commonTraits2, friend: { names: { first: 'Alice', @@ -184,6 +209,7 @@ export const identifyData = [ anonymousId, originalTimestamp, }), + metadata: generateMetadata(2), }, ], }, @@ -203,9 +229,9 @@ export const identifyData = [ type: 'profile', id: '01GW3PHVY0MTCDGS0A1612HARX', attributes: { - ...commonOutputUserProps, + ...commonOutputUserProps2, properties: { - ...commonOutputUserProps.properties, + ...commonOutputUserProps2.properties, 'friend.age': 25, 'friend.names.first': 'Alice', 'friend.names.last': 'Smith', @@ -215,6 +241,7 @@ export const identifyData = [ }, }), statusCode: 200, + metadata: generateMetadata(2), }, { output: transformResultBuilder({ @@ -230,6 +257,7 @@ export const identifyData = [ }, }), statusCode: 200, + metadata: generateMetadata(2), }, ], }, @@ -249,24 +277,23 @@ export const identifyData = [ request: { body: [ { - destination: { - Config: { - publicApiKey: 'dummyPublicApiKey', - privateApiKey: 'dummyPrivateApiKeyforfailure', - }, - }, + destination: overrideDestination(destination, { + publicApiKey: 'dummyPublicApiKey', + privateApiKey: 'dummyPrivateApiKeyforfailure', + }), message: generateSimplifiedIdentifyPayload({ sentAt, userId, context: { traits: { - ...commonTraits, + ...commonTraits2, email: 'test3@rudderstack.com', }, }, anonymousId, originalTimestamp, }), + metadata: generateMetadata(3), }, ], }, @@ -285,8 +312,11 @@ export const identifyData = [ feature: 'processor', implementation: 'native', module: 'destination', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', }, statusCode: 500, + metadata: generateMetadata(3), }, ], }, @@ -312,13 +342,14 @@ export const identifyData = [ userId, context: { traits: { - ...commonTraits, + ...commonTraits2, properties: { ...commonTraits.properties, subscribe: false }, }, }, anonymousId, originalTimestamp, }), + metadata: generateMetadata(4), }, ], }, @@ -335,13 +366,14 @@ export const identifyData = [ JSON: { data: { type: 'profile', - attributes: commonOutputUserProps, + attributes: commonOutputUserProps2, id: '01GW3PHVY0MTCDGS0A1612HARX', }, }, userId: '', }), statusCode: 200, + metadata: generateMetadata(4), }, ], }, @@ -366,11 +398,12 @@ export const identifyData = [ sentAt, userId, context: { - traits: commonTraits, + traits: commonTraits2, }, anonymousId, originalTimestamp, }), + metadata: generateMetadata(5), }, ], }, @@ -389,9 +422,9 @@ export const identifyData = [ data: { type: 'profile', attributes: removeUndefinedAndNullValues({ - ...commonOutputUserProps, + ...commonOutputUserProps2, properties: { - ...commonOutputUserProps.properties, + ...commonOutputUserProps2.properties, _id: userId, }, // remove external_id from the payload @@ -402,6 +435,7 @@ export const identifyData = [ }, }), statusCode: 200, + metadata: generateMetadata(5), }, { output: transformResultBuilder({ @@ -417,6 +451,7 @@ export const identifyData = [ }, }), statusCode: 200, + metadata: generateMetadata(5), }, ], }, @@ -450,6 +485,7 @@ export const identifyData = [ anonymousId, originalTimestamp, }), + metadata: generateMetadata(6), }, ], }, @@ -476,6 +512,7 @@ export const identifyData = [ }, }), statusCode: 200, + metadata: generateMetadata(6), }, { output: transformResultBuilder({ @@ -491,6 +528,7 @@ export const identifyData = [ }, }), statusCode: 200, + metadata: generateMetadata(6), }, ], }, @@ -516,7 +554,7 @@ export const identifyData = [ userId, context: { traits: removeUndefinedAndNullValues({ - ...commonTraits, + ...commonTraits2, email: undefined, phone: undefined, }), @@ -524,6 +562,7 @@ export const identifyData = [ anonymousId, originalTimestamp, }), + metadata: generateMetadata(7), }, ], }, @@ -541,8 +580,11 @@ export const identifyData = [ feature: 'processor', implementation: 'native', module: 'destination', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', }, statusCode: 400, + metadata: generateMetadata(7), }, ], }, diff --git a/test/integrations/destinations/klaviyo/processor/screenTestData.ts b/test/integrations/destinations/klaviyo/processor/screenTestData.ts index 3779747a4ee..0a20110236b 100644 --- a/test/integrations/destinations/klaviyo/processor/screenTestData.ts +++ b/test/integrations/destinations/klaviyo/processor/screenTestData.ts @@ -1,13 +1,30 @@ -import { generateSimplifiedPageOrScreenPayload, transformResultBuilder } from '../../../testUtils'; +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; +import { + generateMetadata, + generateSimplifiedPageOrScreenPayload, + transformResultBuilder, +} from '../../../testUtils'; -const destination = { +const destination: Destination = { + ID: '123', + Name: 'klaviyo', + DestinationDefinition: { + ID: '123', + Name: 'klaviyo', + DisplayName: 'klaviyo', + Config: {}, + }, Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey', }, + Enabled: true, + WorkspaceID: '123', + Transformations: [], }; -export const screenTestData = [ +export const screenTestData: ProcessorTestData[] = [ { id: 'klaviyo-screen-test-1', name: 'klaviyo', @@ -47,6 +64,7 @@ export const screenTestData = [ }, 'screen', ), + metadata: generateMetadata(1), }, ], }, @@ -89,6 +107,7 @@ export const screenTestData = [ userId: '', }), statusCode: 200, + metadata: generateMetadata(1), }, ], }, diff --git a/test/integrations/destinations/klaviyo/processor/trackTestData.ts b/test/integrations/destinations/klaviyo/processor/trackTestData.ts index f3bbfb96b9e..3bc2b1747ad 100644 --- a/test/integrations/destinations/klaviyo/processor/trackTestData.ts +++ b/test/integrations/destinations/klaviyo/processor/trackTestData.ts @@ -1,15 +1,29 @@ +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; import { + generateMetadata, generateSimplifiedTrackPayload, generateTrackPayload, overrideDestination, transformResultBuilder, } from '../../../testUtils'; -const destination = { +const destination: Destination = { + ID: '123', + Name: 'klaviyo', + DestinationDefinition: { + ID: '123', + Name: 'klaviyo', + DisplayName: 'klaviyo', + Config: {}, + }, Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey', }, + Enabled: true, + WorkspaceID: '123', + Transformations: [], }; const commonTraits = { @@ -33,7 +47,7 @@ const commonOutputHeaders = { const eventEndPoint = 'https://a.klaviyo.com/api/events'; -export const trackTestData = [ +export const trackTestData: ProcessorTestData[] = [ { id: 'klaviyo-track-test-1', name: 'klaviyo', @@ -71,6 +85,7 @@ export const trackTestData = [ anonymousId: '9c6bd77ea9da3e68', originalTimestamp: '2021-01-25T15:32:56.409Z', }), + metadata: generateMetadata(1), }, ], }, @@ -110,6 +125,7 @@ export const trackTestData = [ userId: '', }), statusCode: 200, + metadata: generateMetadata(1), }, ], }, @@ -151,6 +167,7 @@ export const trackTestData = [ anonymousId: '9c6bd77ea9da3e68', originalTimestamp: '2021-01-25T15:32:56.409Z', }), + metadata: generateMetadata(2), }, ], }, @@ -187,6 +204,7 @@ export const trackTestData = [ userId: '', }), statusCode: 200, + metadata: generateMetadata(2), }, ], }, @@ -223,6 +241,7 @@ export const trackTestData = [ anonymousId: '9c6bd77ea9da3e68', originalTimestamp: '2021-01-25T15:32:56.409Z', }), + metadata: generateMetadata(3), }, ], }, @@ -256,6 +275,7 @@ export const trackTestData = [ userId: '', }), statusCode: 200, + metadata: generateMetadata(3), }, ], }, @@ -289,6 +309,7 @@ export const trackTestData = [ anonymousId: '9c6bd77ea9da3e68', originalTimestamp: '2021-01-25T15:32:56.409Z', }), + metadata: generateMetadata(4), }, ], }, @@ -306,8 +327,11 @@ export const trackTestData = [ feature: 'processor', implementation: 'native', module: 'destination', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', }, statusCode: 400, + metadata: generateMetadata(4), }, ], }, diff --git a/test/integrations/destinations/klaviyo/processor/validationTestData.ts b/test/integrations/destinations/klaviyo/processor/validationTestData.ts index 59556cfe5f7..801e03d5417 100644 --- a/test/integrations/destinations/klaviyo/processor/validationTestData.ts +++ b/test/integrations/destinations/klaviyo/processor/validationTestData.ts @@ -1,4 +1,26 @@ -export const validationTestData = [ +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; +import { generateMetadata } from '../../../testUtils'; + +const destination: Destination = { + ID: '123', + Name: 'klaviyo', + DestinationDefinition: { + ID: '123', + Name: 'klaviyo', + DisplayName: 'klaviyo', + Config: {}, + }, + Config: { + publicApiKey: 'dummyPublicApiKey', + privateApiKey: 'dummyPrivateApiKey', + }, + Enabled: true, + WorkspaceID: '123', + Transformations: [], +}; + +export const validationTestData: ProcessorTestData[] = [ { id: 'klaviyo-validation-test-1', name: 'klaviyo', @@ -13,12 +35,7 @@ export const validationTestData = [ request: { body: [ { - destination: { - Config: { - publicApiKey: 'dummyPublicApiKey', - privateApiKey: 'dummyPrivateApiKey', - }, - }, + destination, message: { userId: 'user123', type: 'random', @@ -35,6 +52,7 @@ export const validationTestData = [ }, timestamp: '2020-01-21T00:21:34.208Z', }, + metadata: generateMetadata(1), }, ], }, @@ -52,8 +70,11 @@ export const validationTestData = [ feature: 'processor', implementation: 'native', module: 'destination', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', }, statusCode: 400, + metadata: generateMetadata(1), }, ], }, diff --git a/test/integrations/destinations/klaviyo/router/data.ts b/test/integrations/destinations/klaviyo/router/data.ts index 818089a722c..8866a8a546b 100644 --- a/test/integrations/destinations/klaviyo/router/data.ts +++ b/test/integrations/destinations/klaviyo/router/data.ts @@ -1,4 +1,184 @@ -export const data = [ +import { Destination, RouterTransformationRequest } from '../../../../../src/types'; +import { RouterTestData } from '../../../testTypes'; +import { generateMetadata } from '../../../testUtils'; + +const destination: Destination = { + ID: '123', + Name: 'klaviyo', + DestinationDefinition: { + ID: '123', + Name: 'klaviyo', + DisplayName: 'klaviyo', + Config: {}, + }, + Config: { + publicApiKey: 'dummyPublicApiKey', + privateApiKey: 'dummyPrivateApiKey', + }, + Enabled: true, + WorkspaceID: '123', + Transformations: [], +}; + +const routerRequest: RouterTransformationRequest = { + input: [ + { + destination, + metadata: generateMetadata(1), + message: { + type: 'identify', + sentAt: '2021-01-03T17:02:53.195Z', + userId: 'test', + channel: 'web', + context: { + os: { name: '', version: '' }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.1.11', + namespace: 'com.rudderlabs.javascript', + }, + traits: { + firstName: 'Test', + lastName: 'Rudderlabs', + email: 'test@rudderstack.com', + phone: '+12 345 578 900', + userId: 'Testc', + title: 'Developer', + organization: 'Rudder', + city: 'Tokyo', + region: 'Kanto', + country: 'JP', + zip: '100-0001', + Flagged: false, + Residence: 'Shibuya', + properties: { consent: ['email', 'sms'] }, + }, + locale: 'en-US', + screen: { density: 2 }, + library: { name: 'RudderLabs JavaScript SDK', version: '1.1.11' }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + rudderId: '8f8fa6b5-8e24-489c-8e22-61f23f2e364f', + messageId: '2116ef8c-efc3-4ca4-851b-02ee60dad6ff', + anonymousId: '97c46c81-3140-456d-b2a9-690d70aaca35', + integrations: { All: true }, + originalTimestamp: '2021-01-03T17:02:53.193Z', + }, + }, + { + destination, + metadata: generateMetadata(2), + message: { + type: 'identify', + sentAt: '2021-01-03T17:02:53.195Z', + userId: 'test', + channel: 'web', + context: { + os: { name: '', version: '' }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.1.11', + namespace: 'com.rudderlabs.javascript', + }, + traits: { + firstName: 'Test', + lastName: 'Rudderlabs', + email: 'test@rudderstack.com', + phone: '+12 345 578 900', + userId: 'test', + title: 'Developer', + organization: 'Rudder', + city: 'Tokyo', + region: 'Kanto', + country: 'JP', + zip: '100-0001', + Flagged: false, + Residence: 'Shibuya', + properties: { listId: 'XUepkK', subscribe: true, consent: ['email', 'sms'] }, + }, + locale: 'en-US', + screen: { density: 2 }, + library: { name: 'RudderLabs JavaScript SDK', version: '1.1.11' }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + }, + rudderId: '8f8fa6b5-8e24-489c-8e22-61f23f2e364f', + messageId: '2116ef8c-efc3-4ca4-851b-02ee60dad6ff', + anonymousId: '97c46c81-3140-456d-b2a9-690d70aaca35', + integrations: { All: true }, + originalTimestamp: '2021-01-03T17:02:53.193Z', + }, + }, + { + destination, + metadata: generateMetadata(3), + message: { + userId: 'user123', + type: 'group', + groupId: 'XUepkK', + traits: { subscribe: true }, + context: { + traits: { + email: 'test@rudderstack.com', + phone: '+12 345 678 900', + consent: ['email'], + }, + ip: '14.5.67.21', + library: { name: 'http' }, + }, + timestamp: '2020-01-21T00:21:34.208Z', + }, + }, + { + destination, + metadata: generateMetadata(4), + message: { + userId: 'user123', + type: 'random', + groupId: 'XUepkK', + traits: { subscribe: true }, + context: { + traits: { + email: 'test@rudderstack.com', + phone: '+12 345 678 900', + consent: 'email', + }, + ip: '14.5.67.21', + library: { name: 'http' }, + }, + timestamp: '2020-01-21T00:21:34.208Z', + }, + }, + { + destination, + metadata: generateMetadata(5), + message: { + userId: 'user123', + type: 'group', + groupId: '', + traits: { subscribe: true }, + context: { + traits: { + email: 'test@rudderstack.com', + phone: '+12 345 678 900', + consent: 'email', + }, + ip: '14.5.67.21', + library: { name: 'http' }, + }, + timestamp: '2020-01-21T00:21:34.208Z', + }, + }, + ], + destType: 'klaviyo', +}; + +export const data: RouterTestData[] = [ { id: 'klaviyo-router-test-1', name: 'klaviyo', @@ -10,173 +190,7 @@ export const data = [ version: 'v0', input: { request: { - body: { - input: [ - { - destination: { - Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey' }, - }, - metadata: { jobId: 1, userId: 'u1' }, - message: { - type: 'identify', - sentAt: '2021-01-03T17:02:53.195Z', - userId: 'test', - channel: 'web', - context: { - os: { name: '', version: '' }, - app: { - name: 'RudderLabs JavaScript SDK', - build: '1.0.0', - version: '1.1.11', - namespace: 'com.rudderlabs.javascript', - }, - traits: { - firstName: 'Test', - lastName: 'Rudderlabs', - email: 'test@rudderstack.com', - phone: '+12 345 578 900', - userId: 'Testc', - title: 'Developer', - organization: 'Rudder', - city: 'Tokyo', - region: 'Kanto', - country: 'JP', - zip: '100-0001', - Flagged: false, - Residence: 'Shibuya', - properties: { consent: ['email', 'sms'] }, - }, - locale: 'en-US', - screen: { density: 2 }, - library: { name: 'RudderLabs JavaScript SDK', version: '1.1.11' }, - campaign: {}, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', - }, - rudderId: '8f8fa6b5-8e24-489c-8e22-61f23f2e364f', - messageId: '2116ef8c-efc3-4ca4-851b-02ee60dad6ff', - anonymousId: '97c46c81-3140-456d-b2a9-690d70aaca35', - integrations: { All: true }, - originalTimestamp: '2021-01-03T17:02:53.193Z', - }, - }, - { - destination: { - Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey' }, - }, - metadata: { jobId: 2, userId: 'u1' }, - message: { - type: 'identify', - sentAt: '2021-01-03T17:02:53.195Z', - userId: 'test', - channel: 'web', - context: { - os: { name: '', version: '' }, - app: { - name: 'RudderLabs JavaScript SDK', - build: '1.0.0', - version: '1.1.11', - namespace: 'com.rudderlabs.javascript', - }, - traits: { - firstName: 'Test', - lastName: 'Rudderlabs', - email: 'test@rudderstack.com', - phone: '+12 345 578 900', - userId: 'test', - title: 'Developer', - organization: 'Rudder', - city: 'Tokyo', - region: 'Kanto', - country: 'JP', - zip: '100-0001', - Flagged: false, - Residence: 'Shibuya', - properties: { listId: 'XUepkK', subscribe: true, consent: ['email', 'sms'] }, - }, - locale: 'en-US', - screen: { density: 2 }, - library: { name: 'RudderLabs JavaScript SDK', version: '1.1.11' }, - campaign: {}, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', - }, - rudderId: '8f8fa6b5-8e24-489c-8e22-61f23f2e364f', - messageId: '2116ef8c-efc3-4ca4-851b-02ee60dad6ff', - anonymousId: '97c46c81-3140-456d-b2a9-690d70aaca35', - integrations: { All: true }, - originalTimestamp: '2021-01-03T17:02:53.193Z', - }, - }, - { - destination: { - Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey' }, - }, - metadata: { jobId: 3, userId: 'u1' }, - message: { - userId: 'user123', - type: 'group', - groupId: 'XUepkK', - traits: { subscribe: true }, - context: { - traits: { - email: 'test@rudderstack.com', - phone: '+12 345 678 900', - consent: ['email'], - }, - ip: '14.5.67.21', - library: { name: 'http' }, - }, - timestamp: '2020-01-21T00:21:34.208Z', - }, - }, - { - destination: { - Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey' }, - }, - metadata: { jobId: 4, userId: 'u1' }, - message: { - userId: 'user123', - type: 'random', - groupId: 'XUepkK', - traits: { subscribe: true }, - context: { - traits: { - email: 'test@rudderstack.com', - phone: '+12 345 678 900', - consent: 'email', - }, - ip: '14.5.67.21', - library: { name: 'http' }, - }, - timestamp: '2020-01-21T00:21:34.208Z', - }, - }, - { - destination: { - Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey' }, - }, - metadata: { jobId: 5, userId: 'u1' }, - message: { - userId: 'user123', - type: 'group', - groupId: '', - traits: { subscribe: true }, - context: { - traits: { - email: 'test@rudderstack.com', - phone: '+12 345 678 900', - consent: 'email', - }, - ip: '14.5.67.21', - library: { name: 'http' }, - }, - timestamp: '2020-01-21T00:21:34.208Z', - }, - }, - ], - destType: 'klaviyo', - }, + body: routerRequest, }, }, output: { @@ -263,15 +277,10 @@ export const data = [ files: {}, }, ], - metadata: [ - { jobId: 3, userId: 'u1' }, - { jobId: 2, userId: 'u1' }, - ], + metadata: [generateMetadata(3), generateMetadata(2)], batched: true, statusCode: 200, - destination: { - Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey' }, - }, + destination, }, { batchedRequest: { @@ -315,15 +324,13 @@ export const data = [ }, files: {}, }, - metadata: [{ jobId: 1, userId: 'u1' }], + metadata: [generateMetadata(1)], batched: false, statusCode: 200, - destination: { - Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey' }, - }, + destination, }, { - metadata: [{ jobId: 4, userId: 'u1' }], + metadata: [generateMetadata(4)], batched: false, statusCode: 400, error: 'Event type random is not supported', @@ -334,13 +341,13 @@ export const data = [ feature: 'router', implementation: 'native', module: 'destination', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', }, - destination: { - Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey' }, - }, + destination, }, { - metadata: [{ jobId: 5, userId: 'u1' }], + metadata: [generateMetadata(5)], batched: false, statusCode: 400, error: 'groupId is a required field for group events', @@ -351,10 +358,10 @@ export const data = [ feature: 'router', implementation: 'native', module: 'destination', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', }, - destination: { - Config: { publicApiKey: 'dummyPublicApiKey', privateApiKey: 'dummyPrivateApiKey' }, - }, + destination, }, ], }, diff --git a/test/integrations/destinations/koala/processor/data.ts b/test/integrations/destinations/koala/processor/data.ts new file mode 100644 index 00000000000..b866353066b --- /dev/null +++ b/test/integrations/destinations/koala/processor/data.ts @@ -0,0 +1,323 @@ +export const data = [ + { + name: 'koala', + description: 'Sucessful track event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + publicKey: 'kkooaallaa321', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + userId: 'user-uuid', + annonymousId: 'annonymous-uuid', + event: 'User Signed Up', + type: 'track', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + properties: { + email: 'johndoe@somemail.com', + label: 'test', + value: 10, + }, + context: { + network: 'wifi', + }, + originalTimestamp: '2024-01-23T08:35:17.562Z', + sentAt: '2024-01-23T08:35:17.562Z', + request_ip: '192.11.22.33', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + FORM: {}, + JSON_ARRAY: {}, + XML: {}, + JSON: { + ip: '192.11.22.33', + email: 'johndoe@somemail.com', + events: [ + { + type: 'track', + event: 'User Signed Up', + sent_at: '2024-01-23T08:35:17.562Z', + message_id: '84e26acc-56a5-4835-8233-591137fca468', + properties: { + email: 'johndoe@somemail.com', + label: 'test', + value: 10, + }, + context: { + network: 'wifi', + }, + }, + ], + }, + }, + endpoint: 'https://api2.getkoala.com/web/projects/kkooaallaa321/batch', + files: {}, + params: {}, + type: 'REST', + version: '1', + method: 'POST', + userId: '', + headers: { + 'content-type': 'application/json', + }, + }, + statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'koala', + description: 'Successful identify event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + publicKey: 'kkooaallaa321', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + userId: 'user-uuid', + type: 'identify', + traits: { + FirstName: 'John', + LastName: 'Doe', + address: { + city: 'San Francisco', + state: 'CA', + postalCode: '94107', + }, + email: 'johndoe@somemail.com', + ko_profile_id: 'xxxx-2222-xxxx-xxxx', + }, + originalTimestamp: '2024-01-23T08:35:17.342Z', + sentAt: '2024-01-23T08:35:35.234Z', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + FORM: {}, + JSON_ARRAY: {}, + XML: {}, + JSON: { + email: 'johndoe@somemail.com', + profile_id: 'xxxx-2222-xxxx-xxxx', + identifies: [ + { + type: 'identify', + sent_at: '2024-01-23T08:35:17.342Z', + traits: { + FirstName: 'John', + LastName: 'Doe', + address: { + city: 'San Francisco', + state: 'CA', + postalCode: '94107', + }, + email: 'johndoe@somemail.com', + }, + }, + ], + }, + }, + endpoint: 'https://api2.getkoala.com/web/projects/kkooaallaa321/batch', + files: {}, + params: {}, + type: 'REST', + version: '1', + method: 'POST', + userId: '', + headers: { + 'content-type': 'application/json', + }, + }, + statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'koala', + description: 'Missing required email or ko_profile_id fields in traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + publicKey: 'kkooaallaa321', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + userId: 'user-uuid', + type: 'track', + traits: { + name: 'John Doe', + }, + originalTimestamp: '2024-01-23T08:35:17.342Z', + sentAt: '2024-01-23T08:35:35.234Z', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: + 'Neither email or ko_profile_id are present on traits. Aborting message: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Neither email or ko_profile_id are present on traits. Aborting message', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'KOALA', + module: 'destination', + implementation: 'cdkV2', + destinationId: 'destId', + workspaceId: 'wspId', + feature: 'processor', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'koala', + description: 'Invalid message type page', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + publicKey: 'kkooaallaa321', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + userId: 'user-uuid', + type: 'page', + groupId: 'group-uuid', + originalTimestamp: '2024-01-23T08:35:17.342Z', + sentAt: '2024-01-23T08:35:35.234Z', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: + 'message type page is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type page is not supported', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'KOALA', + module: 'destination', + implementation: 'cdkV2', + destinationId: 'destId', + workspaceId: 'wspId', + feature: 'processor', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/koala/router/data.ts b/test/integrations/destinations/koala/router/data.ts new file mode 100644 index 00000000000..f998f48dc4b --- /dev/null +++ b/test/integrations/destinations/koala/router/data.ts @@ -0,0 +1,204 @@ +export const data = [ + { + name: 'koala', + description: 'Router batch request', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + destination: { + Config: { + publicKey: 'kkooaallaa321', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + userId: 'user-uuid', + annonymousId: 'annonymous-uuid', + event: 'User Signed Up', + type: 'track', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + traits: { + email: 'johndoe@somemail.com', + }, + properties: { + label: 'test', + value: 10, + }, + context: { + network: 'wifi', + }, + originalTimestamp: '2024-01-23T08:35:17.562Z', + sentAt: '2024-01-23T08:35:17.562Z', + request_ip: '192.11.22.33', + }, + metadata: { + jobId: 1, + userId: 'u1', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + { + destination: { + Config: { + publicKey: 'kkooaallaa321', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + userId: 'user-uuid', + annonymousId: 'annonymous-uuid', + event: 'User Deleted account', + type: 'track', + messageId: '8bc79b03-2a5c-4615-b2da-54c0aaaaaae8', + traits: { + ko_profile_id: '123456', + }, + properties: { + attr1: 'foo', + attr2: 'bar', + }, + context: { + network: 'wifi', + }, + originalTimestamp: '2024-01-23T08:35:17.562Z', + sentAt: '2024-01-23T08:35:17.562Z', + request_ip: '192.11.55.1', + }, + metadata: { + jobId: 2, + userId: 'u1', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + destType: 'koala', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: { + body: { + FORM: {}, + JSON_ARRAY: {}, + XML: {}, + JSON: { + ip: '192.11.22.33', + email: 'johndoe@somemail.com', + events: [ + { + type: 'track', + event: 'User Signed Up', + sent_at: '2024-01-23T08:35:17.562Z', + message_id: '84e26acc-56a5-4835-8233-591137fca468', + properties: { + label: 'test', + value: 10, + }, + context: { + network: 'wifi', + }, + }, + ], + }, + }, + endpoint: 'https://api2.getkoala.com/web/projects/kkooaallaa321/batch', + files: {}, + params: {}, + type: 'REST', + version: '1', + method: 'POST', + headers: { + 'content-type': 'application/json', + }, + }, + batched: false, + metadata: [{ jobId: 1, userId: 'u1', workspaceId: 'wspId', destinationId: 'destId' }], + statusCode: 200, + destination: { + Config: { + publicKey: 'kkooaallaa321', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + }, + { + batchedRequest: { + body: { + FORM: {}, + JSON_ARRAY: {}, + XML: {}, + JSON: { + ip: '192.11.55.1', + profile_id: '123456', + events: [ + { + type: 'track', + event: 'User Deleted account', + sent_at: '2024-01-23T08:35:17.562Z', + message_id: '8bc79b03-2a5c-4615-b2da-54c0aaaaaae8', + properties: { + attr1: 'foo', + attr2: 'bar', + }, + context: { + network: 'wifi', + }, + }, + ], + }, + }, + endpoint: 'https://api2.getkoala.com/web/projects/kkooaallaa321/batch', + files: {}, + params: {}, + type: 'REST', + version: '1', + method: 'POST', + headers: { + 'content-type': 'application/json', + }, + }, + batched: false, + metadata: [{ jobId: 2, userId: 'u1', workspaceId: 'wspId', destinationId: 'destId' }], + statusCode: 200, + destination: { + Config: { + publicKey: 'kkooaallaa321', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + }, + ], + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/marketo/dataDelivery/business.ts b/test/integrations/destinations/marketo/dataDelivery/business.ts new file mode 100644 index 00000000000..ca4e05afa99 --- /dev/null +++ b/test/integrations/destinations/marketo/dataDelivery/business.ts @@ -0,0 +1,352 @@ +import { ProxyMetdata } from '../../../../../src/types'; +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV1Payload } from '../../../testUtils'; + +const statTags = { + aborted: { + destType: 'MARKETO', + destinationId: 'dummyDestinationId', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'dummyWorkspaceId', + }, + retryable: { + destType: 'MARKETO', + destinationId: 'dummyDestinationId', + errorCategory: 'network', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'dummyWorkspaceId', + }, + throttled: { + destType: 'MARKETO', + destinationId: 'dummyDestinationId', + errorCategory: 'network', + errorType: 'throttled', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'dummyWorkspaceId', + }, +}; + +export const proxyMetdata: ProxyMetdata = { + jobId: 1, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, +}; + +export const reqMetadataArray = [proxyMetdata]; +const params = { + destination: 'marketo', +}; + +const commonRequestParameters = { + JSON: { + action: 'createOrUpdate', + input: [ + { + City: 'Tokyo', + Country: 'JP', + Email: 'gabi29@gmail.com', + PostalCode: '100-0001', + Title: 'Owner', + id: 1328328, + userId: 'gabi_userId_45', + }, + ], + lookupField: 'id', + }, + params, +}; + +export const testScenariosForV1API: ProxyV1TestData[] = [ + { + id: 'marketo_v1_scenario_1', + name: 'marketo', + description: '[Proxy v1 API] :: Test for a successful update request', + successCriteria: 'Should return a 200 status code with status updated and record id', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + headers: { + Authorization: 'Bearer test_token_1', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + endpoint: 'https://mktId.mktorest.com/rest/v1/leads.json/test1', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + response: [ + { + error: + '{"requestId":"664#17dae8c3d48","result":[{"id":1328328,"status":"updated"}],"success":true}', + metadata: proxyMetdata, + statusCode: 200, + }, + ], + }, + }, + }, + }, + }, + { + id: 'marketo_v1_scenario_2', + name: 'marketo', + description: '[Proxy v1 API] :: Test for Access token invalid scenario', + successCriteria: 'Should return a 500 status code with message Access token invalid', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + headers: { + Authorization: 'Bearer test_token_2', + 'Content-Type': 'application/json', + }, + endpoint: 'https://mktId.mktorest.com/rest/v1/leads.json/test2', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 500, + statTags: statTags.retryable, + message: + 'Request Failed for marketo, Access token invalid (Retryable).during Marketo Response Handling', + response: [ + { + error: + '{"requestId":"a61c#17daea5968a","success":false,"errors":[{"code":"601","message":"Access token invalid"}]}', + metadata: proxyMetdata, + statusCode: 500, + }, + ], + }, + }, + }, + }, + }, + { + id: 'marketo_v1_scenario_3', + name: 'marketo', + description: '[Proxy v1 API] :: Test for Requested resource not found scenario', + successCriteria: 'Should return a 400 status code with message Requested resource not found', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + headers: { + Authorization: 'Bearer test_token_3', + 'Content-Type': 'application/json', + }, + endpoint: 'https://mktId.mktorest.com/rest/v1/leads.json/test3', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + statTags: statTags.aborted, + message: + 'Request Failed for marketo, Requested resource not found (Aborted).during Marketo Response Handling', + response: [ + { + error: + '{"requestId":"a61c#17daea5968a","success":false,"errors":[{"code":"610","message":"Requested resource not found"}]}', + metadata: proxyMetdata, + statusCode: 400, + }, + ], + }, + }, + }, + }, + }, + { + id: 'marketo_v1_scenario_4', + name: 'marketo', + description: '[Proxy v1 API] :: Test for Unknown error with empty response', + successCriteria: 'Should return a 500 status code with empty response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + headers: { + Authorization: 'Bearer test_token_4', + 'Content-Type': 'application/json', + }, + endpoint: 'https://mktId.mktorest.com/rest/v1/leads.json/test4', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 500, + statTags: statTags.retryable, + message: 'Request failed with status: 500', + response: [ + { + error: '""', + metadata: proxyMetdata, + statusCode: 500, + }, + ], + }, + }, + }, + }, + }, + { + id: 'marketo_v1_scenario_5', + name: 'marketo', + description: '[Proxy v1 API] :: Test for missing content type header scenario', + successCriteria: 'Should return a 612 status code with Invalid Content Type ', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: { + Authorization: 'Bearer test_token_6', + 'Content-Type': 'invalid', + 'User-Agent': 'RudderLabs', + }, + endpoint: 'https://mktId.mktorest.com/rest/v1/leads.json/test_invalid_header', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + statTags: statTags.aborted, + message: + 'Request Failed for marketo, Invalid Content Type (Aborted).during Marketo Response Handling', + response: [ + { + error: + '{"success":false,"errors":[{"code":"612","message":"Invalid Content Type"}]}', + metadata: proxyMetdata, + statusCode: 400, + }, + ], + }, + }, + }, + }, + }, + { + id: 'marketo_v1_scenario_6', + name: 'marketo', + description: '[Proxy v1 API] :: Test for a passed field exceeding max length', + successCriteria: 'Should return a 1077 status code with Value for field exceeds max length', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: { + Authorization: 'Bearer test_token_6', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + endpoint: 'https://mktId.mktorest.com/rest/v1/leads.json/test_exceeded_length', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + statTags: statTags.aborted, + message: 'Request failed with status: 400', + response: [ + { + error: + '{"success":false,"errors":[{"code":"1077","message":"Value for field exceeds max length"}]}', + metadata: proxyMetdata, + statusCode: 400, + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/marketo/dataDelivery/data.ts b/test/integrations/destinations/marketo/dataDelivery/data.ts index 47dd8e92362..db379c9e956 100644 --- a/test/integrations/destinations/marketo/dataDelivery/data.ts +++ b/test/integrations/destinations/marketo/dataDelivery/data.ts @@ -1,4 +1,7 @@ -export const data = [ +import { testScenariosForV1API } from './business'; +import { otheMarketoScenariosV1 } from './other'; + +const legacyTests = [ { name: 'marketo', description: 'Test 0', @@ -488,3 +491,5 @@ export const data = [ }, }, ]; + +export const data = [...legacyTests, ...testScenariosForV1API, ...otheMarketoScenariosV1]; diff --git a/test/integrations/destinations/marketo/dataDelivery/other.ts b/test/integrations/destinations/marketo/dataDelivery/other.ts new file mode 100644 index 00000000000..5d4e3b1f177 --- /dev/null +++ b/test/integrations/destinations/marketo/dataDelivery/other.ts @@ -0,0 +1,266 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV1Payload } from '../../../testUtils'; + +const statTags = { + aborted: { + destType: 'MARKETO', + destinationId: 'default-destinationId', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'default-workspaceId', + }, + retryable: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'MARKETO', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + }, +}; + +const metadata = { + jobId: 1, + secret: { + accessToken: 'default-accessToken', + }, + attemptNum: 1, + userId: 'default-userId', + sourceId: 'default-sourceId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + dontBatch: false, +}; + +export const otheMarketoScenariosV1: ProxyV1TestData[] = [ + { + id: 'marketo_v1_other_scenario_1', + name: 'marketo', + description: + '[Proxy v1 API] :: Scenario for testing Service Unavailable error from destination', + successCriteria: 'Should return 503 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_service_not_available', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: + '{"error":{"message":"Service Unavailable","description":"The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later."}}', + statusCode: 503, + metadata, + }, + ], + statTags: statTags.retryable, + message: 'Request failed with status: 503', + status: 503, + }, + }, + }, + }, + }, + { + id: 'marketo_v1_other_scenario_2', + name: 'marketo', + description: '[Proxy v1 API] :: Scenario for testing Internal Server error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_internal_server_error', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Internal Server Error"', + statusCode: 500, + metadata, + }, + ], + statTags: statTags.retryable, + message: 'Request failed with status: 500', + status: 500, + }, + }, + }, + }, + }, + { + id: 'marketo_v1_other_scenario_3', + name: 'marketo', + description: '[Proxy v1 API] :: Scenario for testing Gateway Time Out error from destination', + successCriteria: 'Should return 504 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_gateway_time_out', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Gateway Timeout"', + statusCode: 504, + metadata, + }, + ], + statTags: statTags.retryable, + message: 'Request failed with status: 504', + status: 504, + }, + }, + }, + }, + }, + { + id: 'marketo_v1_other_scenario_4', + name: 'marketo', + description: '[Proxy v1 API] :: Scenario for testing null response from destination', + successCriteria: 'Should return 500 status code with empty error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_response', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata, + }, + ], + statTags: statTags.retryable, + message: 'Request failed with status: 500', + status: 500, + }, + }, + }, + }, + }, + { + id: 'marketo_v1_other_scenario_5', + name: 'marketo', + description: + '[Proxy v1 API] :: Scenario for testing null and no status response from destination', + successCriteria: 'Should return 500 status code with empty error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_and_no_status', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata, + }, + ], + statTags: statTags.retryable, + message: 'Request failed with status: 500', + status: 500, + }, + }, + }, + }, + }, + { + id: 'marketo_v1_scenario_6', + name: 'marketo', + description: '[Proxy v1 API] :: Test for DNS lookup failed scenario', + successCriteria: 'Should return a 400 status code with empty response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/dns_lookup_failure', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + statTags: statTags.aborted, + message: 'Request failed with status: 400', + response: [ + { + error: '{}', + metadata, + statusCode: 400, + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/marketo/network.ts b/test/integrations/destinations/marketo/network.ts index 9c28a9aef1d..1606e78c516 100644 --- a/test/integrations/destinations/marketo/network.ts +++ b/test/integrations/destinations/marketo/network.ts @@ -1,20 +1,26 @@ -export const networkCallsData = [ +const userObject = { + City: 'Tokyo', + Country: 'JP', + Email: 'gabi29@gmail.com', + PostalCode: '100-0001', + Title: 'Owner', + id: 1328328, + userId: 'gabi_userId_45', +}; + +const headerObject = { + Authorization: 'Bearer test_token_2', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', +}; + +const tfProxyMocksData = [ { httpReq: { url: 'https://mktId.mktorest.com/rest/v1/leads.json/test1', data: { action: 'createOrUpdate', - input: [ - { - City: 'Tokyo', - Country: 'JP', - Email: 'gabi29@gmail.com', - PostalCode: '100-0001', - Title: 'Owner', - id: 1328328, - userId: 'gabi_userId_45', - }, - ], + input: [userObject], lookupField: 'id', }, headers: { @@ -44,24 +50,10 @@ export const networkCallsData = [ url: 'https://mktId.mktorest.com/rest/v1/leads.json/test2', data: { action: 'createOrUpdate', - input: [ - { - City: 'Tokyo', - Country: 'JP', - Email: 'gabi29@gmail.com', - PostalCode: '100-0001', - Title: 'Owner', - id: 1328328, - userId: 'gabi_userId_45', - }, - ], + input: [userObject], lookupField: 'id', }, - headers: { - Authorization: 'Bearer test_token_2', - 'Content-Type': 'application/json', - 'User-Agent': 'RudderLabs', - }, + headers: headerObject, method: 'POST', }, httpRes: { @@ -84,17 +76,7 @@ export const networkCallsData = [ url: 'https://mktId.mktorest.com/rest/v1/leads.json/test3', data: { action: 'createOrUpdate', - input: [ - { - City: 'Tokyo', - Country: 'JP', - Email: 'gabi29@gmail.com', - PostalCode: '100-0001', - Title: 'Owner', - id: 1328328, - userId: 'gabi_userId_45', - }, - ], + input: [userObject], lookupField: 'id', }, headers: { @@ -124,17 +106,7 @@ export const networkCallsData = [ url: 'https://mktId.mktorest.com/rest/v1/leads.json/test4', data: { action: 'createOrUpdate', - input: [ - { - City: 'Tokyo', - Country: 'JP', - Email: 'gabi29@gmail.com', - PostalCode: '100-0001', - Title: 'Owner', - id: 1328328, - userId: 'gabi_userId_45', - }, - ], + input: [userObject], lookupField: 'id', }, headers: { @@ -151,17 +123,7 @@ export const networkCallsData = [ url: 'https://mktId.mktorest.com/rest/v1/leads.json/test5', data: { action: 'createOrUpdate', - input: [ - { - City: 'Tokyo', - Country: 'JP', - Email: 'gabi29@gmail.com', - PostalCode: '100-0001', - Title: 'Owner', - id: 1328328, - userId: 'gabi_userId_45', - }, - ], + input: [userObject], lookupField: 'id', }, headers: { @@ -178,17 +140,7 @@ export const networkCallsData = [ url: 'https://mktId.mktorest.com/rest/v1/leads.json/test6', data: { action: 'createOrUpdate', - input: [ - { - City: 'Tokyo', - Country: 'JP', - Email: 'gabi29@gmail.com', - PostalCode: '100-0001', - Title: 'Owner', - id: 1328328, - userId: 'gabi_userId_45', - }, - ], + input: [userObject], lookupField: 'id', }, headers: { @@ -970,3 +922,1007 @@ export const networkCallsData = [ }, }, ]; + +const businessMockData = [ + { + description: 'Mock response for a successful update request', + httpReq: { + url: 'https://mktId.mktorest.com/rest/v1/leads.json/test1', + data: { + action: 'createOrUpdate', + input: [userObject], + lookupField: 'id', + }, + headers: { + Authorization: 'Bearer test_token_1', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: { + requestId: '664#17dae8c3d48', + result: [ + { + id: 1328328, + status: 'updated', + }, + ], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed update request due to invalid access token', + httpReq: { + url: 'https://mktId.mktorest.com/rest/v1/leads.json/test2', + data: { + action: 'createOrUpdate', + input: [userObject], + lookupField: 'id', + }, + headers: headerObject, + method: 'POST', + }, + httpRes: { + data: { + requestId: 'a61c#17daea5968a', + success: false, + errors: [ + { + code: '601', + message: 'Access token invalid', + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed update request due to requested resource not found', + httpReq: { + url: 'https://mktId.mktorest.com/rest/v1/leads.json/test3', + data: { + action: 'createOrUpdate', + input: [userObject], + lookupField: 'id', + }, + headers: { + Authorization: 'Bearer test_token_3', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: { + requestId: 'a61c#17daea5968a', + success: false, + errors: [ + { + code: '610', + message: 'Requested resource not found', + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful create/update request', + httpReq: { + url: 'https://mktId.mktorest.com/rest/v1/leads.json/test4', + data: { + action: 'createOrUpdate', + input: [userObject], + lookupField: 'id', + }, + headers: { + Authorization: 'Bearer test_token_4', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: {}, + }, + { + description: 'Mock response for a successful create/update request', + httpReq: { + url: 'https://mktId.mktorest.com/rest/v1/leads.json/test5', + data: { + action: 'createOrUpdate', + input: [userObject], + lookupField: 'id', + }, + headers: { + Authorization: 'Bearer test_token_5', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: '', + }, + { + description: 'Mock response for a failed create/update request due to DNS lookup failure', + httpReq: { + url: 'https://mktId.mktorest.com/rest/v1/leads.json/test6', + data: { + action: 'createOrUpdate', + input: [userObject], + lookupField: 'id', + }, + headers: { + Authorization: 'Bearer test_token_6', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + code: '[ENOTFOUND] :: DNS lookup failed', + status: 400, + }, + }, + { + description: + 'Mock response for a failed create/update request due to unhandled exception in proxy request', + httpReq: { + url: 'https://unhandled_exception_in_proxy_req.mktorest.com/rest/v1/leads.json', + data: { + action: 'createOrUpdate', + input: [userObject], + lookupField: 'id', + }, + headers: { + Authorization: 'Bearer access_token_success', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: { + requestId: '142e4#1835b117b76', + success: false, + errors: [ + { + code: 'random_marketo_code', + message: 'problem', + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful access token request', + httpReq: { + url: 'https://marketo_acct_id_success.mktorest.com/identity/oauth/token', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'access_token_success', + expires_in: 3599, + scope: 'integrations@rudderstack.com', + token_type: 'bearer', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed access token request due to expired token', + httpReq: { + url: 'https://marketo_acct_id_token_failure.mktorest.com/identity/oauth/token', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'access_token_expired', + expires_in: 0, + scope: 'integrations@rudderstack.com', + token_type: 'bearer', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful get request', + httpReq: { + url: 'https://marketo_acct_id_success.mktorest.com/rest/v1/leads.json', + method: 'get', + }, + httpRes: { + data: { + requestId: '7ab2#17672a46a99', + result: [ + { + id: 4, + status: 'created', + }, + ], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful get request with filterType=email with no results', + httpReq: { + url: 'https://marketo_acct_id_success.mktorest.com/rest/v1/leads.json?filterType=email&filterValues=arnab.compsc%40gmail.com', + method: 'GET', + }, + httpRes: { + data: { + requestId: '107#17672aeadba', + result: [], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful get request with filterType=userId with results', + httpReq: { + url: 'https://marketo_acct_id_success.mktorest.com/rest/v1/leads.json?filterType=userId&filterValues=test-user-6j55yr', + method: 'GET', + }, + httpRes: { + data: { + requestId: '12093#17672aeaee6', + result: [ + { + createdAt: '2020-12-17T21:39:07Z', + email: null, + firstName: null, + id: 4, + lastName: null, + updatedAt: '2020-12-17T21:39:07Z', + userId: 'test-user-6j55yr', + }, + ], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed access token request due to expired token', + httpReq: { + url: 'https://marketo_acct_id_failed.mktorest.com/identity/oauth/token', + method: 'GET', + }, + httpRes: { + data: { + success: false, + errors: [ + { + code: '601', + message: 'Access Token Expired', + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful access token request', + httpReq: { + url: 'https://munchkinId.mktorest.com/identity/oauth/token?client_id=b&client_secret=clientSecret&grant_type=client_credentials', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'test_acess', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed access token request due to invalid client id', + httpReq: { + url: 'https://munchkinId.mktorest.com/identity/oauth/token?client_id=wrongClientId&client_secret=clientSecret&grant_type=client_credentials', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'test_access_token', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful get request to get list of fields', + httpReq: { + url: 'https://munchkinId.mktorest.com/rest/v1/leads/describe2.json', + method: 'GET', + }, + httpRes: { + data: { + requestId: '7fa1#17fd1da66fe', + result: [ + { + name: 'API Lead', + searchableFields: [['email']], + fields: [ + { + name: 'email', + displayName: 'Email Address', + dataType: 'email', + length: 255, + updateable: true, + crmManaged: false, + }, + ], + }, + ], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful bulk request with queued status', + httpReq: { + url: 'https://munchkinId.mktorest.com/bulk/v1/leads.json', + method: 'GET', + }, + httpRes: { + data: { + requestId: '5bdd#17fd1ff88cd', + result: [ + { + batchId: 2977, + importId: '2977', + status: 'Queued', + }, + ], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for bulk request', + httpReq: { + url: 'https://a.mktorest.com/identity/oauth/token?client_id=b&client_secret=c&grant_type=client_credentials', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'test_access_token', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for bulk request for throttling error', + httpReq: { + url: 'https://a.mktorest.com/identity/oauth/token?client_id=b&client_secret=forThrottle&grant_type=client_credentials', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'test_access_token', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful get request to get list of fields', + httpReq: { + url: 'https://a.mktorest.com/rest/v1/leads/describe2.json', + method: 'GET', + }, + httpRes: { + data: { + requestId: '7fa1#17fd1da66fe', + result: [ + { + name: 'API Lead', + searchableFields: [['email']], + fields: [ + { + name: 'email', + displayName: 'Email Address', + dataType: 'email', + length: 255, + updateable: true, + crmManaged: false, + }, + ], + }, + ], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a succesful oauth token request', + httpReq: { + url: 'https://testMunchkin4.mktorest.com/identity/oauth/token?client_id=b&client_secret=c&grant_type=client_credentials', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'test_access_token', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed bulk request with 400 error', + httpReq: { + url: 'https://testMunchkin4.mktorest.com/bulk/v1/leads/batch/1234.json', + method: 'GET', + }, + httpRes: { + data: { + errors: [ + { + message: 'Any 400 error', + code: 1000, + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful oauth token request', + httpReq: { + url: 'https://testMunchkin3.mktorest.com/identity/oauth/token?client_id=b&client_secret=c&grant_type=client_credentials', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'test_access_token', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful oauth token request', + httpReq: { + url: 'https://testMunchkin500.mktorest.com/identity/oauth/token?client_id=b&client_secret=c&grant_type=client_credentials', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'test_access_token', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed bulk request with 500 error', + httpReq: { + url: 'https://testMunchkin500.mktorest.com/bulk/v1/leads/batch/1234.json', + method: 'GET', + }, + httpRes: { + data: { + errors: [ + { + message: 'Any 500 error', + code: 502, + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful bulk request with warnings', + httpReq: { + url: 'https://a.mktorest.com/bulk/v1/leads/batch/12345/warnings.json', + method: 'GET', + }, + httpRes: { + data: 'data \n data', + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful bulk request with failures', + httpReq: { + url: 'https://a.mktorest.com/bulk/v1/leads/batch/12345/failures.json', + method: 'GET', + }, + httpRes: { + data: 'data \n data', + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful bearer token request', + httpReq: { + url: 'https://testMunchkin1.mktorest.com/identity/oauth/token?client_id=b&client_secret=c&grant_type=client_credentials', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'access_token_success', + expires_in: 3599, + scope: 'integrations@rudderstack.com', + token_type: 'bearer', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful get request to get list of fields', + httpReq: { + url: 'https://testMunchkin1.mktorest.com/rest/v1/leads/describe2.json', + method: 'GET', + }, + httpRes: { + data: { + requestId: '7fa1#17fd1da66fe', + result: [ + { + name: 'API Lead', + searchableFields: [['email']], + fields: [ + { + name: 'email', + displayName: 'Email Address', + dataType: 'email', + length: 255, + updateable: true, + crmManaged: false, + }, + ], + }, + ], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed bulk request with 603 error code', + httpReq: { + url: 'https://testMunchkin1.mktorest.com/bulk/v1/leads.json', + method: 'GET', + }, + httpRes: { + data: { + success: false, + errors: [ + { + code: 603, + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful bearer token request', + httpReq: { + url: 'https://testMunchkin2.mktorest.com/identity/oauth/token?client_id=b&client_secret=c&grant_type=client_credentials', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'access_token_success', + expires_in: 3599, + scope: 'integrations@rudderstack.com', + token_type: 'bearer', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful get request to get list of fields', + httpReq: { + url: 'https://testMunchkin2.mktorest.com/rest/v1/leads/describe2.json', + method: 'GET', + }, + httpRes: { + data: { + requestId: '7fa1#17fd1da66fe', + result: [ + { + name: 'API Lead', + searchableFields: [['email']], + fields: [ + { + name: 'Email', + displayName: 'Email Address', + dataType: 'email', + length: 255, + updateable: true, + crmManaged: false, + }, + ], + }, + ], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed leads query request with pending import error', + httpReq: { + url: 'https://testMunchkin2.mktorest.com/bulk/v1/leads.json', + method: 'GET', + }, + httpRes: { + data: { + success: false, + errors: [ + { + message: 'There are 10 imports currently being processed. Please try again later', + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a succesful leads query request', + httpReq: { + url: 'https://testMunchkin3.mktorest.com/rest/v1/leads/describe2.json', + method: 'GET', + }, + httpRes: { + data: { + requestId: '7fa1#17fd1da66fe', + result: [ + { + name: 'API Lead', + searchableFields: [['email']], + fields: [ + { + name: 'Email', + displayName: 'Email Address', + dataType: 'email', + length: 255, + updateable: true, + crmManaged: false, + }, + ], + }, + ], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed leads query request with empty file error', + httpReq: { + url: 'https://testMunchkin3.mktorest.com/bulk/v1/leads.json', + method: 'GET', + }, + httpRes: { + data: { + success: false, + errors: [ + { + message: 'Empty file', + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful leads query request', + httpReq: { + url: 'https://testMunchkin4.mktorest.com/rest/v1/leads/describe2.json', + method: 'GET', + }, + httpRes: { + data: { + requestId: '7fa1#17fd1da66fe', + result: [ + { + name: 'API Lead', + searchableFields: [['email']], + fields: [ + { + name: 'Email', + displayName: 'Email Address', + dataType: 'email', + length: 255, + updateable: true, + crmManaged: false, + }, + ], + }, + ], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed leads query request with any other error', + httpReq: { + url: 'https://testMunchkin4.mktorest.com/bulk/v1/leads.json', + method: 'GET', + }, + httpRes: { + data: { + success: false, + errors: [ + { + message: 'Any other error', + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a succesful bearer token request', + httpReq: { + url: 'https://valid_account_broken_event.mktorest.com/identity/oauth/token', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'access_token_success', + expires_in: 3599, + scope: 'integrations@rudderstack.com', + token_type: 'bearer', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: + 'Mock response for a successful get request with filterType=email and filterValues specified with no results', + httpReq: { + url: 'https://valid_account_broken_event.mktorest.com/rest/v1/leads.json?filterType=email&filterValues=0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail', + method: 'GET', + }, + httpRes: { + data: { + requestId: '12093#17672aeaee6', + result: [], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed get request due to missing lookup field', + httpReq: { + url: 'https://valid_account_broken_event.mktorest.com/rest/v1/leads.json', + method: 'GET', + }, + httpRes: { + data: { + requestId: '142e4#1835b117b76', + success: false, + errors: [ + { + code: '1006', + message: "Lookup field 'userId' not found", + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful bearer token request', + httpReq: { + url: 'https://unhandled_status_code.mktorest.com/identity/oauth/token', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'access_token_success', + expires_in: 3599, + scope: 'integrations@rudderstack.com', + token_type: 'bearer', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: + 'Mock response for a successful get request with filterType=email and filterValues specified with no results', + httpReq: { + url: 'https://unhandled_status_code.mktorest.com/rest/v1/leads.json?filterType=email&filterValues=0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail', + method: 'GET', + }, + httpRes: { + data: { + requestId: '12093#17672aeaee6', + result: [], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed get request due to random marketo error code', + httpReq: { + url: 'https://unhandled_status_code.mktorest.com/rest/v1/leads.json', + method: 'GET', + }, + httpRes: { + data: { + requestId: '142e4#1835b117b76', + success: false, + errors: [ + { + code: 'random_marketo_code', + message: 'some other problem', + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a successful bearer token request', + httpReq: { + url: 'https://successful_identify_transformation.mktorest.com/identity/oauth/token', + method: 'GET', + }, + httpRes: { + data: { + access_token: 'access_token_success', + expires_in: 3599, + scope: 'integrations@rudderstack.com', + token_type: 'bearer', + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: + 'Mock response for a successful get request with no filterType and filterValues specified', + httpReq: { + url: 'https://successful_identify_transformation.mktorest.com/rest/v1/leads.json', + method: 'GET', + }, + httpRes: { + data: { + requestId: '7ab2#17672a46a99', + result: [ + { + id: 4, + status: 'created', + }, + ], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: + 'Mock response for a successful get request with filterType=email and filterValues specified with results', + httpReq: { + url: 'https://successful_identify_transformation.mktorest.com/rest/v1/leads.json?filterType=email&filterValues=0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail', + method: 'GET', + }, + httpRes: { + data: { + requestId: '12093#17672aeaee6', + result: [ + { + createdAt: '2022-09-17T21:39:07Z', + email: '0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail', + firstName: 'random_first', + id: 4, + lastName: 'random_last', + updatedAt: '2022-09-20T21:48:07Z', + userId: 'test-user-957ue', + }, + ], + success: true, + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed lead request due to invalid header', + httpReq: { + url: 'https://mktId.mktorest.com/rest/v1/leads.json/test_invalid_header', + headers: { + Authorization: 'Bearer test_token_6', + 'Content-Type': 'invalid', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: { + success: false, + errors: [ + { + code: '612', + message: 'Invalid Content Type', + }, + ], + }, + status: 200, + statusText: 'OK', + }, + }, + { + description: 'Mock response for a failed lead request due to length exceeded', + httpReq: { + url: 'https://mktId.mktorest.com/rest/v1/leads.json/test_exceeded_length', + headers: { + Authorization: 'Bearer test_token_6', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: { + success: false, + errors: [ + { + code: '1077', + message: 'Value for field exceeds max length', + }, + ], + }, + status: 400, + statusText: 'OK', + }, + }, +]; + +export const networkCallsData = [...businessMockData, ...tfProxyMocksData]; diff --git a/test/integrations/destinations/marketo_bulk_upload/processor/data.ts b/test/integrations/destinations/marketo_bulk_upload/processor/data.ts index 5f3f2ccb582..90a3ca8584a 100644 --- a/test/integrations/destinations/marketo_bulk_upload/processor/data.ts +++ b/test/integrations/destinations/marketo_bulk_upload/processor/data.ts @@ -1,499 +1,598 @@ export const data = [ - { - "name": "marketo_bulk_upload", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "type": "identify", - "traits": { - "name": "Carlo Lombard", - "plan": "Quarterly Team+ Plan for Enuffsaid Media", - "email": "carlo@enuffsaid.media" - }, - "userId": 476335, - "context": { - "ip": "14.0.2.238", - "page": { - "url": "enuffsaid.proposify.com", - "path": "/settings", - "method": "POST", - "referrer": "https://enuffsaid.proposify.com/login" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "786dfec9-jfh", - "messageId": "5d9bc6e2-ekjh" - }, - "destination": { - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", - "Config": { - "munchkinId": "XXXX", - "clientId": "YYYY", - "clientSecret": "ZZZZ", - "columnFieldsMapping": [ - { - "to": "name__c", - "from": "name" - }, - { - "to": "email__c", - "from": "email" - }, - { - "to": "plan__c", - "from": "plan" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "/fileUpload", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "name__c": "Carlo Lombard", - "email__c": "carlo@enuffsaid.media", - "plan__c": "Quarterly Team+ Plan for Enuffsaid Media" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "marketo_bulk_upload", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "traits": { - "name": "Carlo Lombard", - "plan": "Quarterly Team+ Plan for Enuffsaid Media", - "email": "carlo@enuffsaid.media" - }, - "userId": 476335, - "context": { - "ip": "14.0.2.238", - "page": { - "url": "enuffsaid.proposify.com", - "path": "/settings", - "method": "POST", - "referrer": "https://enuffsaid.proposify.com/login" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "786dfec9-jfh", - "messageId": "5d9bc6e2-ekjh" - }, - "destination": { - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", - "Config": { - "munchkinId": "XXXX", - "clientId": "YYYY", - "clientSecret": "ZZZZ", - "columnFieldsMapping": [ - { - "to": "name__c", - "from": "name" - }, - { - "to": "email__c", - "from": "email" - }, - { - "to": "plan__c", - "from": "plan" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Event type is required", - "statTags": { - "destType": "MARKETO_BULK_UPLOAD", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "marketo_bulk_upload", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "type": "track", - "traits": { - "name": "Carlo Lombard", - "plan": "Quarterly Team+ Plan for Enuffsaid Media", - "email": "carlo@enuffsaid.media" - }, - "userId": 476335, - "context": { - "ip": "14.0.2.238", - "page": { - "url": "enuffsaid.proposify.com", - "path": "/settings", - "method": "POST", - "referrer": "https://enuffsaid.proposify.com/login" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "786dfec9-jfh", - "messageId": "5d9bc6e2-ekjh" - }, - "destination": { - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", - "Config": { - "munchkinId": "XXXX", - "clientId": "YYYY", - "clientSecret": "ZZZZ", - "columnFieldsMapping": [ - { - "to": "name__c", - "from": "name" - }, - { - "to": "email__c", - "from": "email" - }, - { - "to": "plan__c", - "from": "plan" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Event type track is not supported", - "statTags": { - "destType": "MARKETO_BULK_UPLOAD", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "marketo_bulk_upload", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "type": "identify", - "traits": { - "name": "Carlo Lombard", - "plan": "Quarterly Team+ Plan for Enuffsaid Media", - "email": "carlo@enuffsaid.media" - }, - "userId": 476335, - "context": { - "ip": "14.0.2.238", - "page": { - "url": "enuffsaid.proposify.com", - "path": "/settings", - "method": "POST", - "referrer": "https://enuffsaid.proposify.com/login" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "786dfec9-jfh", - "messageId": "5d9bc6e2-ekjh" - }, - "destination": { - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", - "Config": { - "munchkinId": "XXXX", - "clientId": "YYYY", - "clientSecret": "ZZZZ", - "columnFieldsMapping": [ - { - "to": "name__c", - "from": "1" - }, - { - "to": "email__c", - "from": "email1" - }, - { - "to": "plan__c", - "from": "plan1" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "/fileUpload", - "headers": {}, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "marketo_bulk_upload", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "type": "identify", - "traits": { - "name": "Carlo Lombard", - "plan": "Quarterly Team+ Plan for Enuffsaid Media", - "email": "carlo@enuffsaid.media" - }, - "userId": 476335, - "context": { - "ip": "14.0.2.238", - "page": { - "url": "enuffsaid.proposify.com", - "path": "/settings", - "method": "POST", - "referrer": "https://enuffsaid.proposify.com/login" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "786dfec9-jfh", - "messageId": "5d9bc6e2-ekjh" - }, - "destination": { - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", - "Config": { - "munchkinId": "XXXX", - "clientId": "YYYY", - "clientSecret": "ZZZZ", - "columnFieldsMapping": [ - { - "to": "name__c", - "from": "name" - }, - { - "to": "email__c", - "from": "email1" - }, - { - "to": "plan__c", - "from": "plan1" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "/fileUpload", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "name__c": "Carlo Lombard" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "marketo_bulk_upload", - "description": "Test 5", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "type": "identify", - "traits": { - "name": "Carlo Lombard", - "plan": 1 - }, - "userId": 476335, - "context": { - "ip": "14.0.2.238", - "page": { - "url": "enuffsaid.proposify.com", - "path": "/settings", - "method": "POST", - "referrer": "https://enuffsaid.proposify.com/login" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "786dfec9-jfh", - "messageId": "5d9bc6e2-ekjh" - }, - "destination": { - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", - "Config": { - "munchkinId": "XXXX", - "clientId": "YYYY", - "clientSecret": "ZZZZ", - "columnFieldsMapping": [ - { - "to": "name__c", - "from": "name" - }, - { - "to": "email__c", - "from": "email" - }, - { - "to": "plan__c", - "from": "plan" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "/fileUpload", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "name__c": "Carlo Lombard", - "plan__c": 1 - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - } -] + { + name: 'marketo_bulk_upload', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'identify', + traits: { + name: 'Carlo Lombard', + plan: 'Quarterly Team+ Plan for Enuffsaid Media', + email: 'carlo@enuffsaid.media', + }, + userId: 476335, + context: { + ip: '14.0.2.238', + page: { + url: 'enuffsaid.proposify.com', + path: '/settings', + method: 'POST', + referrer: 'https://enuffsaid.proposify.com/login', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '786dfec9-jfh', + messageId: '5d9bc6e2-ekjh', + }, + destination: { + ID: '1mMy5cqbtfuaKZv1IhVQKnBdVwe', + Config: { + munchkinId: 'XXXX', + clientId: 'YYYY', + clientSecret: 'ZZZZ', + columnFieldsMapping: [ + { + to: 'name__c', + from: 'name', + }, + { + to: 'email__c', + from: 'email', + }, + { + to: 'plan__c', + from: 'plan', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: '/fileUpload', + headers: {}, + params: {}, + body: { + JSON: { + name__c: 'Carlo Lombard', + email__c: 'carlo@enuffsaid.media', + plan__c: 'Quarterly Team+ Plan for Enuffsaid Media', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'marketo_bulk_upload', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + traits: { + name: 'Carlo Lombard', + plan: 'Quarterly Team+ Plan for Enuffsaid Media', + email: 'carlo@enuffsaid.media', + }, + userId: 476335, + context: { + ip: '14.0.2.238', + page: { + url: 'enuffsaid.proposify.com', + path: '/settings', + method: 'POST', + referrer: 'https://enuffsaid.proposify.com/login', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '786dfec9-jfh', + messageId: '5d9bc6e2-ekjh', + }, + destination: { + ID: '1mMy5cqbtfuaKZv1IhVQKnBdVwe', + Config: { + munchkinId: 'XXXX', + clientId: 'YYYY', + clientSecret: 'ZZZZ', + columnFieldsMapping: [ + { + to: 'name__c', + from: 'name', + }, + { + to: 'email__c', + from: 'email', + }, + { + to: 'plan__c', + from: 'plan', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Event type is required', + statTags: { + destType: 'MARKETO_BULK_UPLOAD', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'marketo_bulk_upload', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + traits: { + name: 'Carlo Lombard', + plan: 'Quarterly Team+ Plan for Enuffsaid Media', + email: 'carlo@enuffsaid.media', + }, + userId: 476335, + context: { + ip: '14.0.2.238', + page: { + url: 'enuffsaid.proposify.com', + path: '/settings', + method: 'POST', + referrer: 'https://enuffsaid.proposify.com/login', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '786dfec9-jfh', + messageId: '5d9bc6e2-ekjh', + }, + destination: { + ID: '1mMy5cqbtfuaKZv1IhVQKnBdVwe', + Config: { + munchkinId: 'XXXX', + clientId: 'YYYY', + clientSecret: 'ZZZZ', + columnFieldsMapping: [ + { + to: 'name__c', + from: 'name', + }, + { + to: 'email__c', + from: 'email', + }, + { + to: 'plan__c', + from: 'plan', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Event type track is not supported', + statTags: { + destType: 'MARKETO_BULK_UPLOAD', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'marketo_bulk_upload', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'identify', + traits: { + name: 'Carlo Lombard', + plan: 'Quarterly Team+ Plan for Enuffsaid Media', + email: 'carlo@enuffsaid.media', + }, + userId: 476335, + context: { + ip: '14.0.2.238', + page: { + url: 'enuffsaid.proposify.com', + path: '/settings', + method: 'POST', + referrer: 'https://enuffsaid.proposify.com/login', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '786dfec9-jfh', + messageId: '5d9bc6e2-ekjh', + }, + destination: { + ID: '1mMy5cqbtfuaKZv1IhVQKnBdVwe', + Config: { + munchkinId: 'XXXX', + clientId: 'YYYY', + clientSecret: 'ZZZZ', + columnFieldsMapping: [ + { + to: 'name__c', + from: '1', + }, + { + to: 'email__c', + from: 'email1', + }, + { + to: 'plan__c', + from: 'plan1', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: '/fileUpload', + headers: {}, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'marketo_bulk_upload', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'identify', + traits: { + name: 'Carlo Lombard', + plan: 'Quarterly Team+ Plan for Enuffsaid Media', + email: 'carlo@enuffsaid.media', + }, + userId: 476335, + context: { + ip: '14.0.2.238', + page: { + url: 'enuffsaid.proposify.com', + path: '/settings', + method: 'POST', + referrer: 'https://enuffsaid.proposify.com/login', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '786dfec9-jfh', + messageId: '5d9bc6e2-ekjh', + }, + destination: { + ID: '1mMy5cqbtfuaKZv1IhVQKnBdVwe', + Config: { + munchkinId: 'XXXX', + clientId: 'YYYY', + clientSecret: 'ZZZZ', + columnFieldsMapping: [ + { + to: 'name__c', + from: 'name', + }, + { + to: 'email__c', + from: 'email1', + }, + { + to: 'plan__c', + from: 'plan1', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: '/fileUpload', + headers: {}, + params: {}, + body: { + JSON: { + name__c: 'Carlo Lombard', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'marketo_bulk_upload', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'identify', + traits: { + name: 'Carlo Lombard', + plan: 1, + }, + userId: 476335, + context: { + ip: '14.0.2.238', + page: { + url: 'enuffsaid.proposify.com', + path: '/settings', + method: 'POST', + referrer: 'https://enuffsaid.proposify.com/login', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '786dfec9-jfh', + messageId: '5d9bc6e2-ekjh', + }, + destination: { + ID: '1mMy5cqbtfuaKZv1IhVQKnBdVwe', + Config: { + munchkinId: 'XXXX', + clientId: 'YYYY', + clientSecret: 'ZZZZ', + columnFieldsMapping: [ + { + to: 'name__c', + from: 'name', + }, + { + to: 'email__c', + from: 'email', + }, + { + to: 'plan__c', + from: 'plan', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: '/fileUpload', + headers: {}, + params: {}, + body: { + JSON: { + name__c: 'Carlo Lombard', + plan__c: 1, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'marketo_bulk_upload', + description: 'Test 5: Any null or zero value will be passed through transform payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'identify', + traits: { + name: 'Carlo Lombard', + plan: 0, + id: null, + }, + userId: 476335, + context: { + ip: '14.0.2.238', + page: { + url: 'enuffsaid.proposify.com', + path: '/settings', + method: 'POST', + referrer: 'https://enuffsaid.proposify.com/login', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '786dfec9-jfh', + messageId: '5d9bc6e2-ekjh', + }, + destination: { + ID: '1mMy5cqbtfuaKZv1IhVQKnBdVwe', + Config: { + munchkinId: 'XXXX', + clientId: 'YYYY', + clientSecret: 'ZZZZ', + columnFieldsMapping: [ + { + to: 'name__c', + from: 'name', + }, + { + to: 'email__c', + from: 'email', + }, + { + to: 'plan__c', + from: 'plan', + }, + { + to: 'id', + from: 'id', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: '/fileUpload', + headers: {}, + params: {}, + body: { + JSON: { + name__c: 'Carlo Lombard', + plan__c: 0, + id: null, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/marketo_static_list/dataDelivery/business.ts b/test/integrations/destinations/marketo_static_list/dataDelivery/business.ts new file mode 100644 index 00000000000..08be877ba84 --- /dev/null +++ b/test/integrations/destinations/marketo_static_list/dataDelivery/business.ts @@ -0,0 +1,255 @@ +import { ProxyMetdata } from '../../../../../src/types'; +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV1Payload } from '../../../testUtils'; + +export const statTags = { + aborted: { + destType: 'MARKETO_STATIC_LIST', + destinationId: 'dummyDestinationId', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'dummyWorkspaceId', + }, + retryable: { + destType: 'MARKETO_STATIC_LIST', + destinationId: 'default-destinationId', + errorCategory: 'network', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'default-workspaceId', + }, + throttled: { + destType: 'MARKETO_STATIC_LIST', + destinationId: 'dummyDestinationId', + errorCategory: 'network', + errorType: 'throttled', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'dummyWorkspaceId', + }, +}; + +export const proxyMetdata: ProxyMetdata = { + jobId: 1, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + secret: {}, + dontBatch: false, +}; + +export const reqMetadataArray = [proxyMetdata]; +const params = { + destination: 'marketo_static_list', +}; + +const commonRequestParameters = { + params, + userId: '', + body: { + FORM: {}, + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + }, + files: {}, +}; + +export const testScenariosForV1API: ProxyV1TestData[] = [ + { + id: 'msl_v1_scenario_1', + name: 'marketo_static_list', + description: '[Proxy v1 API] :: Test for a partial successful request with multiple ids', + successCriteria: 'Should return a 200 status code with respective status for each record id', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + headers: { + Authorization: 'Bearer Incorrect_token', + 'Content-Type': 'application/json', + }, + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=110&id=111&id=112', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + response: [ + { + error: + '{"requestId":"b6d1#18a8d2c10e7","result":[{"id":110,"status":"skipped","reasons":[{"code":"1015","message":"Lead not in list"}]},{"id":111,"status":"removed"},{"id":112,"status":"removed"}],"success":true}', + metadata: proxyMetdata, + statusCode: 200, + }, + ], + }, + }, + }, + }, + }, + { + id: 'msl_v1_scenario_2', + name: 'marketo_static_list', + description: '[Proxy v1 API] :: Test for Access token invalid scenario', + successCriteria: 'Should return a 500 status code with message Access token invalid', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + headers: { + Authorization: 'Bearer Incorrect_token', + 'Content-Type': 'application/json', + }, + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2&id=3', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 500, + statTags: statTags.retryable, + message: + 'Request Failed for Marketo Static List, Access token invalid (Retryable).during Marketo Static List Response Handling', + response: [ + { + error: + '{"requestId":"68d8#1846058ee27","success":false,"errors":[{"code":"601","message":"Access token invalid"}]}', + metadata: proxyMetdata, + statusCode: 500, + }, + ], + }, + }, + }, + }, + }, + { + id: 'msl_v1_scenario_3', + name: 'marketo_static_list', + description: '[Proxy v1 API] :: Test for a complete successful request with multiple ids', + successCriteria: + 'Should return a 200 status code with respective added status for each record id', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + headers: { + Authorization: 'Bearer token', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + response: [ + { + error: + '{"requestId":"12d3c#1846057dce2","result":[{"id":1,"status":"added"},{"id":2,"status":"added"}],"success":true}', + metadata: proxyMetdata, + statusCode: 200, + }, + ], + }, + }, + }, + }, + }, + { + id: 'msl_v1_scenario_4', + name: 'marketo_static_list', + description: '[Proxy v1 API] :: Test for DNS lookup failed scenario', + successCriteria: 'Should return a 400 status code with empty response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + headers: { + Authorization: 'Bearer test_token_6', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + endpoint: 'https://mktId.mktorest.com/rest/v1/leads.json/test6', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 500, + statTags: statTags.retryable, + message: 'Request failed with status: 500', + response: [ + { + error: '""', + metadata: proxyMetdata, + statusCode: 500, + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/marketo_static_list/dataDelivery/data.ts b/test/integrations/destinations/marketo_static_list/dataDelivery/data.ts index 0ac91235924..c0398f6d2b8 100644 --- a/test/integrations/destinations/marketo_static_list/dataDelivery/data.ts +++ b/test/integrations/destinations/marketo_static_list/dataDelivery/data.ts @@ -1,368 +1,320 @@ -export const data = [ +import { testScenariosForV1API } from './business'; +import { otherScenariosV1 } from './other'; + +const legacyTests = [ { - "name": "marketo_static_list", - "description": "Test 0", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "type": "REST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=110&id=111&id=112", - "method": "POST", - "userId": "", - "headers": { - "Authorization": "Bearer Incorrect_token", - "Content-Type": "application/json" + name: 'marketo_static_list', + description: 'Test 0', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + type: 'REST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=110&id=111&id=112', + method: 'POST', + userId: '', + headers: { + Authorization: 'Bearer Incorrect_token', + 'Content-Type': 'application/json', }, - "body": { - "FORM": {}, - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {} + body: { + FORM: {}, + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + }, + files: {}, + params: { + destination: 'marketo_static_list', }, - "files": {}, - "params": { - "destination": "marketo_static_list" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 200, - "body": { - "output": { - "message": "Request Processed Successfully", - "destinationResponse": { - "response": { - "requestId": "b6d1#18a8d2c10e7", - "result": [ + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + destinationResponse: { + response: { + requestId: 'b6d1#18a8d2c10e7', + result: [ { - "id": 110, - "status": "skipped", - "reasons": [ + id: 110, + status: 'skipped', + reasons: [ { - "code": "1015", - "message": "Lead not in list" - } - ] + code: '1015', + message: 'Lead not in list', + }, + ], }, { - "id": 111, - "status": "removed" + id: 111, + status: 'removed', }, { - "id": 112, - "status": "removed" - } + id: 112, + status: 'removed', + }, ], - "success": true + success: true, }, - "status": 200 + status: 200, }, - "status": 200 - } - } - } - } + status: 200, + }, + }, + }, + }, }, { - "name": "marketo_static_list", - "description": "Test 1", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "type": "REST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2&id=3", - "method": "POST", - "userId": "", - "headers": { - "Authorization": "Bearer Incorrect_token", - "Content-Type": "application/json" + name: 'marketo_static_list', + description: 'Test 1', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + type: 'REST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2&id=3', + method: 'POST', + userId: '', + headers: { + Authorization: 'Bearer Incorrect_token', + 'Content-Type': 'application/json', + }, + body: { + FORM: {}, + JSON: {}, + JSON_ARRAY: {}, + XML: {}, }, - "body": { - "FORM": {}, - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {} + files: {}, + params: { + destination: 'marketo_static_list', }, - "files": {}, - "params": { - "destination": "marketo_static_list" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 500, - "body": { - "output": { - "status": 500, - "message": "Request Failed for Marketo Static List, Access token invalid (Retryable).during Marketo Static List Response Handling", - "destinationResponse": { - "response": { - "requestId": "68d8#1846058ee27", - "success": false, - "errors": [ + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: + 'Request Failed for Marketo Static List, Access token invalid (Retryable).during Marketo Static List Response Handling', + destinationResponse: { + response: { + requestId: '68d8#1846058ee27', + success: false, + errors: [ { - "code": "601", - "message": "Access token invalid" - } - ] + code: '601', + message: 'Access token invalid', + }, + ], }, - "status": 200 + status: 200, }, - "statTags": { - "destType": "MARKETO_STATIC_LIST", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "retryable", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } + statTags: { + destType: 'MARKETO_STATIC_LIST', + errorCategory: 'network', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + }, + }, + }, + }, + }, }, { - "name": "marketo_static_list", - "description": "Test 2", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "type": "REST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2", - "method": "POST", - "userId": "", - "headers": { - "Authorization": "Bearer token", - "Content-Type": "application/json" + name: 'marketo_static_list', + description: 'Test 2', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + type: 'REST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2', + method: 'POST', + userId: '', + headers: { + Authorization: 'Bearer token', + 'Content-Type': 'application/json', }, - "body": { - "FORM": {}, - "JSON": { - "action": "createOrUpdate", - "input": [ - { - "City": "Tokyo", - "Country": "JP", - "Email": "gabi29@gmail.com", - "PostalCode": "100-0001", - "Title": "Owner", - "id": 1328328, - "userId": "gabi_userId_45" - } - ], - "lookupField": "id" - }, - "JSON_ARRAY": {}, - "XML": {} + body: { + FORM: {}, + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + }, + files: {}, + params: { + destination: 'marketo_static_list', }, - "files": {}, - "params": { - "destination": "marketo_static_list" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 200, - "body": { - "output": { - "status": 200, - "message": "Request Processed Successfully", - "destinationResponse": { - "response": { - "requestId": "12d3c#1846057dce2", - "success": true, - "result": [ + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + destinationResponse: { + response: { + requestId: '12d3c#1846057dce2', + success: true, + result: [ { - "id": 1, - "status": "added" + id: 1, + status: 'added', }, { - "id": 2, - "status": "added" - } - ] + id: 2, + status: 'added', + }, + ], }, - "status": 200 - } - } - } - } - } + status: 200, + }, + }, + }, + }, + }, }, { - "name": "marketo_static_list", - "description": "Test 3", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "type": "REST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=3&id=4", - "method": "POST", - "userId": "", - "headers": { - "Authorization": "Bearer token", - "Content-Type": "application/json" + name: 'marketo_static_list', + description: 'Test 3', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + type: 'REST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=3&id=4', + method: 'POST', + userId: '', + headers: { + Authorization: 'Bearer token', + 'Content-Type': 'application/json', }, - "params": {}, - "body": { - "FORM": {}, - "JSON": { - "action": "createOrUpdate", - "input": [ - { - "City": "Tokyo", - "Country": "JP", - "Email": "gabi29@gmail.com", - "PostalCode": "100-0001", - "Title": "Owner", - "id": 1328328, - "userId": "gabi_userId_45" - }, - { - "City": "Tokyo", - "Country": "JP", - "Email": "b@s.com", - "PostalCode": "100-0001", - "Title": "Owner", - "id": 1328329, - "userId": "ben_userId_45" - } - ], - "lookupField": "id" - }, - "JSON_ARRAY": {}, - "XML": {} + params: {}, + body: { + FORM: {}, + JSON: {}, + JSON_ARRAY: {}, + XML: {}, }, - "files": {} + files: {}, }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 400, - "body": { - "output": { - "destinationResponse": "", - "message": "Request failed during: during Marketo Static List Response Handling, error: [{\"code\":\"1004\",\"message\":\"Lead not found\"}]", - "statTags": { - "destType": "MARKETO_STATIC_LIST", - "errorCategory": "dataValidation", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "instrumentation", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: '', + message: + 'Request failed during: during Marketo Static List Response Handling, error: [{"code":"1004","message":"Lead not found"}]', + statTags: { + destType: 'MARKETO_STATIC_LIST', + errorCategory: 'dataValidation', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + errorType: 'instrumentation', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', }, - "status": 400 - } - } - } - } + status: 400, + }, + }, + }, + }, }, { - "name": "marketo_static_list", - "description": "Test 4", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "type": "REST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=5&id=6", - "method": "POST", - "userId": "", - "headers": { - "Authorization": "Bearer token", - "Content-Type": "application/json" + name: 'marketo_static_list', + description: 'Test 4', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + type: 'REST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=5&id=6', + method: 'POST', + userId: '', + headers: { + Authorization: 'Bearer token', + 'Content-Type': 'application/json', }, - "params": {}, - "body": { - "FORM": {}, - "JSON": { - "action": "createOrUpdate", - "input": [ - { - "City": "Tokyo", - "Country": "JP", - "Email": "gabi29@gmail.com", - "PostalCode": "100-0001", - "Title": "Owner", - "id": 1328328, - "userId": "gabi_userId_45" - }, - { - "City": "Tokyo", - "Country": "JP", - "Email": "b@s.com", - "PostalCode": "100-0001", - "Title": "Owner", - "id": 1328329, - "userId": "ben_userId_45" - } - ], - "lookupField": "id" - }, - "JSON_ARRAY": {}, - "XML": {} + params: {}, + body: { + FORM: {}, + JSON: {}, + JSON_ARRAY: {}, + XML: {}, }, - "files": {} + files: {}, }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 200, - "body": { - "output": { - "status": 200, - "message": "Request Processed Successfully", - "destinationResponse": { - "response": { - "requestId": "12d3c#1846057dce2", - "result": { - "id": 5, - "status": "skipped", - "reasons": [ + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + destinationResponse: { + response: { + requestId: '12d3c#1846057dce2', + result: { + id: 5, + status: 'skipped', + reasons: [ { - "code": "1015", - "message": "Lead not in list" - } - ] + code: '1015', + message: 'Lead not in list', + }, + ], }, - "success": true + success: true, }, - "status": 200 - } - } - } - } - } - } -] + status: 200, + }, + }, + }, + }, + }, + }, +]; + +export const data = [...legacyTests, ...testScenariosForV1API, ...otherScenariosV1]; diff --git a/test/integrations/destinations/marketo_static_list/dataDelivery/other.ts b/test/integrations/destinations/marketo_static_list/dataDelivery/other.ts new file mode 100644 index 00000000000..b1f3403fa6f --- /dev/null +++ b/test/integrations/destinations/marketo_static_list/dataDelivery/other.ts @@ -0,0 +1,194 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV1Payload, generateMetadata } from '../../../testUtils'; +import { reqMetadataArray, statTags } from './business'; + +export const otherScenariosV1: ProxyV1TestData[] = [ + { + id: 'marketo_static_list_v1_other_scenario_1', + name: 'marketo_static_list', + description: + '[Proxy v1 API] :: Scenario for testing Service Unavailable error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_service_not_available', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: + '{"error":{"message":"Service Unavailable","description":"The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later."}}', + statusCode: 503, + metadata: generateMetadata(1), + }, + ], + statTags: statTags.retryable, + message: 'Request failed with status: 503', + status: 503, + }, + }, + }, + }, + }, + { + id: 'marketo_static_list_v1_other_scenario_2', + name: 'marketo_static_list', + description: '[Proxy v1 API] :: Scenario for testing Internal Server error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_internal_server_error', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Internal Server Error"', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: statTags.retryable, + message: 'Request failed with status: 500', + status: 500, + }, + }, + }, + }, + }, + { + id: 'marketo_static_list_v1_other_scenario_3', + name: 'marketo_static_list', + description: '[Proxy v1 API] :: Scenario for testing Gateway Time Out error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_gateway_time_out', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Gateway Timeout"', + statusCode: 504, + metadata: generateMetadata(1), + }, + ], + statTags: statTags.retryable, + message: 'Request failed with status: 504', + status: 504, + }, + }, + }, + }, + }, + { + id: 'marketo_static_list_v1_other_scenario_4', + name: 'marketo_static_list', + description: '[Proxy v1 API] :: Scenario for testing null response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_response', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: statTags.retryable, + message: 'Request failed with status: 500', + status: 500, + }, + }, + }, + }, + }, + { + id: 'marketo_static_list_v1_other_scenario_5', + name: 'marketo_static_list', + description: + '[Proxy v1 API] :: Scenario for testing null and no status response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_and_no_status', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: statTags.retryable, + message: 'Request failed with status: 500', + status: 500, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/marketo_static_list/network.ts b/test/integrations/destinations/marketo_static_list/network.ts index 5c132738595..f165291c15a 100644 --- a/test/integrations/destinations/marketo_static_list/network.ts +++ b/test/integrations/destinations/marketo_static_list/network.ts @@ -46,21 +46,6 @@ const deliveryCallsData = [ { httpReq: { url: 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2', - data: { - action: 'createOrUpdate', - input: [ - { - City: 'Tokyo', - Country: 'JP', - Email: 'gabi29@gmail.com', - PostalCode: '100-0001', - Title: 'Owner', - id: 1328328, - userId: 'gabi_userId_45', - }, - ], - lookupField: 'id', - }, params: { destination: 'marketo_static_list' }, headers: { Authorization: 'Bearer token', @@ -84,30 +69,6 @@ const deliveryCallsData = [ { httpReq: { url: 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=3&id=4', - data: { - action: 'createOrUpdate', - input: [ - { - City: 'Tokyo', - Country: 'JP', - Email: 'gabi29@gmail.com', - PostalCode: '100-0001', - Title: 'Owner', - id: 1328328, - userId: 'gabi_userId_45', - }, - { - City: 'Tokyo', - Country: 'JP', - Email: 'b@s.com', - PostalCode: '100-0001', - Title: 'Owner', - id: 1328329, - userId: 'ben_userId_45', - }, - ], - lookupField: 'id', - }, params: {}, headers: { Authorization: 'Bearer token', @@ -131,30 +92,6 @@ const deliveryCallsData = [ { httpReq: { url: 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=5&id=6', - data: { - action: 'createOrUpdate', - input: [ - { - City: 'Tokyo', - Country: 'JP', - Email: 'gabi29@gmail.com', - PostalCode: '100-0001', - Title: 'Owner', - id: 1328328, - userId: 'gabi_userId_45', - }, - { - City: 'Tokyo', - Country: 'JP', - Email: 'b@s.com', - PostalCode: '100-0001', - Title: 'Owner', - id: 1328329, - userId: 'ben_userId_45', - }, - ], - lookupField: 'id', - }, params: {}, headers: { Authorization: 'Bearer token', diff --git a/test/integrations/destinations/movable_ink/common.ts b/test/integrations/destinations/movable_ink/common.ts new file mode 100644 index 00000000000..f7eaa7af399 --- /dev/null +++ b/test/integrations/destinations/movable_ink/common.ts @@ -0,0 +1,128 @@ +import { Destination } from '../../../../src/types'; + +const destType = 'movable_ink'; +const destTypeInUpperCase = 'MOVABLE_INK'; +const displayName = 'Movable Ink'; +const channel = 'web'; +const destination: Destination = { + Config: { + endpoint: 'https://collector.movableink-dmz.com/behavioral/abc123', + accessKey: 'test-access-key', + accessSecret: 'test_access_secret', + }, + DestinationDefinition: { + DisplayName: displayName, + ID: '123', + Name: destTypeInUpperCase, + Config: { cdkV2Enabled: true }, + }, + Enabled: true, + ID: '123', + Name: destTypeInUpperCase, + Transformations: [], + WorkspaceID: 'test-workspace-id', +}; + +const processorInstrumentationErrorStatTags = { + destType: destTypeInUpperCase, + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', +}; + +const RouterInstrumentationErrorStatTags = { + ...processorInstrumentationErrorStatTags, + feature: 'router', +}; + +const traits = { + email: 'test@example.com', + firstName: 'John', + lastName: 'Doe', + phone: '1234567890', +}; + +const headers = { + 'Content-Type': 'application/json', + Authorization: 'Basic dGVzdC1hY2Nlc3Mta2V5OnRlc3RfYWNjZXNzX3NlY3JldA==', +}; + +const commonProperties = { + product_id: '622c6f5d5cf86a4c77358033', + sku: '8472-998-0112', + categories: [ + { url: 'https://example1', id: '1' }, + { url: 'https://example2', id: '2' }, + ], + name: 'Cones of Dunshire', + brand: 'Wyatt Games', + variant: 'expansion pack', + price: 49.99, + quantity: 5, + coupon: 'PREORDER15', + position: 1, + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.webp', +}; + +const customProperties = { + key1: 'value1', + key2: true, + key3: ['value3'], + key4: { key5: { key6: 'value6' } }, +}; + +const trackTestProperties = { + 'Product Added': { ...commonProperties, ...customProperties }, + 'Product Viewed': { ...commonProperties, ...customProperties }, + 'Order Completed': { + checkout_id: '70324a1f0eaf000000000000', + order_id: '40684e8f0eaf000000000000', + affiliation: 'Vandelay Games', + total: 52, + subtotal: 45, + revenue: 50, + shipping: 4, + tax: 3, + discount: 5, + coupon: 'NEWCUST5', + currency: 'USD', + products: [ + { + product_id: '622c6f5d5cf86a4c77358033', + sku: '8472-998-0112', + name: 'Cones of Dunshire', + price: 40, + position: 1, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + product_id: '577c6f5d5cf86a4c7735ba03', + sku: '3309-483-2201', + name: 'Five Crowns', + price: 5, + position: 2, + category: 'Games', + }, + ], + }, + 'Products Searched': { query: 'HDMI cable', url: 'https://www.website.com/product/path' }, + 'Custom event': { ...commonProperties, key1: 'value1', key2: true }, +}; + +export { + destType, + channel, + destination, + processorInstrumentationErrorStatTags, + RouterInstrumentationErrorStatTags, + traits, + headers, + trackTestProperties, +}; diff --git a/test/integrations/destinations/movable_ink/processor/data.ts b/test/integrations/destinations/movable_ink/processor/data.ts new file mode 100644 index 00000000000..45453c74cdf --- /dev/null +++ b/test/integrations/destinations/movable_ink/processor/data.ts @@ -0,0 +1,4 @@ +import { validation } from './validation'; +import { identify } from './identify'; +import { track } from './track'; +export const data = [...identify, ...track, ...validation]; diff --git a/test/integrations/destinations/movable_ink/processor/identify.ts b/test/integrations/destinations/movable_ink/processor/identify.ts new file mode 100644 index 00000000000..27186da05c2 --- /dev/null +++ b/test/integrations/destinations/movable_ink/processor/identify.ts @@ -0,0 +1,64 @@ +import { ProcessorTestData } from '../../../testTypes'; +import { generateMetadata, transformResultBuilder } from '../../../testUtils'; +import { destType, channel, destination, traits, headers } from '../common'; + +export const identify: ProcessorTestData[] = [ + { + id: 'MovableInk-identify-test-1', + name: destType, + description: 'Identify call with traits and anonymousId', + scenario: 'Framework+Business', + successCriteria: + 'Response should contain the input payload with few additional mappings configured in transformer and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'identify', + anonymousId: 'anonId123', + traits, + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'POST', + userId: '', + endpoint: destination.Config.endpoint, + headers, + JSON: { + type: 'identify', + userId: traits.email, + anonymousId: 'anonId123', + traits, + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + timestamp: 1709566376409, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/movable_ink/processor/track.ts b/test/integrations/destinations/movable_ink/processor/track.ts new file mode 100644 index 00000000000..5f30a3de83b --- /dev/null +++ b/test/integrations/destinations/movable_ink/processor/track.ts @@ -0,0 +1,189 @@ +import { ProcessorTestData } from '../../../testTypes'; +import { generateMetadata, transformResultBuilder } from '../../../testUtils'; +import { destType, channel, destination, headers, trackTestProperties } from '../common'; + +export const track: ProcessorTestData[] = [ + { + id: 'MovableInk-track-test-1', + name: destType, + description: 'Track call: Product Added event', + scenario: 'Framework+Business', + successCriteria: + 'Response should contain the input payload with few additional mappings configured in transformer and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + properties: trackTestProperties['Product Added'], + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'POST', + userId: '', + endpoint: destination.Config.endpoint, + headers, + JSON: { + type: 'track', + channel, + userId: 'userId123', + anonymousId: 'anonId123', + properties: trackTestProperties['Product Added'], + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + timestamp: 1709566376409, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'MovableInk-track-test-2', + name: destType, + description: 'Track call: Order Completed event', + scenario: 'Framework+Business', + successCriteria: + 'Response should contain the input payload with few additional mappings configured in transformer and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + properties: trackTestProperties['Order Completed'], + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'POST', + userId: '', + endpoint: destination.Config.endpoint, + headers, + JSON: { + type: 'track', + channel, + userId: 'userId123', + anonymousId: 'anonId123', + properties: trackTestProperties['Order Completed'], + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + timestamp: 1709566376409, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'MovableInk-track-test-3', + name: destType, + description: 'Track call: Custom event', + scenario: 'Framework+Business', + successCriteria: + 'Response should contain the input payload with few additional mappings configured in transformer and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + properties: trackTestProperties['Custom Event'], + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'POST', + userId: '', + endpoint: destination.Config.endpoint, + headers, + JSON: { + type: 'track', + channel, + userId: 'userId123', + anonymousId: 'anonId123', + properties: trackTestProperties['Custom Event'], + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + timestamp: 1709566376409, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/movable_ink/processor/validation.ts b/test/integrations/destinations/movable_ink/processor/validation.ts new file mode 100644 index 00000000000..ab6b123eb7d --- /dev/null +++ b/test/integrations/destinations/movable_ink/processor/validation.ts @@ -0,0 +1,217 @@ +import { ProcessorTestData } from '../../../testTypes'; +import { generateMetadata } from '../../../testUtils'; +import { destType, destination, processorInstrumentationErrorStatTags } from '../common'; + +export const validation: ProcessorTestData[] = [ + { + id: 'MovableInk-validation-test-1', + name: destType, + description: 'All of the required fields — userId, email, and anonymousId — are missing.', + scenario: 'Framework', + successCriteria: 'Instrumentation Error', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'identify', + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Either one of userId or email or anonymousId is required. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Either one of userId or email or anonymousId is required. Aborting', + metadata: generateMetadata(1), + statTags: processorInstrumentationErrorStatTags, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'MovableInk-validation-test-2', + name: destType, + description: 'Unsupported message type -> group', + scenario: 'Framework', + successCriteria: 'Instrumentation Error for Unsupported message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'group', + userId: 'userId123', + channel: 'mobile', + anonymousId: 'anon_123', + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'message type group is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type group is not supported', + metadata: generateMetadata(1), + statTags: processorInstrumentationErrorStatTags, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'MovableInk-validation-test-3', + name: destType, + description: 'Missing required field -> timestamp', + scenario: 'Framework', + successCriteria: 'Instrumentation Error', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'identify', + integrations: { + All: true, + }, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Timestamp is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Timestamp is not present. Aborting', + metadata: generateMetadata(1), + statTags: processorInstrumentationErrorStatTags, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'MovableInk-validation-test-4', + name: destType, + description: "Products Searched event - Missing 'query' property", + scenario: 'Framework', + successCriteria: 'Instrumentation Error', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + userId: 'user123', + integrations: { + All: true, + }, + event: 'Products Searched', + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + "Missing 'query' property in properties. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Missing 'query' property in properties. Aborting", + metadata: generateMetadata(1), + statTags: processorInstrumentationErrorStatTags, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'MovableInk-validation-test-5', + name: destType, + description: "Products Added event - Missing 'product_id' property", + scenario: 'Framework', + successCriteria: 'Instrumentation Error', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + userId: 'user123', + integrations: { + All: true, + }, + event: 'Product Added', + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + "Missing 'product_id' property in properties. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Missing 'product_id' property in properties. Aborting", + metadata: generateMetadata(1), + statTags: processorInstrumentationErrorStatTags, + statusCode: 400, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/movable_ink/router/data.ts b/test/integrations/destinations/movable_ink/router/data.ts new file mode 100644 index 00000000000..72df3d7074c --- /dev/null +++ b/test/integrations/destinations/movable_ink/router/data.ts @@ -0,0 +1,162 @@ +import { RouterTestData } from '../../../testTypes'; +import { RouterTransformationRequest } from '../../../../../src/types'; +import { generateMetadata } from '../../../testUtils'; +import { + destType, + channel, + destination, + traits, + headers, + trackTestProperties, + RouterInstrumentationErrorStatTags, +} from '../common'; + +const routerRequest: RouterTransformationRequest = { + input: [ + { + message: { + type: 'identify', + anonymousId: 'anonId123', + traits, + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + destination, + }, + { + message: { + type: 'identify', + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(2), + destination, + }, + { + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + properties: trackTestProperties['Product Added'], + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(3), + destination, + }, + { + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + properties: trackTestProperties['Custom Event'], + integrations: { + All: true, + }, + }, + metadata: generateMetadata(4), + destination, + }, + ], + destType, +}; + +export const data: RouterTestData[] = [ + { + id: 'MovableInk-router-test-1', + name: destType, + description: 'Basic Router Test to test multiple payloads', + scenario: 'Framework', + successCriteria: + 'Some events should be transformed successfully and some should fail for missing fields and status code should be 200', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: routerRequest, + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: destination.Config.endpoint, + headers, + params: {}, + body: { + JSON: { + events: [ + { + type: 'identify', + userId: traits.email, + anonymousId: 'anonId123', + traits, + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + timestamp: 1709566376409, + }, + { + type: 'track', + channel, + userId: 'userId123', + anonymousId: 'anonId123', + properties: trackTestProperties['Product Added'], + integrations: { + All: true, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + timestamp: 1709566376409, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + metadata: [generateMetadata(1), generateMetadata(3)], + batched: true, + statusCode: 200, + destination, + }, + { + metadata: [generateMetadata(2)], + batched: false, + statusCode: 400, + error: 'Either one of userId or email or anonymousId is required. Aborting', + statTags: RouterInstrumentationErrorStatTags, + destination, + }, + { + metadata: [generateMetadata(4)], + batched: false, + statusCode: 400, + error: 'Timestamp is not present. Aborting', + statTags: RouterInstrumentationErrorStatTags, + destination, + }, + ], + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/mp/common.ts b/test/integrations/destinations/mp/common.ts index fbba162b989..d40afa0c02e 100644 --- a/test/integrations/destinations/mp/common.ts +++ b/test/integrations/destinations/mp/common.ts @@ -1,8 +1,10 @@ +import { Destination } from '../../../../src/types'; + const defaultMockFns = () => { jest.spyOn(Date, 'now').mockImplementation(() => new Date(Date.UTC(2020, 0, 25)).valueOf()); }; -const sampleDestination = { +const sampleDestination: Destination = { Config: { apiKey: 'dummyApiKey', token: 'test_api_token', @@ -13,11 +15,13 @@ const sampleDestination = { DisplayName: 'Mixpanel', ID: '1WhbSZ6uA3H5ChVifHpfL2H6sie', Name: 'MP', + Config: undefined, }, Enabled: true, ID: '1WhcOCGgj9asZu850HvugU2C3Aq', Name: 'MP', Transformations: [], + WorkspaceID: '', }; const destinationWithSetOnceProperty = { diff --git a/test/integrations/destinations/mp/processor/data.ts b/test/integrations/destinations/mp/processor/data.ts index e560a455969..db5bc840c2e 100644 --- a/test/integrations/destinations/mp/processor/data.ts +++ b/test/integrations/destinations/mp/processor/data.ts @@ -124,7 +124,10 @@ export const data = [ request: { body: [ { - destination: sampleDestination, + destination: overrideDestination(sampleDestination, { + useUserDefinedPageEventName: true, + userDefinedPageEventTemplate: 'Viewed a {{ name }} page', + }), message: { anonymousId: 'e6ab2c5e-2cda-44a9-a962-e2f67df78bca', channel: 'web', @@ -201,7 +204,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Page","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us","category":"Contact","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"Viewed a Contact Us page","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us","category":"Contact","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -4345,10 +4348,9 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: - 'Basic cnVkZGVyLmQyYTNmMS5tcC1zZXJ2aWNlLWFjY291bnQ6amF0cFF4Y2pNaDhlZXRrMXhySDNLalFJYnp5NGlYOGI=', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, - params: { project_id: '123456', strict: 0 }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { diff --git a/test/integrations/destinations/mp/router/data.ts b/test/integrations/destinations/mp/router/data.ts index 77282027d42..8716c9daa09 100644 --- a/test/integrations/destinations/mp/router/data.ts +++ b/test/integrations/destinations/mp/router/data.ts @@ -479,6 +479,7 @@ export const data = [ ID: '1WhcOCGgj9asZu850HvugU2C3Aq', Name: 'MP', Transformations: [], + WorkspaceID: '', }, }, { @@ -546,6 +547,7 @@ export const data = [ ID: '1WhcOCGgj9asZu850HvugU2C3Aq', Name: 'MP', Transformations: [], + WorkspaceID: '', }, }, { @@ -617,6 +619,7 @@ export const data = [ ID: '1WhcOCGgj9asZu850HvugU2C3Aq', Name: 'MP', Transformations: [], + WorkspaceID: '', }, }, { @@ -680,6 +683,7 @@ export const data = [ ID: '1WhcOCGgj9asZu850HvugU2C3Aq', Name: 'MP', Transformations: [], + WorkspaceID: '', }, }, { @@ -715,6 +719,7 @@ export const data = [ ID: '1WhcOCGgj9asZu850HvugU2C3Aq', Name: 'MP', Transformations: [], + WorkspaceID: '', }, }, ], @@ -1197,6 +1202,7 @@ export const data = [ ID: '1WhcOCGgj9asZu850HvugU2C3Aq', Name: 'MP', Transformations: [], + WorkspaceID: '', }, }, { @@ -1263,6 +1269,7 @@ export const data = [ ID: '1WhcOCGgj9asZu850HvugU2C3Aq', Name: 'MP', Transformations: [], + WorkspaceID: '', }, }, { @@ -1333,6 +1340,7 @@ export const data = [ ID: '1WhcOCGgj9asZu850HvugU2C3Aq', Name: 'MP', Transformations: [], + WorkspaceID: '', }, }, { @@ -1396,6 +1404,7 @@ export const data = [ ID: '1WhcOCGgj9asZu850HvugU2C3Aq', Name: 'MP', Transformations: [], + WorkspaceID: '', }, }, { @@ -1431,6 +1440,7 @@ export const data = [ ID: '1WhcOCGgj9asZu850HvugU2C3Aq', Name: 'MP', Transformations: [], + WorkspaceID: '', }, }, ], diff --git a/test/integrations/destinations/ninetailed/commonConfig.ts b/test/integrations/destinations/ninetailed/commonConfig.ts new file mode 100644 index 00000000000..4baf72dee15 --- /dev/null +++ b/test/integrations/destinations/ninetailed/commonConfig.ts @@ -0,0 +1,146 @@ +export const destination = { + ID: 'random_id', + Name: 'ninetailed', + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + organisationId: 'dummyOrganisationId', + environment: 'main', + }, +}; + +export const metadata = { + destinationId: 'dummyDestId', +}; +export const commonProperties = { + segment: 'SampleSegment', + shipcountry: 'USA', + shipped: '20240129_1500', + sitename: 'SampleSiteName', + storeId: '12345', + storecat: 'Electronics', +}; +export const traits = { + email: 'test@user.com', + firstname: 'John', + lastname: 'Doe', + phone: '+1(123)456-7890', + gender: 'Male', + birthday: '1980-01-02', + city: 'San Francisco', +}; +export const context = { + app: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + campaign: { + name: 'campign_123', + source: 'social marketing', + medium: 'facebook', + term: '1 year', + }, + library: { + name: 'RudderstackSDK', + version: 'Ruddderstack SDK version', + }, + locale: 'en-US', + page: { + path: '/signup', + referrer: 'https://rudderstack.medium.com/', + search: '?type=freetrial', + url: 'https://app.rudderstack.com/signup?type=freetrial', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + location: { + coordinates: { + latitude: 40.7128, + longitude: -74.006, + }, + city: 'San Francisco', + postalCode: '94107', + region: 'CA', + regionCode: 'CA', + country: ' United States', + countryCode: 'United States of America', + continent: 'North America', + timezone: 'America/Los_Angeles', + }, +}; +export const contextWithNoLocation = { + app: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + campaign: { + name: 'campign_123', + source: 'social marketing', + medium: 'facebook', + term: '1 year', + }, + library: { + name: 'RudderstackSDK', + version: 'Ruddderstack SDK version', + }, + locale: 'en-US', + page: { + path: '/signup', + referrer: 'https://rudderstack.medium.com/', + search: '?type=freetrial', + url: 'https://app.rudderstack.com/signup?type=freetrial', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', +}; +export const commonInputWithNoLocation = { + anonymousId: 'anon_123', + messageId: 'dummy_msg_id', + context: contextWithNoLocation, + channel: 'web', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', +}; +export const commonInput = { + anonymousId: 'anon_123', + messageId: 'dummy_msg_id', + context, + channel: 'web', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', +}; + +export const commonOutput = { + anonymousId: 'anon_123', + messageId: 'dummy_msg_id', + context, + channel: 'web', + originalTimestamp: '2021-01-25T15:32:56.409Z', +}; + +export const endpoint = + 'https://experience.ninetailed.co/v2/organizations/dummyOrganisationId/environments/main/events'; +export const routerInstrumentationErrorStatTags = { + destType: 'NINETAILED', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'router', + implementation: 'cdkV2', + module: 'destination', +}; +export const processInstrumentationErrorStatTags = { + destType: 'NINETAILED', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + destinationId: 'dummyDestId', +}; diff --git a/test/integrations/destinations/ninetailed/mocks.ts b/test/integrations/destinations/ninetailed/mocks.ts new file mode 100644 index 00000000000..a16b2760533 --- /dev/null +++ b/test/integrations/destinations/ninetailed/mocks.ts @@ -0,0 +1,5 @@ +import config from '../../../../src/cdk/v2/destinations/ninetailed/config'; + +export const defaultMockFns = () => { + jest.replaceProperty(config, 'MAX_BATCH_SIZE', 2); +}; diff --git a/test/integrations/destinations/ninetailed/processor/data.ts b/test/integrations/destinations/ninetailed/processor/data.ts new file mode 100644 index 00000000000..4e5fa72365d --- /dev/null +++ b/test/integrations/destinations/ninetailed/processor/data.ts @@ -0,0 +1,5 @@ +import { validationFailures } from './validation'; +import { track } from './track'; +import { page } from './page'; +import { identify } from './identify'; +export const data = [...identify, ...page, ...track, ...validationFailures]; diff --git a/test/integrations/destinations/ninetailed/processor/identify.ts b/test/integrations/destinations/ninetailed/processor/identify.ts new file mode 100644 index 00000000000..3bb333c1609 --- /dev/null +++ b/test/integrations/destinations/ninetailed/processor/identify.ts @@ -0,0 +1,244 @@ +import { + destination, + traits, + commonInput, + commonInputWithNoLocation, + metadata, + processInstrumentationErrorStatTags, +} from '../commonConfig'; +import { transformResultBuilder } from '../../../testUtils'; +export const identify = [ + { + id: 'ninetailed-test-identify-success-1', + name: 'ninetailed', + description: 'identify call with all mappings available', + scenario: 'Framework+Buisness', + successCriteria: 'Response should contain all the mappings and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'identify', + ...commonInput, + userId: 'sajal12', + traits: traits, + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'dummyDestId', + }, + output: transformResultBuilder({ + method: 'POST', + endpoint: + 'https://experience.ninetailed.co/v2/organizations/dummyOrganisationId/environments/main/events', + JSON: { + events: [ + { + context: { + app: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + campaign: { + name: 'campign_123', + source: 'social marketing', + medium: 'facebook', + term: '1 year', + }, + library: { + name: 'RudderstackSDK', + version: 'Ruddderstack SDK version', + }, + locale: 'en-US', + page: { + path: '/signup', + referrer: 'https://rudderstack.medium.com/', + search: '?type=freetrial', + url: 'https://app.rudderstack.com/signup?type=freetrial', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + location: { + coordinates: { + latitude: 40.7128, + longitude: -74.006, + }, + city: 'San Francisco', + postalCode: '94107', + region: 'CA', + regionCode: 'CA', + country: ' United States', + countryCode: 'United States of America', + continent: 'North America', + timezone: 'America/Los_Angeles', + }, + }, + type: 'identify', + channel: 'web', + userId: 'sajal12', + messageId: 'dummy_msg_id', + traits: traits, + anonymousId: 'anon_123', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + ], + }, + userId: '', + }), + statusCode: 200, + }, + ], + }, + }, + }, + { + id: 'ninetailed-test-identify-failure-1', + name: 'ninetailed', + description: 'identify call with no userId available', + scenario: 'Framework', + successCriteria: + 'Error should be thrown for required field userId not present and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + ...commonInput, + type: 'identify', + channel: 'mobile', + messageId: 'dummy_msg_id', + traits: traits, + }, + metadata, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Missing required value from "userIdOnly": Workflow: procWorkflow, Step: preparePayload, ChildStep: undefined, OriginalError: Missing required value from "userIdOnly"', + metadata: { + destinationId: 'dummyDestId', + }, + statTags: processInstrumentationErrorStatTags, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'ninetailed-test-identify-success-3', + name: 'ninetailed', + description: 'identify call with no context.location present and {} is used as default', + scenario: 'Framework+Buisness', + successCriteria: 'Response should contain context.location as {} and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'identify', + ...commonInputWithNoLocation, + userId: 'sajal12', + traits: traits, + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'dummyDestId', + }, + output: transformResultBuilder({ + method: 'POST', + endpoint: + 'https://experience.ninetailed.co/v2/organizations/dummyOrganisationId/environments/main/events', + JSON: { + events: [ + { + context: { + app: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + campaign: { + name: 'campign_123', + source: 'social marketing', + medium: 'facebook', + term: '1 year', + }, + library: { + name: 'RudderstackSDK', + version: 'Ruddderstack SDK version', + }, + locale: 'en-US', + page: { + path: '/signup', + referrer: 'https://rudderstack.medium.com/', + search: '?type=freetrial', + url: 'https://app.rudderstack.com/signup?type=freetrial', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + location: {}, + }, + type: 'identify', + channel: 'web', + userId: 'sajal12', + messageId: 'dummy_msg_id', + traits: traits, + anonymousId: 'anon_123', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + ], + }, + userId: '', + }), + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/ninetailed/processor/page.ts b/test/integrations/destinations/ninetailed/processor/page.ts new file mode 100644 index 00000000000..93a086ceea0 --- /dev/null +++ b/test/integrations/destinations/ninetailed/processor/page.ts @@ -0,0 +1,108 @@ +import { destination, context, commonProperties, metadata } from '../commonConfig'; +import { transformResultBuilder } from '../../../testUtils'; +export const page = [ + { + id: 'ninetailed-test-page-success-1', + name: 'ninetailed', + description: 'page call with all mappings available', + scenario: 'Framework+Buisness', + successCriteria: 'Response should contain all the mappings and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + context, + type: 'page', + event: 'product purchased', + userId: 'sajal12', + channel: 'mobile', + messageId: 'dummy_msg_id', + properties: commonProperties, + anonymousId: 'anon_123', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'dummyDestId', + }, + output: transformResultBuilder({ + method: 'POST', + endpoint: + 'https://experience.ninetailed.co/v2/organizations/dummyOrganisationId/environments/main/events', + JSON: { + events: [ + { + context: { + app: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + campaign: { + name: 'campign_123', + source: 'social marketing', + medium: 'facebook', + term: '1 year', + }, + library: { + name: 'RudderstackSDK', + version: 'Ruddderstack SDK version', + }, + locale: 'en-US', + page: { + path: '/signup', + referrer: 'https://rudderstack.medium.com/', + search: '?type=freetrial', + url: 'https://app.rudderstack.com/signup?type=freetrial', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + location: { + coordinates: { + latitude: 40.7128, + longitude: -74.006, + }, + city: 'San Francisco', + postalCode: '94107', + region: 'CA', + regionCode: 'CA', + country: ' United States', + countryCode: 'United States of America', + continent: 'North America', + timezone: 'America/Los_Angeles', + }, + }, + type: 'page', + channel: 'mobile', + messageId: 'dummy_msg_id', + properties: commonProperties, + anonymousId: 'anon_123', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + ], + }, + userId: '', + }), + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/ninetailed/processor/track.ts b/test/integrations/destinations/ninetailed/processor/track.ts new file mode 100644 index 00000000000..6b6a1e7831d --- /dev/null +++ b/test/integrations/destinations/ninetailed/processor/track.ts @@ -0,0 +1,204 @@ +import { destination, context, commonProperties, metadata } from '../commonConfig'; +import { transformResultBuilder } from '../../../testUtils'; +export const track = [ + { + id: 'ninetailed-test-track-success-1', + name: 'ninetailed', + description: 'Track call with all mappings available', + scenario: 'Framework+Buisness', + successCriteria: 'Response should contain all the mappings and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + context: { + app: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + campaign: { + name: 'campign_123', + source: 'social marketing', + medium: 'facebook', + term: '1 year', + }, + library: { + name: 'RudderstackSDK', + version: 'Ruddderstack SDK version', + }, + locale: 'en-US', + page: { + path: '/signup', + referrer: 'https://rudderstack.medium.com/', + search: '?type=freetrial', + url: 'https://app.rudderstack.com/signup?type=freetrial', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + location: { + coordinates: { + latitude: 40.7128, + longitude: -74.006, + }, + city: 'San Francisco', + postalCode: '94107', + region: 'CA', + regionCode: 'CA', + country: ' United States', + countryCode: 'United States of America', + continent: 'North America', + timezone: 'America/Los_Angeles', + }, + }, + type: 'track', + event: 'product purchased', + userId: 'sajal12', + channel: 'mobile', + messageId: 'dummy_msg_id', + properties: commonProperties, + anonymousId: 'anon_123', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'dummyDestId', + }, + output: transformResultBuilder({ + method: 'POST', + endpoint: + 'https://experience.ninetailed.co/v2/organizations/dummyOrganisationId/environments/main/events', + JSON: { + events: [ + { + context: { + app: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + campaign: { + name: 'campign_123', + source: 'social marketing', + medium: 'facebook', + term: '1 year', + }, + library: { + name: 'RudderstackSDK', + version: 'Ruddderstack SDK version', + }, + locale: 'en-US', + page: { + path: '/signup', + referrer: 'https://rudderstack.medium.com/', + search: '?type=freetrial', + url: 'https://app.rudderstack.com/signup?type=freetrial', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + location: { + coordinates: { + latitude: 40.7128, + longitude: -74.006, + }, + city: 'San Francisco', + postalCode: '94107', + region: 'CA', + regionCode: 'CA', + country: ' United States', + countryCode: 'United States of America', + continent: 'North America', + timezone: 'America/Los_Angeles', + }, + }, + type: 'track', + event: 'product purchased', + channel: 'mobile', + messageId: 'dummy_msg_id', + properties: commonProperties, + anonymousId: 'anon_123', + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + ], + }, + userId: '', + }), + statusCode: 200, + }, + ], + }, + }, + }, + { + id: 'ninetailed-test-track-failure-1', + name: 'ninetailed', + description: 'track call with no event available', + scenario: 'Framework', + successCriteria: + 'Error should be thrown for required field event not present and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + context, + type: 'track', + channel: 'mobile', + messageId: 'dummy_msg_id', + properties: commonProperties, + anonymousId: 'anon_123', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Missing required value from "event": Workflow: procWorkflow, Step: preparePayload, ChildStep: undefined, OriginalError: Missing required value from "event"', + metadata: { + destinationId: 'dummyDestId', + }, + statTags: { + destType: 'NINETAILED', + destinationId: 'dummyDestId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/ninetailed/processor/validation.ts b/test/integrations/destinations/ninetailed/processor/validation.ts new file mode 100644 index 00000000000..68c025faad1 --- /dev/null +++ b/test/integrations/destinations/ninetailed/processor/validation.ts @@ -0,0 +1,115 @@ +import { processInstrumentationErrorStatTags, destination, context } from '../commonConfig'; + +export const validationFailures = [ + { + id: 'Ninetailed-validation-test-1', + name: 'ninetailed', + description: 'Required field anonymousId not present', + scenario: 'Framework', + successCriteria: 'Transformationn Error for anonymousId not present', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + event: 'product purchased', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + context, + properties: { + products: [{}], + }, + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Missing required value from "anonymousId": Workflow: procWorkflow, Step: preparePayload, ChildStep: undefined, OriginalError: Missing required value from "anonymousId"', + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + statTags: processInstrumentationErrorStatTags, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'Ninetailed-test-4', + name: 'ninetailed', + description: 'Unsupported message type -> group', + scenario: 'Framework', + successCriteria: 'Transformationn Error for Unsupported message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'group', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + channel: 'mobile', + rudderId: 'b7b24f86-f7bf-46d8-b2b4-ccafc080239c', + messageId: 'dummy_msg_id', + traits: { + orderId: 'ord 123', + products: [], + }, + anonymousId: 'anon_123', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'message type group is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type group is not supported', + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + statTags: processInstrumentationErrorStatTags, + statusCode: 400, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/ninetailed/router/basicProperties.ts b/test/integrations/destinations/ninetailed/router/basicProperties.ts new file mode 100644 index 00000000000..5725f3d4451 --- /dev/null +++ b/test/integrations/destinations/ninetailed/router/basicProperties.ts @@ -0,0 +1,33 @@ +export const trackProperties = { + index: 'products', + queryId: '43b15df305339e827f0ac0bdc5ebcaa7', + products: [ + { objectId: 'ecommerce-sample-data-919', position: 7 }, + { objectId: '9780439784542', position: 8 }, + ], +}; + +export const pageProperties = { + title: 'Sample Page', + url: 'https://example.com/?utm_campaign=example_campaign&utm_content=example_content', + path: '/', + hash: '', + search: '?utm_campaign=example_campaign&utm_content=example_content', + width: '1920', + height: '1080', + query: { + utm_campaign: 'example_campaign', + utm_content: 'example_content', + }, + referrer: '', +}; + +export const traits = { + email: 'test@user.com', + firstname: 'John', + lastname: 'Doe', + phone: '+1(123)456-7890', + gender: 'Male', + birthday: '1980-01-02', + city: 'San Francisco', +}; diff --git a/test/integrations/destinations/ninetailed/router/data.ts b/test/integrations/destinations/ninetailed/router/data.ts new file mode 100644 index 00000000000..05105f4aed8 --- /dev/null +++ b/test/integrations/destinations/ninetailed/router/data.ts @@ -0,0 +1,393 @@ +import { + commonInput, + destination, + commonOutput, + routerInstrumentationErrorStatTags, +} from '../commonConfig'; +import { trackProperties, pageProperties, traits } from './basicProperties'; +import { defaultMockFns } from '../mocks'; + +export const data = [ + { + name: 'ninetailed', + id: 'Test 0 - router', + description: 'Batch calls with all three type of calls as success', + scenario: 'Framework+Buisness', + successCriteria: 'All events should be transformed successfully and status code should be 200', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + ...commonInput, + type: 'track', + event: 'product list viewed', + properties: trackProperties, + }, + metadata: { jobId: 1, userId: 'u1' }, + destination, + }, + { + message: { + ...commonInput, + type: 'page', + properties: pageProperties, + }, + metadata: { jobId: 2, userId: 'u1' }, + destination, + }, + { + message: { + type: 'identify', + ...commonInput, + userId: 'testuserId1', + traits, + integrations: { All: true }, + }, + metadata: { jobId: 3, userId: 'u1' }, + destination, + }, + ], + destType: 'ninetailed', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://experience.ninetailed.co/v2/organizations/dummyOrganisationId/environments/main/events', + params: {}, + body: { + FORM: {}, + JSON: { + events: [ + { + ...commonOutput, + type: 'track', + event: 'product list viewed', + properties: trackProperties, + }, + { + ...commonOutput, + type: 'page', + properties: pageProperties, + }, + { + type: 'identify', + ...commonOutput, + userId: 'testuserId1', + traits, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + headers: { + 'Content-Type': 'application/json', + }, + files: {}, + }, + metadata: [ + { jobId: 1, userId: 'u1' }, + { jobId: 2, userId: 'u1' }, + { jobId: 3, userId: 'u1' }, + ], + batched: true, + statusCode: 200, + destination, + }, + ], + }, + }, + }, + }, + { + name: 'ninetailed', + id: 'Test 1 - router', + description: 'Batch calls with one fail invalid event and two valid events', + scenario: 'Framework+Buisness', + successCriteria: + 'Two events should be transformed successfully and one should fail and status code should be 200', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + ...commonInput, + type: 'track', + event: 'product list viewed', + properties: trackProperties, + }, + metadata: { jobId: 1, userId: 'u1' }, + destination, + }, + { + message: { + ...commonInput, + type: 'page', + properties: { + title: 'Sample Page', + url: 'https://example.com/?utm_campaign=example_campaign&utm_content=example_content', + path: '/', + hash: '', + search: '?utm_campaign=example_campaign&utm_content=example_content', + width: '1920', + height: '1080', + query: { + utm_campaign: 'example_campaign', + utm_content: 'example_content', + }, + referrer: '', + }, + }, + metadata: { jobId: 2, userId: 'u1' }, + destination, + }, + { + message: { + type: 'identify', + ...commonInput, + traits, + integrations: { All: true }, + }, + metadata: { jobId: 3, userId: 'u1' }, + destination, + }, + ], + destType: 'ninetailed', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batched: false, + destination, + error: 'Missing required value from "userIdOnly"', + metadata: [{ jobId: 3, userId: 'u1' }], + statTags: routerInstrumentationErrorStatTags, + statusCode: 400, + }, + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://experience.ninetailed.co/v2/organizations/dummyOrganisationId/environments/main/events', + params: {}, + body: { + FORM: {}, + JSON: { + events: [ + { + ...commonOutput, + type: 'track', + event: 'product list viewed', + properties: trackProperties, + }, + { + ...commonOutput, + type: 'page', + properties: pageProperties, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + headers: { + 'Content-Type': 'application/json', + }, + files: {}, + }, + metadata: [ + { jobId: 1, userId: 'u1' }, + { jobId: 2, userId: 'u1' }, + ], + batched: true, + statusCode: 200, + destination, + }, + ], + }, + }, + }, + mockFns: defaultMockFns, + }, + { + name: 'ninetailed', + id: 'Test 2 - router', + description: 'Batch calls with 3 succesfull events and 1 failed event', + scenario: 'Framework+Buisness', + successCriteria: + '3 successful events should be distributed in two and 1 failed in one hence total batches should be 3 and status code should be 200', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + ...commonInput, + type: 'track', + event: 'product list viewed', + properties: trackProperties, + }, + metadata: { jobId: 1, userId: 'u1' }, + destination, + }, + { + message: { + ...commonInput, + type: 'page', + properties: pageProperties, + }, + metadata: { jobId: 2, userId: 'u1' }, + destination, + }, + { + message: { + type: 'identify', + ...commonInput, + userId: 'testuserId1', + traits, + integrations: { All: true }, + }, + metadata: { jobId: 3, userId: 'u1' }, + destination, + }, + { + message: { + type: 'identify', + ...commonInput, + traits, + integrations: { All: true }, + }, + metadata: { jobId: 4, userId: 'u1' }, + destination, + }, + ], + destType: 'ninetailed', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batched: false, + destination, + error: 'Missing required value from "userIdOnly"', + metadata: [{ jobId: 4, userId: 'u1' }], + statTags: routerInstrumentationErrorStatTags, + statusCode: 400, + }, + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://experience.ninetailed.co/v2/organizations/dummyOrganisationId/environments/main/events', + params: {}, + body: { + FORM: {}, + JSON: { + events: [ + { + ...commonOutput, + type: 'track', + event: 'product list viewed', + properties: trackProperties, + }, + { + ...commonOutput, + type: 'page', + properties: pageProperties, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + headers: { + 'Content-Type': 'application/json', + }, + files: {}, + }, + metadata: [ + { jobId: 1, userId: 'u1' }, + { jobId: 2, userId: 'u1' }, + ], + batched: true, + statusCode: 200, + destination, + }, + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://experience.ninetailed.co/v2/organizations/dummyOrganisationId/environments/main/events', + params: {}, + body: { + FORM: {}, + JSON: { + events: [ + { + type: 'identify', + ...commonOutput, + userId: 'testuserId1', + traits, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + headers: { + 'Content-Type': 'application/json', + }, + files: {}, + }, + metadata: [{ jobId: 3, userId: 'u1' }], + batched: true, + statusCode: 200, + destination, + }, + ], + }, + }, + }, + mockFns: defaultMockFns, + }, +]; diff --git a/test/integrations/destinations/one_signal/processor/data.ts b/test/integrations/destinations/one_signal/processor/data.ts index 7f244aa7114..4171157aef7 100644 --- a/test/integrations/destinations/one_signal/processor/data.ts +++ b/test/integrations/destinations/one_signal/processor/data.ts @@ -702,7 +702,7 @@ export const data = [ headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, version: '1', endpoint: - 'https://onesignal.com/api/v1/apps/random-818c-4a28-b98e-6cd8a994eb22/users/user@27', + 'https://onesignal.com/api/v1/apps/random-818c-4a28-b98e-6cd8a994eb22/users/user%4027', userId: '', }, statusCode: 200, @@ -789,7 +789,7 @@ export const data = [ headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, version: '1', endpoint: - 'https://onesignal.com/api/v1/apps/random-818c-4a28-b98e-6cd8a994eb22/users/user@27', + 'https://onesignal.com/api/v1/apps/random-818c-4a28-b98e-6cd8a994eb22/users/user%4027', userId: '', }, statusCode: 200, @@ -870,7 +870,7 @@ export const data = [ headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, version: '1', endpoint: - 'https://onesignal.com/api/v1/apps/random-818c-4a28-b98e-6cd8a994eb22/users/user@27', + 'https://onesignal.com/api/v1/apps/random-818c-4a28-b98e-6cd8a994eb22/users/user%4027', userId: '', }, statusCode: 200, @@ -945,7 +945,7 @@ export const data = [ headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, version: '1', endpoint: - 'https://onesignal.com/api/v1/apps/random-818c-4a28-b98e-6cd8a994eb22/users/user@27', + 'https://onesignal.com/api/v1/apps/random-818c-4a28-b98e-6cd8a994eb22/users/user%4027', userId: '', }, statusCode: 200, @@ -1025,7 +1025,7 @@ export const data = [ headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, version: '1', endpoint: - 'https://onesignal.com/api/v1/apps/random-818c-4a28-b98e-6cd8a994eb22/users/user@27', + 'https://onesignal.com/api/v1/apps/random-818c-4a28-b98e-6cd8a994eb22/users/user%4027', userId: '', }, statusCode: 200, diff --git a/test/integrations/destinations/one_signal/router/data.ts b/test/integrations/destinations/one_signal/router/data.ts index fe8460e45df..a27da5a7456 100644 --- a/test/integrations/destinations/one_signal/router/data.ts +++ b/test/integrations/destinations/one_signal/router/data.ts @@ -199,7 +199,7 @@ export const data = [ headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, version: '1', endpoint: - 'https://onesignal.com/api/v1/apps/random-818c-4a28-b98e-6cd8a994eb22/users/user@27', + 'https://onesignal.com/api/v1/apps/random-818c-4a28-b98e-6cd8a994eb22/users/user%4027', }, metadata: [{ jobId: 2, userId: 'u1' }], batched: false, diff --git a/test/integrations/destinations/pardot/dataDelivery/business.ts b/test/integrations/destinations/pardot/dataDelivery/business.ts new file mode 100644 index 00000000000..f6baefbc8f2 --- /dev/null +++ b/test/integrations/destinations/pardot/dataDelivery/business.ts @@ -0,0 +1,372 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { + generateMetadata, + generateProxyV0Payload, + generateProxyV1Payload, +} from '../../../testUtils'; +import { commonRequestParameters, retryStatTags } from './constant'; + +const pardotResponseRogerEmail = { + '@attributes': { stat: 'ok', version: 1 }, + prospect: { + id: 123435, + campaign_id: 42213, + salutation: null, + first_name: 'Roger_12', + last_name: 'Federer_12', + email: 'Roger_12@federer.io', + password: null, + company: null, + website: 'https://rudderstack.com', + job_title: null, + department: null, + country: 'AU', + address_one: null, + address_two: null, + city: null, + state: null, + territory: null, + zip: null, + phone: null, + fax: null, + source: null, + annual_revenue: null, + employees: null, + industry: null, + years_in_business: null, + comments: null, + notes: null, + score: 14, + grade: null, + last_activity_at: null, + recent_interaction: 'Never active.', + crm_lead_fid: '00Q6r000002LKhTPVR', + crm_contact_fid: null, + crm_owner_fid: '00G2v000004WYXaEAO', + crm_account_fid: null, + salesforce_fid: '00Q6r000002LKhTPVR', + crm_last_sync: '2022-01-21 18:47:37', + crm_url: 'https://testcompany.my.salesforce.com/00Q6r000002LKhTPVR', + is_do_not_email: null, + is_do_not_call: null, + opted_out: null, + is_reviewed: 1, + is_starred: null, + created_at: '2022-01-21 18:21:46', + updated_at: '2022-01-21 18:48:41', + campaign: { id: 42113, name: 'Test', crm_fid: '7012y000000MNOCLL4' }, + assigned_to: { + user: { + id: 38443703, + email: 'test_rudderstack@testcompany.com', + first_name: 'Rudderstack', + last_name: 'User', + job_title: null, + role: 'Administrator', + account: 489853, + created_at: '2021-02-26 06:25:17', + updated_at: '2021-02-26 06:25:17', + }, + }, + Are_you_shipping_large_fragile_or_bulky_items: false, + Calendly: false, + Country_Code: 'AU', + Currency: 'AUD', + Inventory_or_Warehouse_Management_System: false, + Lead_Status: 'New', + Marketing_Stage: 'SAL', + Record_Type_ID: 'TestCompany Lead', + profile: { + id: 304, + name: 'Default', + profile_criteria: [ + { id: 1500, name: 'Shipping Volume', matches: 'Unknown' }, + { id: 1502, name: 'Industry', matches: 'Unknown' }, + { id: 1506, name: 'Job Title', matches: 'Unknown' }, + { id: 1508, name: 'Department', matches: 'Unknown' }, + ], + }, + visitors: null, + visitor_activities: null, + lists: null, + }, +}; + +const pardotResponseWalterEmail = { + '@attributes': { stat: 'ok', version: 1 }, + prospect: { + id: 123435, + campaign_id: 42213, + salutation: null, + first_name: 'Roger_12', + last_name: 'Federer_12', + email: 'Roger_12@waltair.io', + password: null, + company: null, + website: 'https://rudderstack.com', + job_title: null, + department: null, + country: 'AU', + address_one: null, + address_two: null, + city: null, + state: null, + territory: null, + zip: null, + phone: null, + fax: null, + source: null, + annual_revenue: null, + employees: null, + industry: null, + years_in_business: null, + comments: null, + notes: null, + score: 14, + grade: null, + last_activity_at: null, + recent_interaction: 'Never active.', + crm_lead_fid: null, + crm_contact_fid: null, + crm_owner_fid: '00G2v000004WYXaEAO', + crm_account_fid: null, + salesforce_fid: null, + crm_last_sync: null, + crm_url: null, + is_do_not_email: null, + is_do_not_call: null, + opted_out: null, + is_reviewed: 1, + is_starred: null, + created_at: '2022-01-21 18:21:46', + updated_at: '2022-01-21 18:48:41', + campaign: { id: 42113, name: 'Test', crm_fid: '7012y000000MNOCLL4' }, + assigned_to: { + user: { + id: 38443703, + email: 'test_rudderstack@testcompany.com', + first_name: 'Rudderstack', + last_name: 'User', + job_title: null, + role: 'Administrator', + account: 489853, + created_at: '2021-02-26 06:25:17', + updated_at: '2021-02-26 06:25:17', + }, + }, + Are_you_shipping_large_fragile_or_bulky_items: false, + Calendly: false, + Country_Code: 'AU', + Currency: 'AUD', + Inventory_or_Warehouse_Management_System: false, + Lead_Status: 'New', + Marketing_Stage: 'SAL', + Record_Type_ID: 'TestCompany Lead', + profile: { + id: 304, + name: 'Default', + profile_criteria: [ + { id: 1500, name: 'Shipping Volume', matches: 'Unknown' }, + { id: 1502, name: 'Industry', matches: 'Unknown' }, + { id: 1506, name: 'Job Title', matches: 'Unknown' }, + { id: 1508, name: 'Department', matches: 'Unknown' }, + ], + }, + visitors: null, + visitor_activities: null, + lists: null, + }, +}; + +export const businessV0TestScenarios = [ + { + id: 'pardot_v0_bussiness_scenario_1', + name: 'pardot', + description: '[Proxy v0 API] :: pardot email upsert', + successCriteria: 'Proper response from destination is received', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: + 'https://pi.pardot.com/api/prospect/version/4/do/upsert/email/Roger_12@waltair.io', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 201, + message: 'Request Processed Successfully', + destinationResponse: { + response: pardotResponseWalterEmail, + status: 201, + }, + }, + }, + }, + }, + }, + { + id: 'pardot_v0_bussiness_scenario_2', + name: 'pardot', + description: '[Proxy v0 API] :: pardot fid type upsert', + successCriteria: 'Proper response from destination is received', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://pi.pardot.com/api/prospect/version/4/do/upsert/fid/00Q6r000002LKhTPVR', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + destinationResponse: { + response: pardotResponseRogerEmail, + status: 200, + }, + }, + }, + }, + }, + }, +]; + +export const businessV1TestScenarios: ProxyV1TestData[] = [ + { + id: 'pardot_v1_bussiness_scenario_1', + name: 'pardot', + description: '[Proxy v1 API] :: pardot email type upsert', + successCriteria: 'Proper response from destination is received', + scenario: 'business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + ...commonRequestParameters, + endpoint: + 'https://pi.pardot.com/api/prospect/version/4/do/upsert/email/Roger_12@waltair.io', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 201, + message: 'Request Processed Successfully', + response: [ + { + statusCode: 201, + metadata: generateMetadata(1), + error: JSON.stringify(pardotResponseWalterEmail), + }, + ], + }, + }, + }, + }, + }, + { + id: 'pardot_v1_bussiness_scenario_2', + name: 'pardot', + description: '[Proxy v1 API] :: pardot fid type upsert', + successCriteria: 'Proper response from destination is received', + scenario: 'business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + ...commonRequestParameters, + endpoint: 'https://pi.pardot.com/api/prospect/version/4/do/upsert/fid/00Q6r000002LKhTPVR', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + response: [ + { + statusCode: 200, + metadata: generateMetadata(1), + error: JSON.stringify(pardotResponseRogerEmail), + }, + ], + }, + }, + }, + }, + }, + { + id: 'pardot_v1_Business_scenario_2', + name: 'pardot', + description: '[Proxy v1 API] :: Response with other retryable codes', + successCriteria: 'the proxy should return 500 with retryable tag', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + ...commonRequestParameters, + endpoint: + 'https://pi.pardot.com/api/prospect/version/4/do/upsert/email/rolex_waltair@test.com', + params: { + destination: 'pardot', + }, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: + 'Unable to verify Salesforce connector during Pardot response transformation', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: retryStatTags, + message: 'Unable to verify Salesforce connector during Pardot response transformation', + status: 500, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/pardot/dataDelivery/constant.ts b/test/integrations/destinations/pardot/dataDelivery/constant.ts new file mode 100644 index 00000000000..97e456998e1 --- /dev/null +++ b/test/integrations/destinations/pardot/dataDelivery/constant.ts @@ -0,0 +1,27 @@ +export const retryStatTags = { + destType: 'PARDOT', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', +}; +const commonHeaders = { + Authorization: 'Bearer myToken', + 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', + 'Pardot-Business-Unit-Id': '0Uv2v000000k9tHCAQ', + 'User-Agent': 'RudderLabs', +}; + +export const commonRequestParameters = { + headers: commonHeaders, + FORM: { + first_name: 'Roger12', + last_name: 'Federer12', + website: 'https://rudderstack.com', + score: 14, + campaign_id: 42213, + }, +}; diff --git a/test/integrations/destinations/pardot/dataDelivery/data.ts b/test/integrations/destinations/pardot/dataDelivery/data.ts new file mode 100644 index 00000000000..752ef22cb1d --- /dev/null +++ b/test/integrations/destinations/pardot/dataDelivery/data.ts @@ -0,0 +1,10 @@ +import { businessV0TestScenarios, businessV1TestScenarios } from './business'; +import { v1OauthScenarios } from './oauth'; +import { otherScenariosV1 } from './other'; + +export const data = [ + ...v1OauthScenarios, + ...businessV1TestScenarios, + ...businessV0TestScenarios, + ...otherScenariosV1, +]; diff --git a/test/integrations/destinations/pardot/dataDelivery/oauth.ts b/test/integrations/destinations/pardot/dataDelivery/oauth.ts new file mode 100644 index 00000000000..4a0116a9517 --- /dev/null +++ b/test/integrations/destinations/pardot/dataDelivery/oauth.ts @@ -0,0 +1,53 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; +import { commonRequestParameters, retryStatTags } from './constant'; + +export const v1OauthScenarios: ProxyV1TestData[] = [ + { + id: 'pardot_v1_oauth_scenario_1', + name: 'pardot', + description: + '[Proxy v1 API] :: Oauth where valid credentials are missing as mock response from destination', + successCriteria: + 'Since the error from the destination is 401 - the proxy should return 500 with authErrorCategory as REFRESH_TOKEN', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + ...commonRequestParameters, + endpoint: + 'https://pi.pardot.com/api/prospect/version/4/do/upsert/email/rolex_waltair@mywebsite.io', + params: { + destination: 'pardot', + }, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + response: [ + { + error: + 'access_token is invalid, unknown, or malformed: Inactive token during Pardot response transformation', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: retryStatTags, + authErrorCategory: 'REFRESH_TOKEN', + message: + 'access_token is invalid, unknown, or malformed: Inactive token during Pardot response transformation', + status: 500, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/pardot/dataDelivery/other.ts b/test/integrations/destinations/pardot/dataDelivery/other.ts new file mode 100644 index 00000000000..b7454e691c6 --- /dev/null +++ b/test/integrations/destinations/pardot/dataDelivery/other.ts @@ -0,0 +1,205 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; + +const expectedStatTags = { + destType: 'PARDOT', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', +}; + +export const otherScenariosV1: ProxyV1TestData[] = [ + { + id: 'pardot_v1_other_scenario_1', + name: 'pardot', + description: + '[Proxy v1 API] :: Scenario for testing Service Unavailable error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_service_not_available', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: + '{"error":{"message":"Service Unavailable","description":"The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later."}} during Pardot response transformation', + statusCode: 503, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + status: 503, + message: + '{"error":{"message":"Service Unavailable","description":"The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later."}} during Pardot response transformation', + }, + }, + }, + }, + }, + { + id: 'pardot_v1_other_scenario_2', + name: 'pardot', + description: '[Proxy v1 API] :: Scenario for testing Internal Server error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_internal_server_error', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Internal Server Error" during Pardot response transformation', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + status: 500, + message: '"Internal Server Error" during Pardot response transformation', + }, + }, + }, + }, + }, + { + id: 'pardot_v1_other_scenario_3', + name: 'pardot', + description: '[Proxy v1 API] :: Scenario for testing Gateway Time Out error from destination', + successCriteria: 'Should return 504 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_gateway_time_out', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Gateway Timeout" during Pardot response transformation', + statusCode: 504, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + status: 504, + message: '"Gateway Timeout" during Pardot response transformation', + }, + }, + }, + }, + }, + { + id: 'pardot_v1_other_scenario_4', + name: 'pardot', + description: '[Proxy v1 API] :: Scenario for testing null response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_response', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"" during Pardot response transformation', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + status: 500, + message: '"" during Pardot response transformation', + }, + }, + }, + }, + }, + { + id: 'pardot_v1_other_scenario_5', + name: 'pardot', + description: + '[Proxy v1 API] :: Scenario for testing null and no status response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_and_no_status', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"" during Pardot response transformation', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + status: 500, + message: '"" during Pardot response transformation', + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/pardot/network.ts b/test/integrations/destinations/pardot/network.ts index bbbe0d70f93..9493aab01fb 100644 --- a/test/integrations/destinations/pardot/network.ts +++ b/test/integrations/destinations/pardot/network.ts @@ -1,25 +1,9 @@ -import { enhanceRequestOptions, getFormData } from '../../../../src/adapters/network'; +import { getFormData } from '../../../../src/adapters/network'; export const networkCallsData = [ - // 2nd proxy test-case { httpReq: { url: 'https://pi.pardot.com/api/prospect/version/4/do/upsert/email/Roger_12@waltair.io', - data: getFormData({ - first_name: 'Roger_12', - last_name: 'Federer_12', - website: 'https://rudderstack.com', - score: 14, - campaign_id: 42213, - format: 'json', - }).toString(), - params: { destination: 'pardot' }, - headers: { - Authorization: 'Bearer myToken', - 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', - 'Pardot-Business-Unit-Id': '0Uv2v000000k9tHCAQ', - 'User-Agent': 'RudderLabs', - }, method: 'POST', }, httpRes: { @@ -135,59 +119,9 @@ export const networkCallsData = [ statusText: 'Created', }, }, - // 4th proxy test-case - { - httpReq: { - url: 'https://pi.pardot.com/api/prospect/version/4/do/upsert/email/rolex_waltair@mywebsite.io', - data: getFormData({ - first_name: 'Rolex', - last_name: 'Waltair', - website: 'https://rudderstack.com', - score: 15, - campaign_id: 42213, - format: 'json', - }).toString(), - params: { destination: 'pardot' }, - headers: { - Authorization: 'Bearer myExpiredToken', - 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', - 'Pardot-Business-Unit-Id': '0Uv2v000000k9tHCAQ', - 'User-Agent': 'RudderLabs', - }, - method: 'POST', - }, - httpRes: { - data: { - '@attributes': { - stat: 'fail', - version: 1, - err_code: 184, - }, - err: 'access_token is invalid, unknown, or malformed: Inactive token', - }, - status: 401, - statusText: 'Unauthorized', - }, - }, - // 1st proxy test-case { httpReq: { - url: 'https://pi.pardot.com/api/prospect/version/4/do/upsert/id/123435', - data: getFormData({ - first_name: 'Roger12', - last_name: 'Federer12', - website: 'https://rudderstack.com', - score: 14, - campaign_id: 42213, - format: 'json', - }).toString(), - params: { destination: 'pardot' }, - headers: { - Authorization: 'Bearer myToken', - 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', - 'Pardot-Business-Unit-Id': '0Uv2v000000k9tHCAQ', - 'User-Agent': 'RudderLabs', - }, + url: 'https://pi.pardot.com/api/prospect/version/4/do/upsert/fid/00Q6r000002LKhTPVR', method: 'POST', }, httpRes: { @@ -200,9 +134,9 @@ export const networkCallsData = [ id: 123435, campaign_id: 42213, salutation: null, - first_name: 'Roger12', - last_name: 'Federer12', - email: 'Roger12@waltair.io', + first_name: 'Roger_12', + last_name: 'Federer_12', + email: 'Roger_12@federer.io', password: null, company: null, website: 'https://rudderstack.com', @@ -228,13 +162,13 @@ export const networkCallsData = [ grade: null, last_activity_at: null, recent_interaction: 'Never active.', - crm_lead_fid: null, + crm_lead_fid: '00Q6r000002LKhTPVR', crm_contact_fid: null, crm_owner_fid: '00G2v000004WYXaEAO', crm_account_fid: null, - salesforce_fid: null, - crm_last_sync: null, - crm_url: null, + salesforce_fid: '00Q6r000002LKhTPVR', + crm_last_sync: '2022-01-21 18:47:37', + crm_url: 'https://testcompany.my.salesforce.com/00Q6r000002LKhTPVR', is_do_not_email: null, is_do_not_call: null, opted_out: null, @@ -303,15 +237,32 @@ export const networkCallsData = [ statusText: 'OK', }, }, - // 3rd proxy test-case { httpReq: { - url: 'https://pi.pardot.com/api/prospect/version/4/do/upsert/fid/00Q6r000002LKhTPVR', + url: 'https://pi.pardot.com/api/prospect/version/4/do/upsert/email/rolex_waltair@mywebsite.io', + method: 'POST', + }, + httpRes: { + data: { + '@attributes': { + stat: 'fail', + version: 1, + err_code: 184, + }, + err: 'access_token is invalid, unknown, or malformed: Inactive token', + }, + status: 401, + statusText: 'Unauthorized', + }, + }, + { + httpReq: { + url: 'https://pi.pardot.com/api/prospect/version/4/do/upsert/id/123435', data: getFormData({ - first_name: 'Nick', - last_name: 'Kyrgios', + first_name: 'Roger12', + last_name: 'Federer12', website: 'https://rudderstack.com', - score: 12, + score: 14, campaign_id: 42213, format: 'json', }).toString(), @@ -334,9 +285,9 @@ export const networkCallsData = [ id: 123435, campaign_id: 42213, salutation: null, - first_name: 'Roger_12', - last_name: 'Federer_12', - email: 'Roger_12@federer.io', + first_name: 'Roger12', + last_name: 'Federer12', + email: 'Roger12@waltair.io', password: null, company: null, website: 'https://rudderstack.com', @@ -362,13 +313,13 @@ export const networkCallsData = [ grade: null, last_activity_at: null, recent_interaction: 'Never active.', - crm_lead_fid: '00Q6r000002LKhTPVR', + crm_lead_fid: null, crm_contact_fid: null, crm_owner_fid: '00G2v000004WYXaEAO', crm_account_fid: null, - salesforce_fid: '00Q6r000002LKhTPVR', - crm_last_sync: '2022-01-21 18:47:37', - crm_url: 'https://testcompany.my.salesforce.com/00Q6r000002LKhTPVR', + salesforce_fid: null, + crm_last_sync: null, + crm_url: null, is_do_not_email: null, is_do_not_call: null, opted_out: null, @@ -437,4 +388,22 @@ export const networkCallsData = [ statusText: 'OK', }, }, + { + httpReq: { + url: 'https://pi.pardot.com/api/prospect/version/4/do/upsert/email/rolex_waltair@test.com', + method: 'POST', + }, + httpRes: { + data: { + '@attributes': { + stat: 'fail', + version: 1, + err_code: 120, + }, + err: 'Unable to verify Salesforce connector', + }, + status: 500, + statusText: 'Invalid action', + }, + }, ]; diff --git a/test/integrations/destinations/rakuten/dataDelivery/data.ts b/test/integrations/destinations/rakuten/dataDelivery/data.ts new file mode 100644 index 00000000000..ff40954fdff --- /dev/null +++ b/test/integrations/destinations/rakuten/dataDelivery/data.ts @@ -0,0 +1,204 @@ +import { endpoint, commonOutputHeaders } from '../processor/commonConfig'; +const commonParams = { + xml: 1, + source: 'rudderstack', + amtlist: '12500|12500', + qlist: '|5', + ord: 'SampleOrderId', + tr: 'SampleRanSiteID', + land: '20240129_1200', +}; +export const data = [ + { + name: 'rakuten', + description: 'Test 0: Failure response from rakuten for invalid mid', + feature: 'dataDelivery', + module: 'destination', + scenario: 'Framework', + version: 'v0', + input: { + request: { + body: { + method: 'GET', + endpoint, + headers: commonOutputHeaders, + params: { + mid: 'invalid_mid', + ...commonParams, + }, + userId: '', + }, + }, + }, + output: { + response: { + status: 400, + statTags: { + errorCategory: 'network', + errorType: 'configuration', + destType: 'RAKUTEN', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'dummyDestId', + workspaceId: 'dummyWorkspaceId', + }, + destinationResponse: { + response: + 'HTTP Status 400 – Bad Request

HTTP Status 400 – Bad Request

', + status: 400, + rudderJobMetadata: [ + { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: 'dummySourceId', + destinationId: 'dummyDestId', + workspaceId: 'dummyWorkspaceId', + }, + ], + }, + authErrorCategory: '', + message: 'Request failed with status: 400 due to invalid Marketing Id', + }, + }, + }, + { + name: 'rakuten', + description: 'Test 1: Failure response from rakuten for access denied for rakuten mid', + feature: 'dataDelivery', + scenario: 'Framework', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + method: 'GET', + endpoint, + headers: commonOutputHeaders, + params: { + mid: 'access_denied_for_mid', + ...commonParams, + }, + userId: '', + }, + }, + }, + output: { + response: { + status: 400, + statTags: { + errorCategory: 'network', + errorType: 'configuration', + destType: 'RAKUTEN', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'dummyDestId', + workspaceId: 'dummyWorkspaceId', + }, + destinationResponse: { + response: 'Access denied', + status: 200, + rudderJobMetadata: [ + { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: 'dummySourceId', + destinationId: 'dummyDestId', + workspaceId: 'dummyWorkspaceId', + }, + ], + }, + authErrorCategory: '', + message: + 'Request failed with status: 200 due to Access denied. Can you try to enable pixel tracking for this mid.', + }, + }, + }, + { + name: 'rakuten', + description: 'Test 2: Failure response from rakuten for bad records>0', + feature: 'dataDelivery', + scenario: 'Framework', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + method: 'GET', + endpoint, + headers: commonOutputHeaders, + params: { + mid: 'valid_mid_with_bad_records', + ...commonParams, + }, + userId: '', + }, + }, + }, + output: { + response: { + status: 400, + statTags: { + errorCategory: 'network', + errorType: 'aborted', + destType: 'RAKUTEN', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'dummyDestId', + workspaceId: 'dummyWorkspaceId', + }, + destinationResponse: { + response: + '14340739143103', + status: 200, + rudderJobMetadata: [ + { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: 'dummySourceId', + destinationId: 'dummyDestId', + workspaceId: 'dummyWorkspaceId', + }, + ], + }, + authErrorCategory: '', + message: 'Request failed with status: 200 with number of bad records 3', + }, + }, + }, + { + name: 'rakuten', + description: 'Test 3: Success response from rakuten with good records > 0', + feature: 'dataDelivery', + scenario: 'Framework', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + method: 'GET', + endpoint, + headers: commonOutputHeaders, + params: { + mid: 'valid_mid_with_good_records', + ...commonParams, + }, + userId: '', + }, + }, + }, + output: { + response: { + status: 200, + destinationResponse: + 'uniqueId30', + message: '[RAKUTEN Response Handler] - Request Processed Successfully', + }, + }, + }, +]; diff --git a/test/integrations/destinations/rakuten/network.ts b/test/integrations/destinations/rakuten/network.ts new file mode 100644 index 00000000000..a9770d83e26 --- /dev/null +++ b/test/integrations/destinations/rakuten/network.ts @@ -0,0 +1,102 @@ +export const networkCallsData = [ + { + description: 'When mid is invalid', + httpReq: { + url: 'https://track.linksynergy.com/ep', + params: { + mid: 'invalid_mid', + xml: 1, + source: 'rudderstack', + amtlist: '12500|12500', + qlist: '|5', + ord: 'SampleOrderId', + tr: 'SampleRanSiteID', + land: '20240129_1200', + }, + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + method: 'GET', + }, + httpRes: { + status: 400, + data: 'HTTP Status 400 – Bad Request

HTTP Status 400 – Bad Request

', + }, + }, + { + description: 'When mid is valid but there is no access', + httpReq: { + url: 'https://track.linksynergy.com/ep', + params: { + mid: 'access_denied_for_mid', + xml: 1, + source: 'rudderstack', + amtlist: '12500|12500', + qlist: '|5', + ord: 'SampleOrderId', + tr: 'SampleRanSiteID', + land: '20240129_1200', + }, + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + method: 'GET', + }, + httpRes: { + status: 200, + data: 'Access denied', + }, + }, + { + description: 'When record along with mid is valid', + httpReq: { + url: 'https://track.linksynergy.com/ep', + params: { + mid: 'valid_mid_with_good_records', + xml: 1, + source: 'rudderstack', + amtlist: '12500|12500', + qlist: '|5', + ord: 'SampleOrderId', + tr: 'SampleRanSiteID', + land: '20240129_1200', + }, + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + method: 'GET', + }, + httpRes: { + status: 200, + data: 'uniqueId30', + }, + }, + { + description: 'When records are invalid and mid is valid', + httpReq: { + url: 'https://track.linksynergy.com/ep', + params: { + mid: 'valid_mid_with_bad_records', + xml: 1, + source: 'rudderstack', + amtlist: '12500|12500', + qlist: '|5', + ord: 'SampleOrderId', + tr: 'SampleRanSiteID', + land: '20240129_1200', + }, + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + method: 'GET', + }, + httpRes: { + status: 200, + data: 'uniqueId03', + }, + }, +]; diff --git a/test/integrations/destinations/rakuten/processor/commonConfig.ts b/test/integrations/destinations/rakuten/processor/commonConfig.ts new file mode 100644 index 00000000000..e7e2af7fbd1 --- /dev/null +++ b/test/integrations/destinations/rakuten/processor/commonConfig.ts @@ -0,0 +1,65 @@ +export const destination = { + ID: 'random_id', + Name: 'rakuten', + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + mid: 'dummyMarketingId', + }, +}; +export const endpoint = 'https://track.linksynergy.com/ep'; +export const commonOutputHeaders = { + accept: 'application/json', + 'content-type': 'application/json', +}; +export const singleProductWithAllProperties = { + sku: 'ABC123', + amount: 20, + quantity: 5, + name: 'SampleProduct', + brand: 'SampleBrand', + coupon: 'SALE20', + categoryId: '12345', + category: 'Electronics', + discountAmount: 10.5, + discountType: 'Percentage', + isClearance: 'Y', + isMarketPlace: 'N', + isSale: 'Y', + itmStatus: 'In Stock', + margin: 0.15, + markdown: 5.0, + shipId: 'SHIP123', + shipBy: 'Express', + taxExempt: 'N', + sequence: '123', + isComm: 'Y', +}; +export const commonProperties = { + orderId: 'SampleOrderId', + tr: 'SampleRanSiteID', + landTime: '20240129_1200', + date: '20240129_1300', + altord: 'SampleAlternateOrderId', + currency: 'INR', + creditCardType: 'Visa', + commReason: 'SampleCommReason', + isComm: 'Y', + consumed: '20240129_1400', + coupon: 'SampleCoupon', + custId: 'SampleCustomerId', + custScore: 'A', + custStatus: 'New', + dId: 'SampleDeviceId', + disamt: '50.00', + ordStatus: 'Pending', + segment: 'SampleSegment', + shipcountry: 'USA', + shipped: '20240129_1500', + sitename: 'SampleSiteName', + storeId: '12345', + storecat: 'Electronics', +}; diff --git a/test/integrations/destinations/rakuten/processor/data.ts b/test/integrations/destinations/rakuten/processor/data.ts new file mode 100644 index 00000000000..bdce4e850ec --- /dev/null +++ b/test/integrations/destinations/rakuten/processor/data.ts @@ -0,0 +1,3 @@ +import { transformationFailures } from './transformationFailure'; +import { trackSuccess } from './track'; +export const data = [...trackSuccess, ...transformationFailures]; diff --git a/test/integrations/destinations/rakuten/processor/track.ts b/test/integrations/destinations/rakuten/processor/track.ts new file mode 100644 index 00000000000..49b26e46581 --- /dev/null +++ b/test/integrations/destinations/rakuten/processor/track.ts @@ -0,0 +1,452 @@ +import { + destination, + commonOutputHeaders, + commonProperties, + endpoint, + singleProductWithAllProperties, +} from './commonConfig'; +import { transformResultBuilder } from '../../../testUtils'; +export const trackSuccess = [ + { + id: 'rakuten-test-track-success-1', + name: 'rakuten', + description: + 'Track call with properties.products with all properties in payload and one product containing all product properties and other containg some', + scenario: 'Business', + successCriteria: + 'Response should contain only properties and product payload and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + event: 'product purchased', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + channel: 'mobile', + rudderId: 'b7b24f86-f7bf-46d8-b2b4-ccafc080239c', + messageId: '1611588776408-ee5a3212-fbf9-4cbb-bbad-3ed0f7c6a2ce', + properties: { + ...commonProperties, + products: [ + { ...singleProductWithAllProperties }, + { + sku: 'custom sku 1', + quantity: 5, + amount: 25, + name: 'name_1', + }, + { + sku: 'custom sku 2', + name: 'SampleProduct', + quantity: 1, + amount: 30, + coupon: 'SALE50', + }, + ], + }, + anonymousId: '9c6bd77ea9da3e68', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + output: transformResultBuilder({ + method: 'GET', + endpoint, + headers: commonOutputHeaders, + params: { + mid: 'dummyMarketingId', + xml: 1, + source: 'rudderstack', + amtlist: '2000|2500|3000', + brandlist: 'SampleBrand||', + catidlist: '12345||', + catlist: 'Electronics||', + couponlist: 'SALE20||SALE50', + disamtlist: '10.5||', + distypelist: 'Percentage||', + ismarketplacelist: 'N||', + sequencelist: '123||', + shipbylist: 'Express||', + shipidlist: 'SHIP123||', + qlist: '5|5|1', + marginlist: '0.15||', + markdownlist: '5||', + taxexemptlist: 'N||', + namelist: 'SampleProduct|name_1|SampleProduct', + skulist: 'ABC123|custom sku 1|custom sku 2', + issalelist: 'Y||', + itmstatuslist: 'In Stock||', + isclearancelist: 'Y||', + ord: 'SampleOrderId', + tr: 'SampleRanSiteID', + land: '20240129_1200', + date: '20240129_1300', + altord: 'SampleAlternateOrderId', + cur: 'INR', + cc: 'Visa', + commreason: 'SampleCommReason', + iscomm: 'Y', + consumed: '20240129_1400', + coupon: 'SampleCoupon', + custid: 'SampleCustomerId', + custscore: 'A', + custstatus: 'New', + did: 'SampleDeviceId', + disamt: '50.00', + ordstatus: 'Pending', + segment: 'SampleSegment', + shipcountry: 'USA', + shipped: '20240129_1500', + sitename: 'SampleSiteName', + storeid: '12345', + storecat: 'Electronics', + }, + userId: '', + }), + statusCode: 200, + }, + ], + }, + }, + }, + { + id: 'rakuten-test-track-success-2', + name: 'rakuten', + description: + 'Track call with properties.products and no event in payload and products containing amount,price and quantity', + scenario: 'Business+Framework', + successCriteria: + 'Response should contain only properties and product payload and amount to be calculated from price*quantity where amount is not present and quantity taken as 1 by default and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + channel: 'mobile', + rudderId: 'b7b24f86-f7bf-46d8-b2b4-ccafc080239c', + messageId: '1611588776408-ee5a3212-fbf9-4cbb-bbad-3ed0f7c6a2ce', + properties: { + ...commonProperties, + products: [ + { + sku: 'custom sku 0', + amount: '125', + quantity: 1, + name: 'name_1', + }, + { + sku: 'custom sku 1', + quantity: 5, + price: 25, + name: 'name_2', + }, + { + sku: 'custom sku 2', + name: 'SampleProduct', + price: 30, + quantity: 1, + coupon: 'SALE50', + }, + ], + }, + anonymousId: '9c6bd77ea9da3e68', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + output: transformResultBuilder({ + method: 'GET', + endpoint, + headers: commonOutputHeaders, + params: { + mid: 'dummyMarketingId', + xml: 1, + source: 'rudderstack', + amtlist: '12500|12500|3000', + couponlist: '||SALE50', + namelist: 'name_1|name_2|SampleProduct', + skulist: 'custom sku 0|custom sku 1|custom sku 2', + qlist: '1|5|1', + ord: 'SampleOrderId', + tr: 'SampleRanSiteID', + land: '20240129_1200', + date: '20240129_1300', + altord: 'SampleAlternateOrderId', + cur: 'INR', + cc: 'Visa', + commreason: 'SampleCommReason', + iscomm: 'Y', + consumed: '20240129_1400', + coupon: 'SampleCoupon', + custid: 'SampleCustomerId', + custscore: 'A', + custstatus: 'New', + did: 'SampleDeviceId', + disamt: '50.00', + ordstatus: 'Pending', + segment: 'SampleSegment', + shipcountry: 'USA', + shipped: '20240129_1500', + sitename: 'SampleSiteName', + storeid: '12345', + storecat: 'Electronics', + }, + userId: '', + }), + statusCode: 200, + }, + ], + }, + }, + }, + { + id: 'rakuten-test-track-success-3', + name: 'rakuten', + description: + 'Track call for products return or cancelled products containing amount,price and quantity where price is negative', + scenario: 'Business', + successCriteria: + 'Response should contain only properties and product payload and amount to be calculated from price*quantity where amount is negative and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + channel: 'mobile', + rudderId: 'b7b24f86-f7bf-46d8-b2b4-ccafc080239c', + messageId: '1611588776408-ee5a3212-fbf9-4cbb-bbad-3ed0f7c6a2ce', + properties: { + ...commonProperties, + products: [ + { + sku: 'custom sku 0', + quantity: 1, + amount: '-125', + name: 'name_1', + }, + { + sku: 'custom sku 1', + quantity: 5, + price: -25, + name: 'name_2', + }, + ], + }, + anonymousId: '9c6bd77ea9da3e68', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + output: transformResultBuilder({ + method: 'GET', + endpoint, + headers: commonOutputHeaders, + params: { + mid: 'dummyMarketingId', + xml: 1, + source: 'rudderstack', + amtlist: '-12500|-12500', + skulist: 'custom sku 0|custom sku 1', + qlist: '1|5', + ord: 'SampleOrderId', + namelist: 'name_1|name_2', + tr: 'SampleRanSiteID', + land: '20240129_1200', + date: '20240129_1300', + altord: 'SampleAlternateOrderId', + cur: 'INR', + cc: 'Visa', + commreason: 'SampleCommReason', + iscomm: 'Y', + consumed: '20240129_1400', + coupon: 'SampleCoupon', + custid: 'SampleCustomerId', + custscore: 'A', + custstatus: 'New', + did: 'SampleDeviceId', + disamt: '50.00', + ordstatus: 'Pending', + segment: 'SampleSegment', + shipcountry: 'USA', + shipped: '20240129_1500', + sitename: 'SampleSiteName', + storeid: '12345', + storecat: 'Electronics', + }, + userId: '', + }), + statusCode: 200, + }, + ], + }, + }, + }, + { + id: 'rakuten-test-track-success-4', + name: 'rakuten', + description: 'Track call for Discount event ', + scenario: 'Business', + successCriteria: + 'Response should have last item of skulist as "Discount", qlist as 0 and amtlist as negative and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + channel: 'mobile', + rudderId: 'b7b24f86-f7bf-46d8-b2b4-ccafc080239c', + messageId: '1611588776408-ee5a3212-fbf9-4cbb-bbad-3ed0f7c6a2ce', + properties: { + orderId: 'SampleOrderId', + tr: 'SampleRanSiteID', + landTime: '20240129_1200', + products: [ + { + sku: 'custom sku 0', + quantity: 5, + amount: '125', + name: 'name_1', + }, + { + sku: 'custom sku 1', + quantity: 5, + price: 25, + name: 'name_2', + }, + { + sku: 'Discount', + quantity: 0, + amount: -500, + name: 'Discount', + }, + ], + }, + anonymousId: '9c6bd77ea9da3e68', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + output: transformResultBuilder({ + method: 'GET', + endpoint, + headers: commonOutputHeaders, + params: { + mid: 'dummyMarketingId', + xml: 1, + source: 'rudderstack', + namelist: 'name_1|name_2|Discount', + amtlist: '12500|12500|-50000', + skulist: 'custom sku 0|custom sku 1|Discount', + qlist: '5|5|0', + ord: 'SampleOrderId', + tr: 'SampleRanSiteID', + land: '20240129_1200', + }, + userId: '', + }), + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/rakuten/processor/transformationFailure.ts b/test/integrations/destinations/rakuten/processor/transformationFailure.ts new file mode 100644 index 00000000000..e35ab26b691 --- /dev/null +++ b/test/integrations/destinations/rakuten/processor/transformationFailure.ts @@ -0,0 +1,335 @@ +import { destination } from './commonConfig'; + +export const transformationFailures = [ + { + id: 'rakuten-test-2', + name: 'rakuten', + description: 'Required field orderId not present', + scenario: 'Framework', + successCriteria: 'Transformationn Error for orderId not present', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + event: 'product purchased', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + channel: 'mobile', + rudderId: 'b7b24f86-f7bf-46d8-b2b4-ccafc080239c', + messageId: '1611588776408-ee5a3212-fbf9-4cbb-bbad-3ed0f7c6a2ce', + properties: { + products: [{}], + }, + anonymousId: '9c6bd77ea9da3e68', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Missing required value from ["properties.order_id","properties.orderId"]: Workflow: procWorkflow, Step: prepareTrackPayload, ChildStep: undefined, OriginalError: Missing required value from ["properties.order_id","properties.orderId"]', + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + statTags: { + destType: 'RAKUTEN', + destinationId: 'dummyDestId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'rakuten-test-3', + name: 'rakuten', + description: 'No products available in products array to send', + scenario: 'Framework', + successCriteria: 'Transformationn Error for no products present to send', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + event: 'product purchased', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + channel: 'mobile', + rudderId: 'b7b24f86-f7bf-46d8-b2b4-ccafc080239c', + messageId: '1611588776408-ee5a3212-fbf9-4cbb-bbad-3ed0f7c6a2ce', + properties: { + land: '20230406_2342', + tr: 'txnId', + orderId: 'ord 123', + products: [], + }, + anonymousId: '9c6bd77ea9da3e68', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Either properties.product is not an array or is empty: Workflow: procWorkflow, Step: prepareTrackPayload, ChildStep: undefined, OriginalError: Either properties.product is not an array or is empty', + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + statTags: { + destType: 'RAKUTEN', + destinationId: 'dummyDestId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'rakuten-test-4', + name: 'rakuten', + description: 'Unsupported message type -> Identify', + scenario: 'Framework', + successCriteria: 'Transformationn Error for Unsupported message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'identify', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + channel: 'mobile', + rudderId: 'b7b24f86-f7bf-46d8-b2b4-ccafc080239c', + messageId: '1611588776408-ee5a3212-fbf9-4cbb-bbad-3ed0f7c6a2ce', + traits: { + orderId: 'ord 123', + products: [], + }, + anonymousId: '9c6bd77ea9da3e68', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'message type identify is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type identify is not supported', + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + statTags: { + destType: 'RAKUTEN', + errorCategory: 'dataValidation', + destinationId: 'dummyDestId', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'rakuten-test-5', + name: 'rakuten', + description: 'No eligible property available for required field tr present', + scenario: 'Framework', + successCriteria: 'Transformationn Error for required field tr not present', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + event: 'product purchased', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + channel: 'mobile', + rudderId: 'b7b24f86-f7bf-46d8-b2b4-ccafc080239c', + messageId: '1611588776408-ee5a3212-fbf9-4cbb-bbad-3ed0f7c6a2ce', + properties: { + orderId: 'ord 123', + products: [], + }, + anonymousId: '9c6bd77ea9da3e68', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Missing required value from ["properties.tr","properties.ran_site_id","properties.ranSiteID"]: Workflow: procWorkflow, Step: prepareTrackPayload, ChildStep: undefined, OriginalError: Missing required value from ["properties.tr","properties.ran_site_id","properties.ranSiteID"]', + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + statTags: { + destType: 'RAKUTEN', + destinationId: 'dummyDestId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + id: 'rakuten-test-6', + name: 'rakuten', + description: 'No eligible property available for required field land present', + scenario: 'Framework', + successCriteria: 'Transformationn Error for required field land not present', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + event: 'product purchased', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + channel: 'mobile', + rudderId: 'b7b24f86-f7bf-46d8-b2b4-ccafc080239c', + messageId: '1611588776408-ee5a3212-fbf9-4cbb-bbad-3ed0f7c6a2ce', + properties: { + tr: 'txnId', + orderId: 'ord 123', + products: [], + }, + anonymousId: '9c6bd77ea9da3e68', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Missing required value from ["properties.land","properties.land_time","properties.landTime"]: Workflow: procWorkflow, Step: prepareTrackPayload, ChildStep: undefined, OriginalError: Missing required value from ["properties.land","properties.land_time","properties.landTime"]', + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + statTags: { + destType: 'RAKUTEN', + destinationId: 'dummyDestId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/reddit/dataDelivery/business.ts b/test/integrations/destinations/reddit/dataDelivery/business.ts new file mode 100644 index 00000000000..2c4714ef13a --- /dev/null +++ b/test/integrations/destinations/reddit/dataDelivery/business.ts @@ -0,0 +1,131 @@ +import { + generateMetadata, + generateProxyV0Payload, + generateProxyV1Payload, +} from '../../../testUtils'; + +const validRequestPayload = { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'Purchase', + }, + user: { + aaid: 'c12d34889302d3c656b5699fa9190b51c50d6f62fce57e13bd56b503d66c487a', + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 3, + products: [ + { + id: '123', + name: 'Monopoly', + category: 'Games', + }, + { + id: '345', + name: 'UNO', + category: 'Games', + }, + ], + }, + }, + ], +}; + +const commonHeaders = { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', +}; + +const commonRequestParameters = { + headers: commonHeaders, + JSON: validRequestPayload, +}; + +export const testScenariosForV0API = [ + { + id: 'reddit_v0_scenario_1', + name: 'reddit', + description: + '[Proxy v0 API] :: Test for a valid request with a successful 200 response from the destination', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_fsddXXXfsfd', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + destResp: { + response: { + message: 'Successfully processed 1 conversion events.', + }, + status: 200, + }, + message: 'Request Processed Successfully', + status: 200, + }, + }, + }, + }, + }, +]; + +export const testScenariosForV1API = [ + { + id: 'reddit_v1_scenario_1', + name: 'reddit', + description: + '[Proxy v1 API] :: Test for a valid request with a successful 200 response from the destination', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: 'https://dfareporting.googleapis.com/test_url_for_valid_request', + }, + [generateMetadata(1)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request Processed Successfully', + response: [ + { + metadata: generateMetadata(1), + statusCode: 500, + }, + ], + status: 500, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/reddit/dataDelivery/data.ts b/test/integrations/destinations/reddit/dataDelivery/data.ts new file mode 100644 index 00000000000..54728ecb90e --- /dev/null +++ b/test/integrations/destinations/reddit/dataDelivery/data.ts @@ -0,0 +1,9 @@ +import { testScenariosForV0API, testScenariosForV1API } from './business'; +import { v0oauthScenarios, v1oauthScenarios } from './oauth'; + +export const data = [ + ...v0oauthScenarios, + ...v1oauthScenarios, + ...testScenariosForV0API, + ...testScenariosForV1API, +]; diff --git a/test/integrations/destinations/reddit/dataDelivery/oauth.ts b/test/integrations/destinations/reddit/dataDelivery/oauth.ts new file mode 100644 index 00000000000..90368cd60b0 --- /dev/null +++ b/test/integrations/destinations/reddit/dataDelivery/oauth.ts @@ -0,0 +1,147 @@ +import { + generateMetadata, + generateProxyV1Payload, + generateProxyV0Payload, +} from '../../../testUtils'; + +const authorizationRequiredRequestPayload = { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'ViewContent', + }, + user: { + aaid: 'c12d34889302d3c656b5699fa9190b51c50d6f62fce57e13bd56b503d66c487a', + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 3, + products: [ + { + id: '123', + name: 'Monopoly', + category: 'Games', + }, + { + id: '345', + name: 'UNO', + category: 'Games', + }, + ], + }, + }, + ], +}; + +const commonHeaders = { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', +}; + +const commonRequestParameters = { + headers: commonHeaders, + JSON: authorizationRequiredRequestPayload, +}; + +const expectedStatTags = { + destType: 'REDDIT', + destinationId: 'default-destinationId', + errorCategory: 'network', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'default-workspaceId', +}; + +export const v0oauthScenarios = [ + { + id: 'reddit_v0_oauth_scenario_1', + name: 'reddit', + description: '[Proxy v0 API] :: Oauth where Authorization Required response from destination', + successCriteria: 'Should return 500 with authErrorCategory as REFRESH_TOKEN', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_gsddXXXfsfd', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + authErrorCategory: 'REFRESH_TOKEN', + destinationResponse: { + response: 'Authorization Required', + status: 401, + }, + message: + "Request failed due to Authorization Required 'during reddit response transformation'", + statTags: expectedStatTags, + status: 500, + }, + }, + }, + }, + }, +]; + +export const v1oauthScenarios = [ + { + id: 'reddit_v1_oauth_scenario_1', + name: 'reddit', + description: '[Proxy v1 API] :: Oauth where Authorization Required response from destination', + successCriteria: 'Should return 500 with authErrorCategory as REFRESH_TOKEN', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_gsddXXXfsfd', + }, + [generateMetadata(1)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + authErrorCategory: 'REFRESH_TOKEN', + message: + "Request failed due to Authorization Required 'during reddit response transformation'", + response: [ + { + error: '"Authorization Required"', + metadata: generateMetadata(1), + statusCode: 500, + }, + ], + statTags: expectedStatTags, + status: 500, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/reddit/delivery/data.ts b/test/integrations/destinations/reddit/delivery/data.ts deleted file mode 100644 index 66c1e2863f3..00000000000 --- a/test/integrations/destinations/reddit/delivery/data.ts +++ /dev/null @@ -1,174 +0,0 @@ -export const data = [ - { - name: 'reddit', - description: 'Test 0', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_fsddXXXfsfd', - headers: { - Authorization: 'Bearer dummyAccessToken', - 'Content-Type': 'application/json', - }, - params: {}, - body: { - JSON: { - events: [ - { - event_at: '2019-10-14T09:03:17.562Z', - event_type: { - tracking_type: 'Purchase', - }, - user: { - aaid: 'c12d34889302d3c656b5699fa9190b51c50d6f62fce57e13bd56b503d66c487a', - email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', - external_id: '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', - ip_address: 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', - user_agent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - screen_dimensions: {}, - }, - event_metadata: { - item_count: 3, - products: [ - { - id: '123', - name: 'Monopoly', - category: 'Games', - }, - { - id: '345', - name: 'UNO', - category: 'Games', - }, - ], - }, - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: { - output: { - destResp: { - response: { - message: 'Successfully processed 1 conversion events.', - }, - status: 200, - }, - message: 'Request Processed Successfully', - status: 200, - }, - }, - }, - }, - }, - { - name: 'reddit', - description: 'Test 1', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_gsddXXXfsfd', - headers: { - Authorization: 'Bearer dummyAccessToken', - 'Content-Type': 'application/json', - }, - params: {}, - body: { - JSON: { - events: [ - { - event_at: '2019-10-14T09:03:17.562Z', - event_type: { - tracking_type: 'ViewContent', - }, - user: { - aaid: 'c12d34889302d3c656b5699fa9190b51c50d6f62fce57e13bd56b503d66c487a', - email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', - external_id: '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', - ip_address: 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', - user_agent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - screen_dimensions: {}, - }, - event_metadata: { - item_count: 3, - products: [ - { - id: '123', - name: 'Monopoly', - category: 'Games', - }, - { - id: '345', - name: 'UNO', - category: 'Games', - }, - ], - }, - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - method: 'POST', - }, - }, - output: { - response: { - status: 500, - body: { - output: { - authErrorCategory: 'REFRESH_TOKEN', - destinationResponse: { - response: 'Authorization Required', - status: 401, - }, - message: - "Request failed due to Authorization Required 'during reddit response transformation'", - statTags: { - destType: 'REDDIT', - destinationId: 'Non-determininable', - errorCategory: 'network', - errorType: 'retryable', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', - workspaceId: 'Non-determininable', - }, - status: 500, - }, - }, - }, - }, - }, -]; diff --git a/test/integrations/destinations/reddit/processor/data.ts b/test/integrations/destinations/reddit/processor/data.ts index 91da5fbe67e..49e0cd2baae 100644 --- a/test/integrations/destinations/reddit/processor/data.ts +++ b/test/integrations/destinations/reddit/processor/data.ts @@ -126,7 +126,177 @@ export const data = [ screen_dimensions: {}, }, event_metadata: { - item_count: 3, + item_count: 2, + currency: 'USD', + value: 1500, + value_decimal: 15, + products: [ + { + id: '123', + name: 'Monopoly', + category: 'Games', + }, + { + id: '345', + name: 'UNO', + category: 'Games', + }, + ], + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'reddit', + description: 'Track call with order completed event with floating point values for revenue', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + email: 'testone@gmail.com', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + ip: '54.100.200.255', + device: { + advertisingId: 'asfds7fdsihf734b34j43f', + }, + os: { + name: 'android', + }, + }, + type: 'track', + session_id: '16733896350494', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'Order Completed', + userId: 'testuserId1', + properties: { + checkout_id: '12345', + order_id: '1234', + affiliation: 'Apple Store', + total: 20, + revenue: 14.985, + shipping: 4, + tax: 1, + discount: 1.5, + coupon: 'ImagePro', + currency: 'USD', + products: [ + { + product_id: '123', + sku: 'G-32', + name: 'Monopoly', + price: 14, + quantity: 1, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + product_id: '345', + sku: 'F-32', + name: 'UNO', + price: 3.45, + quantity: 2, + category: 'Games', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_fsddXXXfsfd', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'Purchase', + }, + user: { + aaid: 'c12d34889302d3c656b5699fa9190b51c50d6f62fce57e13bd56b503d66c487a', + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: + '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: + 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 2, + currency: 'USD', + value: 1499, + value_decimal: 14.99, products: [ { id: '123', diff --git a/test/integrations/destinations/reddit/router/data.ts b/test/integrations/destinations/reddit/router/data.ts index 2f96e27ef72..723afff3746 100644 --- a/test/integrations/destinations/reddit/router/data.ts +++ b/test/integrations/destinations/reddit/router/data.ts @@ -205,7 +205,10 @@ export const data = [ screen_dimensions: {}, }, event_metadata: { - item_count: 3, + item_count: 2, + currency: 'USD', + value: 1500, + value_decimal: 15, products: [ { id: '123', name: 'Monopoly', category: 'Games' }, { id: '345', name: 'UNO', category: 'Games' }, diff --git a/test/integrations/destinations/revenue_cat/processor/data.ts b/test/integrations/destinations/revenue_cat/processor/data.ts index 4ebfe2f8a52..84b7c5975f8 100644 --- a/test/integrations/destinations/revenue_cat/processor/data.ts +++ b/test/integrations/destinations/revenue_cat/processor/data.ts @@ -1,1079 +1,1083 @@ export const data = [ - { - "name": "revenue_cat", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "as9d920a5e75a18acb4a29abd9ec1e2e", - "xPlatform": "stripe" - } - }, - "message": { - "userId": "rudder1235678", - "channel": "web", - "context": { - "ip": "14.5.67.21", - "app": { - "build": "1", - "name": "RudderAndroidClient", - "namespace": "com.rudderstack.demo.android", - "version": "1.0" - }, - "device": { - "manufacturer": "Google", - "model": "Android SDK built for x86", - "name": "generic_x86", - "type": "android" - }, - "library": { - "name": "com.rudderstack.android.sdk.core", - "version": "0.1.4" - }, - "locale": "en-US", - "network": { - "carrier": "Android", - "bluetooth": false, - "cellular": true, - "wifi": true - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content" - }, - "os": { - "name": "Android", - "version": "9" - }, - "screen": { - "density": 420, - "height": 1794, - "width": 1080 - }, - "timezone": "Asia/Mumbai", - "userAgent": "Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)" - }, - "type": "identify", - "traits": { - "email": "chandan@companyname.com", - "phone": "92374162212", - "lastname": "Doe", - "density": "420", - "height": "1794", - "width": "1080", - "iterableCampaignId": "1234", - "iterableTemplateId": "1234" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "GET", - "endpoint": "https://api.revenuecat.com/v1/subscribers/rudder1235678", - "headers": { - "Authorization": "Basic as9d920a5e75a18acb4a29abd9ec1e2e", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - }, - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.revenuecat.com/v1/subscribers/rudder1235678/attributes", - "headers": { - "Authorization": "Basic as9d920a5e75a18acb4a29abd9ec1e2e", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "attributes": { - "app_user_id": { - "value": "rudder1235678" - }, - "$email": { - "value": "chandan@companyname.com" - }, - "$phoneNumber": { - "value": "92374162212" - }, - "$ip": { - "value": "14.5.67.21" - }, - "$iterableCampaignId": { - "value": "1234" - }, - "$iterableTemplateId": { - "value": "1234" - }, - "$displayName": { - "value": "Doe" - }, - "lastname": { - "value": "Doe" - }, - "density": { - "value": "420" - }, - "height": { - "value": "1794" - }, - "width": { - "value": "1080" - } - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "revenue_cat", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "a5e75dfda29abd920ec1ec8a18acb42e", - "xPlatform": "stripe" - } - }, - "message": { - "userId": "rudder1235678", - "channel": "web", - "context": { - "ip": "14.5.67.21", - "app": { - "build": "1", - "name": "RudderAndroidClient", - "namespace": "com.rudderstack.demo.android", - "version": "1.0" - }, - "device": { - "manufacturer": "Google", - "model": "Android SDK built for x86", - "name": "generic_x86", - "type": "android" - }, - "library": { - "name": "com.rudderstack.android.sdk.core", - "version": "0.1.4" - }, - "locale": "en-US", - "network": { - "carrier": "Android", - "bluetooth": false, - "cellular": true, - "wifi": true - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content" - }, - "os": { - "name": "Android", - "version": "9" - }, - "screen": { - "density": 420, - "height": 1794, - "width": 1080 - }, - "timezone": "Asia/Mumbai", - "userAgent": "Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)" - }, - "type": "identify", - "traits": { - "email": "chandan@companyname.com", - "phone": "92374162212", - "firstname": "James", - "density": 420, - "height": 1794, - "width": 1080, - "iterableCampaignId": "1234", - "iterableTemplateId": "1234" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "GET", - "endpoint": "https://api.revenuecat.com/v1/subscribers/rudder1235678", - "headers": { - "Authorization": "Basic a5e75dfda29abd920ec1ec8a18acb42e", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - }, - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.revenuecat.com/v1/subscribers/rudder1235678/attributes", - "headers": { - "Authorization": "Basic a5e75dfda29abd920ec1ec8a18acb42e", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "attributes": { - "app_user_id": { - "value": "rudder1235678" - }, - "$email": { - "value": "chandan@companyname.com" - }, - "$phoneNumber": { - "value": "92374162212" - }, - "$ip": { - "value": "14.5.67.21" - }, - "$iterableCampaignId": { - "value": "1234" - }, - "$iterableTemplateId": { - "value": "1234" - }, - "$displayName": { - "value": "James" - }, - "firstname": { - "value": "James" - }, - "density": { - "value": "420" - }, - "height": { - "value": "1794" - }, - "width": { - "value": "1080" - } - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "revenue_cat", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "xPlatform": "stripe" - } - }, - "message": { - "userId": "rudder1235678", - "channel": "web", - "context": { - "ip": "14.5.67.21", - "app": { - "build": "1", - "name": "RudderAndroidClient", - "namespace": "com.rudderstack.demo.android", - "version": "1.0" - }, - "device": { - "manufacturer": "Google", - "model": "Android SDK built for x86", - "name": "generic_x86", - "type": "android" - }, - "library": { - "name": "com.rudderstack.android.sdk.core", - "version": "0.1.4" - }, - "locale": "en-US", - "network": { - "carrier": "Android", - "bluetooth": false, - "cellular": true, - "wifi": true - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content" - }, - "os": { - "name": "Android", - "version": "9" - }, - "screen": { - "density": 420, - "height": 1794, - "width": 1080 - }, - "timezone": "Asia/Mumbai", - "userAgent": "Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)" - }, - "type": "identify", - "traits": { - "email": "chandan@companyname.com", - "phone": "92374162212", - "name": "John Doe" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "Public API Key required for Authentication", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "configuration", - "destType": "REVENUE_CAT", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "revenue_cat", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "a5e75d99c8a18acb4a29abd920ec1e2e" - } - }, - "message": { - "userId": "rudder1235678", - "channel": "web", - "context": { - "ip": "14.5.67.21", - "app": { - "build": "1", - "name": "RudderAndroidClient", - "namespace": "com.rudderstack.demo.android", - "version": "1.0" - }, - "device": { - "manufacturer": "Google", - "model": "Android SDK built for x86", - "name": "generic_x86", - "type": "android" - }, - "library": { - "name": "com.rudderstack.android.sdk.core", - "version": "0.1.4" - }, - "locale": "en-US", - "network": { - "carrier": "Android", - "bluetooth": false, - "cellular": true, - "wifi": true - }, - "campaign": { - "source": "google", - "medium": "medium", - "term": "keyword", - "content": "some content" - }, - "os": { - "name": "Android", - "version": "9" - }, - "screen": { - "density": 420, - "height": 1794, - "width": 1080 - }, - "timezone": "Asia/Mumbai", - "userAgent": "Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)" - }, - "type": "identify", - "traits": { - "email": "chandan@companyname.com", - "phone": "92374162212", - "name": "John Doe" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "GET", - "endpoint": "https://api.revenuecat.com/v1/subscribers/rudder1235678", - "headers": { - "Authorization": "Basic a5e75d99c8a18acb4a29abd920ec1e2e", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - }, - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.revenuecat.com/v1/subscribers/rudder1235678/attributes", - "headers": { - "Authorization": "Basic a5e75d99c8a18acb4a29abd920ec1e2e", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "attributes": { - "app_user_id": { - "value": "rudder1235678" - }, - "$displayName": { - "value": "John Doe" - }, - "$email": { - "value": "chandan@companyname.com" - }, - "$phoneNumber": { - "value": "92374162212" - }, - "$ip": { - "value": "14.5.67.21" - } - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "revenue_cat", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey" - } - }, - "message": { - "type": "track", - "userId": "rudder123", - "properties": { - "checkout_id": "12345", - "order_id": "1234", - "affiliation": "Apple Store", - "total": 20, - "revenue": 15, - "shipping": 22, - "tax": 1, - "discount": 1.5, - "coupon": "ImagePro", - "currency": "USD", - "fetch_token": "dummyFetchToken", - "product_id": "123", - "products": [ - { - "sku": "G-32", - "name": "Monopoly", - "price": 14, - "quantity": 1, - "introductory_price": "350", - "is_restore": true, - "presented_offering_identifier": "123erd" - }, - { - "product_id": "345", - "sku": "F-32", - "name": "UNO", - "price": 3.45, - "quantity": 2, - "category": "Games", - "introductory_price": "250", - "is_restore": false, - "presented_offering_identifier": "123erd" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "X-Platform is required field", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "configuration", - "destType": "REVENUE_CAT", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "revenue_cat", - "description": "Test 5", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "xPlatform": "stripe" - } - }, - "message": { - "type": "track", - "userId": "rudder123", - "properties": { - "checkout_id": "12345", - "order_id": "1234", - "affiliation": "Apple Store", - "total": 20, - "revenue": 15, - "shipping": 22, - "tax": 1, - "discount": 1.5, - "coupon": "ImagePro", - "currency": "USD", - "fetch_token": "dummyFetchToken", - "product_id": "123", - "products": [ - { - "sku": "G-32", - "name": "Monopoly", - "price": 14, - "quantity": 1, - "introductory_price": "350", - "is_restore": true, - "presented_offering_identifier": "123erd" - }, - { - "product_id": "345", - "sku": "F-32", - "name": "UNO", - "price": 3.45, - "quantity": 2, - "category": "Games", - "introductory_price": "250", - "is_restore": false, - "presented_offering_identifier": "123erd" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.revenuecat.com/v1/receipts", - "headers": { - "Authorization": "Basic dummyApiKey", - "Content-Type": "application/json", - "X-Platform": "stripe" - }, - "params": {}, - "body": { - "JSON": { - "app_user_id": "rudder123", - "fetch_token": "dummyFetchToken", - "product_id": "123", - "currency": "USD", - "price": 14, - "introductory_price": "350", - "is_restore": true, - "presented_offering_identifier": "123erd" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - }, - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.revenuecat.com/v1/receipts", - "headers": { - "Authorization": "Basic dummyApiKey", - "Content-Type": "application/json", - "X-Platform": "stripe" - }, - "params": {}, - "body": { - "JSON": { - "app_user_id": "rudder123", - "fetch_token": "dummyFetchToken", - "product_id": "345", - "currency": "USD", - "price": 3.45, - "introductory_price": "250", - "is_restore": false, - "presented_offering_identifier": "123erd" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "revenue_cat", - "description": "Test 6", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "xPlatform": "stripe" - } - }, - "message": { - "type": "track", - "userId": "rudder123", - "properties": { - "checkout_id": "12345", - "order_id": "1234", - "affiliation": "Apple Store", - "total": 20, - "revenue": 15, - "shipping": 22, - "tax": 1, - "discount": 1.5, - "coupon": "ImagePro", - "currency": "USD", - "fetch_token": "dummyFetchToken", - "product_id": "123-sa", - "products": [ - { - "sku": "G-32", - "name": "Monopoly", - "price": 14, - "quantity": 1, - "introductory_price": "350", - "is_restore": true, - "presented_offering_identifier": "123erd" - }, - { - "product_id": "345", - "sku": "F-32", - "name": "UNO", - "price": 3.45, - "quantity": 2, - "category": "Games", - "introductory_price": "250", - "is_restore": false, - "presented_offering_identifier": "123erd" - }, - { - "sku": "G-33", - "name": "SunGlass", - "price": 14, - "quantity": 1, - "introductory_price": "350", - "is_restore": true, - "presented_offering_identifier": "123erd" - }, - { - "sku": "G-35", - "product_id": "1234sb", - "name": "Real-me", - "price": 14, - "quantity": 1, - "introductory_price": "350", - "is_restore": true, - "presented_offering_identifier": "123erd" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.revenuecat.com/v1/receipts", - "headers": { - "Authorization": "Basic dummyApiKey", - "Content-Type": "application/json", - "X-Platform": "stripe" - }, - "params": {}, - "body": { - "JSON": { - "app_user_id": "rudder123", - "fetch_token": "dummyFetchToken", - "product_id": "123-sa", - "currency": "USD", - "price": 14, - "introductory_price": "350", - "is_restore": true, - "presented_offering_identifier": "123erd" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - }, - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.revenuecat.com/v1/receipts", - "headers": { - "Authorization": "Basic dummyApiKey", - "Content-Type": "application/json", - "X-Platform": "stripe" - }, - "params": {}, - "body": { - "JSON": { - "app_user_id": "rudder123", - "fetch_token": "dummyFetchToken", - "product_id": "345", - "currency": "USD", - "price": 3.45, - "introductory_price": "250", - "is_restore": false, - "presented_offering_identifier": "123erd" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - }, - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.revenuecat.com/v1/receipts", - "headers": { - "Authorization": "Basic dummyApiKey", - "Content-Type": "application/json", - "X-Platform": "stripe" - }, - "params": {}, - "body": { - "JSON": { - "app_user_id": "rudder123", - "fetch_token": "dummyFetchToken", - "product_id": "123-sa", - "currency": "USD", - "price": 14, - "introductory_price": "350", - "is_restore": true, - "presented_offering_identifier": "123erd" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - }, - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.revenuecat.com/v1/receipts", - "headers": { - "Authorization": "Basic dummyApiKey", - "Content-Type": "application/json", - "X-Platform": "stripe" - }, - "params": {}, - "body": { - "JSON": { - "app_user_id": "rudder123", - "fetch_token": "dummyFetchToken", - "product_id": "1234sb", - "currency": "USD", - "price": 14, - "introductory_price": "350", - "is_restore": true, - "presented_offering_identifier": "123erd" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "revenue_cat", - "description": "Test 7", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "apiKey": "dummyApiKey", - "xPlatform": "stripe" - } - }, - "message": { - "type": "track", - "userId": "rudder123", - "properties": { - "checkout_id": "12345", - "order_id": "1234", - "affiliation": "Apple Store", - "total": 20, - "revenue": 15, - "shipping": 22, - "tax": 1, - "discount": 1.5, - "coupon": "ImagePro", - "currency": "USD", - "fetch_token": "dummyFetchToken", - "product_id": "123-sa", - "sku": "G-32", - "name": "Monopoly", - "price": 14, - "quantity": 1, - "introductory_price": "350", - "is_restore": true, - "presented_offering_identifier": "123erd" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.revenuecat.com/v1/receipts", - "headers": { - "Authorization": "Basic dummyApiKey", - "Content-Type": "application/json", - "X-Platform": "stripe" - }, - "params": {}, - "body": { - "JSON": { - "app_user_id": "rudder123", - "fetch_token": "dummyFetchToken", - "product_id": "123-sa", - "price": 14, - "currency": "USD", - "introductory_price": "350", - "is_restore": true, - "presented_offering_identifier": "123erd" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - } -] + { + name: 'revenue_cat', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'as9d920a5e75a18acb4a29abd9ec1e2e', + xPlatform: 'stripe', + }, + }, + message: { + userId: 'rudder1235678', + channel: 'web', + context: { + ip: '14.5.67.21', + app: { + build: '1', + name: 'RudderAndroidClient', + namespace: 'com.rudderstack.demo.android', + version: '1.0', + }, + device: { + manufacturer: 'Google', + model: 'Android SDK built for x86', + name: 'generic_x86', + type: 'android', + }, + library: { + name: 'com.rudderstack.android.sdk.core', + version: '0.1.4', + }, + locale: 'en-US', + network: { + carrier: 'Android', + bluetooth: false, + cellular: true, + wifi: true, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + }, + os: { + name: 'Android', + version: '9', + }, + screen: { + density: 420, + height: 1794, + width: 1080, + }, + timezone: 'Asia/Mumbai', + userAgent: + 'Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)', + }, + type: 'identify', + traits: { + email: 'chandan@companyname.com', + phone: '92374162212', + lastname: 'Doe', + density: '420', + height: '1794', + width: '1080', + iterableCampaignId: '1234', + iterableTemplateId: '1234', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: 'https://api.revenuecat.com/v1/subscribers/rudder1235678', + headers: { + Authorization: 'Basic as9d920a5e75a18acb4a29abd9ec1e2e', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.revenuecat.com/v1/subscribers/rudder1235678/attributes', + headers: { + Authorization: 'Basic as9d920a5e75a18acb4a29abd9ec1e2e', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + attributes: { + app_user_id: { + value: 'rudder1235678', + }, + $email: { + value: 'chandan@companyname.com', + }, + $phoneNumber: { + value: '92374162212', + }, + $ip: { + value: '14.5.67.21', + }, + $iterableCampaignId: { + value: '1234', + }, + $iterableTemplateId: { + value: '1234', + }, + $displayName: { + value: 'Doe', + }, + lastname: { + value: 'Doe', + }, + density: { + value: '420', + }, + height: { + value: '1794', + }, + width: { + value: '1080', + }, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'revenue_cat', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'a5e75dfda29abd920ec1ec8a18acb42e', + xPlatform: 'stripe', + }, + }, + message: { + userId: 'rudder1235678', + channel: 'web', + context: { + ip: '14.5.67.21', + app: { + build: '1', + name: 'RudderAndroidClient', + namespace: 'com.rudderstack.demo.android', + version: '1.0', + }, + device: { + manufacturer: 'Google', + model: 'Android SDK built for x86', + name: 'generic_x86', + type: 'android', + }, + library: { + name: 'com.rudderstack.android.sdk.core', + version: '0.1.4', + }, + locale: 'en-US', + network: { + carrier: 'Android', + bluetooth: false, + cellular: true, + wifi: true, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + }, + os: { + name: 'Android', + version: '9', + }, + screen: { + density: 420, + height: 1794, + width: 1080, + }, + timezone: 'Asia/Mumbai', + userAgent: + 'Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)', + }, + type: 'identify', + traits: { + email: 'chandan@companyname.com', + phone: '92374162212', + firstname: 'James', + density: 420, + height: 1794, + width: 1080, + iterableCampaignId: '1234', + iterableTemplateId: '1234', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: 'https://api.revenuecat.com/v1/subscribers/rudder1235678', + headers: { + Authorization: 'Basic a5e75dfda29abd920ec1ec8a18acb42e', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.revenuecat.com/v1/subscribers/rudder1235678/attributes', + headers: { + Authorization: 'Basic a5e75dfda29abd920ec1ec8a18acb42e', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + attributes: { + app_user_id: { + value: 'rudder1235678', + }, + $email: { + value: 'chandan@companyname.com', + }, + $phoneNumber: { + value: '92374162212', + }, + $ip: { + value: '14.5.67.21', + }, + $iterableCampaignId: { + value: '1234', + }, + $iterableTemplateId: { + value: '1234', + }, + $displayName: { + value: 'James', + }, + firstname: { + value: 'James', + }, + density: { + value: '420', + }, + height: { + value: '1794', + }, + width: { + value: '1080', + }, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'revenue_cat', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + xPlatform: 'stripe', + }, + }, + message: { + userId: 'rudder1235678', + channel: 'web', + context: { + ip: '14.5.67.21', + app: { + build: '1', + name: 'RudderAndroidClient', + namespace: 'com.rudderstack.demo.android', + version: '1.0', + }, + device: { + manufacturer: 'Google', + model: 'Android SDK built for x86', + name: 'generic_x86', + type: 'android', + }, + library: { + name: 'com.rudderstack.android.sdk.core', + version: '0.1.4', + }, + locale: 'en-US', + network: { + carrier: 'Android', + bluetooth: false, + cellular: true, + wifi: true, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + }, + os: { + name: 'Android', + version: '9', + }, + screen: { + density: 420, + height: 1794, + width: 1080, + }, + timezone: 'Asia/Mumbai', + userAgent: + 'Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)', + }, + type: 'identify', + traits: { + email: 'chandan@companyname.com', + phone: '92374162212', + name: 'John Doe', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Public API Key required for Authentication', + statTags: { + errorCategory: 'dataValidation', + errorType: 'configuration', + destType: 'REVENUE_CAT', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'revenue_cat', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'a5e75d99c8a18acb4a29abd920ec1e2e', + }, + }, + message: { + userId: 'rudder1235678', + channel: 'web', + context: { + ip: '14.5.67.21', + app: { + build: '1', + name: 'RudderAndroidClient', + namespace: 'com.rudderstack.demo.android', + version: '1.0', + }, + device: { + manufacturer: 'Google', + model: 'Android SDK built for x86', + name: 'generic_x86', + type: 'android', + }, + library: { + name: 'com.rudderstack.android.sdk.core', + version: '0.1.4', + }, + locale: 'en-US', + network: { + carrier: 'Android', + bluetooth: false, + cellular: true, + wifi: true, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + }, + os: { + name: 'Android', + version: '9', + }, + screen: { + density: 420, + height: 1794, + width: 1080, + }, + timezone: 'Asia/Mumbai', + userAgent: + 'Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)', + }, + type: 'identify', + traits: { + email: 'chandan@companyname.com', + phone: '92374162212', + name: 'John Doe', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: 'https://api.revenuecat.com/v1/subscribers/rudder1235678', + headers: { + Authorization: 'Basic a5e75d99c8a18acb4a29abd920ec1e2e', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.revenuecat.com/v1/subscribers/rudder1235678/attributes', + headers: { + Authorization: 'Basic a5e75d99c8a18acb4a29abd920ec1e2e', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + attributes: { + app_user_id: { + value: 'rudder1235678', + }, + $displayName: { + value: 'John Doe', + }, + $email: { + value: 'chandan@companyname.com', + }, + $phoneNumber: { + value: '92374162212', + }, + $ip: { + value: '14.5.67.21', + }, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'revenue_cat', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + }, + }, + message: { + type: 'track', + userId: 'rudder123', + properties: { + checkout_id: '12345', + order_id: '1234', + affiliation: 'Apple Store', + total: 20, + revenue: 15, + shipping: 22, + tax: 1, + discount: 1.5, + coupon: 'ImagePro', + currency: 'USD', + fetch_token: 'dummyFetchToken', + product_id: '123', + products: [ + { + sku: 'G-32', + name: 'Monopoly', + price: 14, + quantity: 1, + introductory_price: '350', + is_restore: true, + presented_offering_identifier: '123erd', + }, + { + product_id: '345', + sku: 'F-32', + name: 'UNO', + price: 3.45, + quantity: 2, + category: 'Games', + introductory_price: '250', + is_restore: false, + presented_offering_identifier: '123erd', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'X-Platform is required field', + statTags: { + errorCategory: 'dataValidation', + errorType: 'configuration', + destType: 'REVENUE_CAT', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'revenue_cat', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + xPlatform: 'stripe', + }, + }, + message: { + type: 'track', + userId: 'rudder123', + properties: { + checkout_id: '12345', + order_id: '1234', + affiliation: 'Apple Store', + total: 20, + revenue: 15, + shipping: 22, + tax: 1, + discount: 1.5, + coupon: 'ImagePro', + currency: 'USD', + fetch_token: 'dummyFetchToken', + product_id: '123', + products: [ + { + sku: 'G-32', + name: 'Monopoly', + price: 14, + quantity: 1, + introductory_price: '350', + is_restore: true, + presented_offering_identifier: '123erd', + }, + { + product_id: '345', + sku: 'F-32', + name: 'UNO', + price: 3.45, + quantity: 2, + category: 'Games', + introductory_price: '250', + is_restore: false, + presented_offering_identifier: '123erd', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.revenuecat.com/v1/receipts', + headers: { + Authorization: 'Basic dummyApiKey', + 'Content-Type': 'application/json', + 'X-Platform': 'stripe', + }, + params: {}, + body: { + JSON: { + app_user_id: 'rudder123', + fetch_token: 'dummyFetchToken', + product_id: '123', + currency: 'USD', + price: 14, + introductory_price: '350', + is_restore: true, + presented_offering_identifier: '123erd', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.revenuecat.com/v1/receipts', + headers: { + Authorization: 'Basic dummyApiKey', + 'Content-Type': 'application/json', + 'X-Platform': 'stripe', + }, + params: {}, + body: { + JSON: { + app_user_id: 'rudder123', + fetch_token: 'dummyFetchToken', + product_id: '345', + currency: 'USD', + price: 3.45, + introductory_price: '250', + is_restore: false, + presented_offering_identifier: '123erd', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'revenue_cat', + description: 'Test 6', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + xPlatform: 'stripe', + }, + }, + message: { + type: 'track', + userId: 'rudder123', + properties: { + checkout_id: '12345', + order_id: '1234', + affiliation: 'Apple Store', + total: 20, + revenue: 15, + shipping: 22, + tax: 1, + discount: 1.5, + coupon: 'ImagePro', + currency: 'USD', + fetch_token: 'dummyFetchToken', + product_id: '123-sa', + products: [ + { + sku: 'G-32', + name: 'Monopoly', + price: 14, + quantity: 1, + introductory_price: '350', + is_restore: true, + presented_offering_identifier: '123erd', + }, + { + product_id: '345', + sku: 'F-32', + name: 'UNO', + price: 3.45, + quantity: 2, + category: 'Games', + introductory_price: '250', + is_restore: false, + presented_offering_identifier: '123erd', + }, + { + sku: 'G-33', + name: 'SunGlass', + price: 14, + quantity: 1, + introductory_price: '350', + is_restore: true, + presented_offering_identifier: '123erd', + }, + { + sku: 'G-35', + product_id: '1234sb', + name: 'Real-me', + price: 14, + quantity: 1, + introductory_price: '350', + is_restore: true, + presented_offering_identifier: '123erd', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.revenuecat.com/v1/receipts', + headers: { + Authorization: 'Basic dummyApiKey', + 'Content-Type': 'application/json', + 'X-Platform': 'stripe', + }, + params: {}, + body: { + JSON: { + app_user_id: 'rudder123', + fetch_token: 'dummyFetchToken', + product_id: '123-sa', + currency: 'USD', + price: 14, + introductory_price: '350', + is_restore: true, + presented_offering_identifier: '123erd', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.revenuecat.com/v1/receipts', + headers: { + Authorization: 'Basic dummyApiKey', + 'Content-Type': 'application/json', + 'X-Platform': 'stripe', + }, + params: {}, + body: { + JSON: { + app_user_id: 'rudder123', + fetch_token: 'dummyFetchToken', + product_id: '345', + currency: 'USD', + price: 3.45, + introductory_price: '250', + is_restore: false, + presented_offering_identifier: '123erd', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.revenuecat.com/v1/receipts', + headers: { + Authorization: 'Basic dummyApiKey', + 'Content-Type': 'application/json', + 'X-Platform': 'stripe', + }, + params: {}, + body: { + JSON: { + app_user_id: 'rudder123', + fetch_token: 'dummyFetchToken', + product_id: '123-sa', + currency: 'USD', + price: 14, + introductory_price: '350', + is_restore: true, + presented_offering_identifier: '123erd', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.revenuecat.com/v1/receipts', + headers: { + Authorization: 'Basic dummyApiKey', + 'Content-Type': 'application/json', + 'X-Platform': 'stripe', + }, + params: {}, + body: { + JSON: { + app_user_id: 'rudder123', + fetch_token: 'dummyFetchToken', + product_id: '1234sb', + currency: 'USD', + price: 14, + introductory_price: '350', + is_restore: true, + presented_offering_identifier: '123erd', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'revenue_cat', + description: 'Test 7', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + xPlatform: 'stripe', + }, + }, + message: { + type: 'track', + userId: 'rudder123', + properties: { + checkout_id: '12345', + order_id: '1234', + affiliation: 'Apple Store', + total: 20, + revenue: 15, + shipping: 22, + tax: 1, + discount: 1.5, + coupon: 'ImagePro', + currency: 'USD', + fetch_token: 'dummyFetchToken', + product_id: '123-sa', + sku: 'G-32', + name: 'Monopoly', + price: 14, + quantity: 1, + introductory_price: '350', + is_restore: true, + presented_offering_identifier: '123erd', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.revenuecat.com/v1/receipts', + headers: { + Authorization: 'Basic dummyApiKey', + 'Content-Type': 'application/json', + 'X-Platform': 'stripe', + }, + params: {}, + body: { + JSON: { + app_user_id: 'rudder123', + fetch_token: 'dummyFetchToken', + product_id: '123-sa', + price: 14, + currency: 'USD', + introductory_price: '350', + is_restore: true, + presented_offering_identifier: '123erd', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/rockerbox/processor/data.ts b/test/integrations/destinations/rockerbox/processor/data.ts index efb74d2e6e9..76dd8ef11bb 100644 --- a/test/integrations/destinations/rockerbox/processor/data.ts +++ b/test/integrations/destinations/rockerbox/processor/data.ts @@ -1,749 +1,746 @@ export const data = [ - { - "name": "rockerbox", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "advertiserId": "KDH4JNDHCFJHJ57SJOWJE490W01JFNHGDSSFHDKDSDF" - } - }, - "message": { - "context": { - "traits": { - "homwTown": "kanpur", - "age": "24" - } - }, - "type": "Identify", - "userId": "yash001", - "originalTimestamp": "2019-10-14T09:03:17.562Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "Message type identify is not supported", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "ROCKERBOX", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "rockerbox", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "advertiserId": "test id", - "eventFilteringOption": "disable", - "whitelistedEvents": [ - { - "eventName": "" - } - ], - "blacklistedEvents": [ - { - "eventName": "" - } - ], - "eventsMap": [ - { - "from": "Product Added To Cart", - "to": "conv.add_to_cart" - } - ], - "useNativeSDK": { - "web": false - }, - "clientAuthId": { - "web": "test-client-auth-id" - }, - "oneTrustCookieCategories": { - "web": [ - { - "oneTrustCookieCategory": "Marketing Sample" - } - ] - }, - "customDomain": { - "web": "https://cookiedomain.com" - }, - "enableCookieSync": { - "web": true - } - } - }, - "message": { - "type": "track", - "event": "Product Added", - "sentAt": "2022-08-07T20:02:19.352Z", - "userId": "userSampleX138", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "locale": "en-IN", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 584, - "innerHeight": 789 - }, - "traits": { - "email": "userSampleX120@gmail.com", - "phone": "9878764736", - "last_name": "Stack", - "first_name": "Rudder", - "subscription": "youtube" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" - }, - "rudderId": "4a47e99b-2afc-45c6-b902-ed69282ca805", - "messageId": "1659902539347900-c622426c-a1dd-44c0-ac6d-d4dbee3f4a93", - "properties": { - "checkout_id": "12345", - "product_url": "http://www.yourdomain.com/products/red-t-shirt", - "product_name": "Red T-shirt" - }, - "anonymousId": "5f093403-1457-4a2c-b4e4-c61ec3bacf56", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-08-07T20:02:19.347Z" - }, - "writeKey": "2D0yaayoBD7bp8uFomnBONdedcA", - "requestIP": "[::1]", - "receivedAt": "2022-08-08T01:32:19.369+05:30" - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "The event is not associated to a RockerBox event. Aborting!", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "configuration", - "destType": "ROCKERBOX", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "rockerbox", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "advertiserId": "test id", - "eventFilteringOption": "disable", - "whitelistedEvents": [ - { - "eventName": "" - } - ], - "blacklistedEvents": [ - { - "eventName": "" - } - ], - "eventsMap": [ - { - "from": "Product Added", - "to": "conv.add_to_cart" - } - ], - "useNativeSDK": { - "web": false - }, - "clientAuthId": { - "web": "test-client-auth-id" - }, - "oneTrustCookieCategories": { - "web": [ - { - "oneTrustCookieCategory": "Marketing Sample" - } - ] - }, - "customDomain": { - "web": "https://cookiedomain.com" - }, - "enableCookieSync": { - "web": true - } - } - }, - "message": { - "type": "track", - "event": "Product Added", - "sentAt": "2022-08-07T20:02:19.352Z", - "userId": "userSampleX138", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "locale": "en-IN", - "traits": { - "email": "userSampleX120@gmail.com", - "phone": "9878764736", - "last_name": "Stack", - "first_name": "Rudder" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" - }, - "rudderId": "4a47e99b-2afc-45c6-b902-ed69282ca805", - "messageId": "1659902539347900-c622426c-a1dd-44c0-ac6d-d4dbee3f4a93", - "properties": { - "checkout_id": "12345", - "product_url": "http://www.yourdomain.com/products/red-t-shirt", - "product_name": "Red T-shirt" - }, - "anonymousId": "5f093403-1457-4a2c-b4e4-c61ec3bacf56", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-08-07T20:02:19.347Z" - }, - "writeKey": "2D0yaayoBD7bp8uFomnBONdedcA", - "requestIP": "[::1]", - "receivedAt": "2022-08-08T01:32:19.369+05:30" - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://webhooks.getrockerbox.com/rudderstack", - "headers": {}, - "params": { - "advertiser": "test id" - }, - "body": { - "JSON": { - "customer_id": "userSampleX138", - "anonymous_id": "5f093403-1457-4a2c-b4e4-c61ec3bacf56", - "email": "userSampleX120@gmail.com", - "phone": "9878764736", - "timestamp": 1659902539, - "conversion_source": "RudderStack", - "action": "conv.add_to_cart", - "checkout_id": "12345", - "product_url": "http://www.yourdomain.com/products/red-t-shirt", - "product_name": "Red T-shirt" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "rockerbox", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "advertiserId": "test id", - "eventFilteringOption": "disable", - "whitelistedEvents": [ - { - "eventName": "" - } - ], - "blacklistedEvents": [ - { - "eventName": "" - } - ], - "eventsMap": [ - { - "from": "Product Added", - "to": "conv.add_to_cart" - } - ], - "useNativeSDK": { - "web": false - }, - "clientAuthId": { - "web": "test-client-auth-id" - }, - "oneTrustCookieCategories": { - "web": [ - { - "oneTrustCookieCategory": "Marketing Sample" - } - ] - }, - "customDomain": { - "web": "https://cookiedomain.com" - }, - "enableCookieSync": { - "web": true - } - } - }, - "message": { - "type": "track", - "event": "Product Added", - "sentAt": "2022-08-07T20:02:19.352Z", - "userId": "userSampleX138", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "locale": "en-IN", - "traits": { - "email": "userSampleX120@gmail.com", - "phone": "9878764736", - "last_name": "Stack", - "first_name": "Rudder" - }, - "externalId": [ - { - "type": "rockerboxExternalId", - "id": "rbUid" - } - ], - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" - }, - "rudderId": "4a47e99b-2afc-45c6-b902-ed69282ca805", - "messageId": "1659902539347900-c622426c-a1dd-44c0-ac6d-d4dbee3f4a93", - "properties": { - "checkout_id": "12345", - "product_url": "http://www.yourdomain.com/products/red-t-shirt", - "product_name": "Red T-shirt", - "externalId": "rbUid", - "countryCode": "IN", - "listingId": "10101" - }, - "anonymousId": "5f093403-1457-4a2c-b4e4-c61ec3bacf56", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-08-07T20:02:19.347Z" - }, - "writeKey": "2D0yaayoBD7bp8uFomnBONdedcA", - "requestIP": "[::1]", - "receivedAt": "2022-08-08T01:32:19.369+05:30" - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://webhooks.getrockerbox.com/rudderstack", - "headers": {}, - "params": { - "advertiser": "test id" - }, - "body": { - "JSON": { - "customer_id": "userSampleX138", - "anonymous_id": "5f093403-1457-4a2c-b4e4-c61ec3bacf56", - "email": "userSampleX120@gmail.com", - "phone": "9878764736", - "timestamp": 1659902539, - "country_code": "IN", - "listing_id": "10101", - "conversion_source": "RudderStack", - "action": "conv.add_to_cart", - "checkout_id": "12345", - "product_url": "http://www.yourdomain.com/products/red-t-shirt", - "product_name": "Red T-shirt", - "externalId": "rbUid" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "rockerbox", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "advertiserId": "hdowhfiqhfwaiwhrdafshbfacicolsa", - "eventFilteringOption": "disable", - "whitelistedEvents": [ - { - "eventName": "" - } - ], - "blacklistedEvents": [ - { - "eventName": "" - } - ], - "eventsMap": [ - { - "from": "Product Added", - "to": "conv.add_to_cart" - } - ], - "customPropsMapping": [ - { - "from": "unit_id", - "to": "unitID" - }, - { - "from": "merch_id", - "to": "merch_id" - }, - { - "from": "bounce_id", - "to": "bounceID" - } - ], - "useNativeSDK": { - "web": false - }, - "useNativeSDKToSend": { - "web": false - }, - "clientAuthId": { - "web": "" - }, - "oneTrustCookieCategories": { - "web": [ - { - "oneTrustCookieCategory": "" - } - ] - }, - "customDomain": { - "web": "" - }, - "enableCookieSync": { - "web": false - } - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "anonymousId": "anon_id", - "type": "track", - "traits": { - "userId": "anon_id", - "email": "jamesDoe@gmail.com", - "name": "James Doe", - "phone": "92374162212", - "gender": "M", - "employed": true, - "birthday": "1614775793", - "education": "Science", - "graduate": true, - "married": true, - "customerType": "Prime", - "msg_push": true, - "msgSms": true, - "msgemail": true, - "msgwhatsapp": false, - "custom_tags": [ - "Test_User", - "Interested_User", - "DIY_Hobby" - ], - "custom_mappings": { - "Office": "Trastkiv", - "Country": "Russia" - }, - "address": { - "city": "kolkata", - "country": "India", - "postalCode": 789223, - "state": "WB", - "street": "" - } - }, - "properties": { - "unit_id": 123, - "merch_id": false, - "bounceiD": "fakefake", - "counce_id": "" - }, - "event": "Product Added", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "writeKey": "2D0yaayoBD7bp8uFomnBONdedcA", - "requestIP": "[::1]", - "receivedAt": "2022-08-08T01:32:19.369+05:30" - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://webhooks.getrockerbox.com/rudderstack", - "headers": {}, - "params": { - "advertiser": "hdowhfiqhfwaiwhrdafshbfacicolsa" - }, - "body": { - "JSON": { - "customer_id": "anon_id", - "anonymous_id": "anon_id", - "email": "jamesDoe@gmail.com", - "phone": "92374162212", - "timestamp": 1571043797, - "conversion_source": "RudderStack", - "action": "conv.add_to_cart", - "unit_id": 123, - "merch_id": false, - "bounceiD": "fakefake", - "counce_id": "" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "rockerbox", - "description": "Test 5", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "advertiserId": "KDH4JNDHCFJHJ57SJOWJE490W01JFNHGDSSFHDKDSDF" - } - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36", - "locale": "en-US", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - } - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "traits": { - "email": "jamesDoe@gmail.com", - "name": "James Doe", - "phone": "92374162212", - "gender": "M", - "employed": true, - "birthday": "1614775793", - "education": "Science", - "graduate": true, - "married": true, - "customerType": "Prime", - "msg_push": true, - "msgSms": true, - "msgemail": true, - "msgwhatsapp": false, - "custom_tags": [ - "Test_User", - "Interested_User", - "DIY_Hobby" - ], - "custom_mappings": { - "Office": "Trastkiv", - "Country": "Russia" - }, - "address": { - "city": "kolkata", - "country": "India", - "postalCode": 789223, - "state": "WB", - "street": "" - } - }, - "properties": { - "unit_id": 123, - "merch_id": false, - "bounceiD": "fakefake", - "counce_id": "" - }, - "event": "Product Added", - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "Anyone of userId or anonymousId is required to make the call", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "ROCKERBOX", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - } -] + { + name: 'rockerbox', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: 'KDH4JNDHCFJHJ57SJOWJE490W01JFNHGDSSFHDKDSDF', + }, + }, + message: { + context: { + traits: { + homwTown: 'kanpur', + age: '24', + }, + }, + type: 'Identify', + userId: 'yash001', + originalTimestamp: '2019-10-14T09:03:17.562Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Message type identify is not supported', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'ROCKERBOX', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'rockerbox', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: 'test id', + eventFilteringOption: 'disable', + whitelistedEvents: [ + { + eventName: '', + }, + ], + blacklistedEvents: [ + { + eventName: '', + }, + ], + eventsMap: [ + { + from: 'Product Added To Cart', + to: 'conv.add_to_cart', + }, + ], + useNativeSDK: { + web: false, + }, + clientAuthId: { + web: 'test-client-auth-id', + }, + oneTrustCookieCategories: { + web: [ + { + oneTrustCookieCategory: 'Marketing Sample', + }, + ], + }, + customDomain: { + web: 'https://cookiedomain.com', + }, + enableCookieSync: { + web: true, + }, + }, + }, + message: { + type: 'track', + event: 'Product Added', + sentAt: '2022-08-07T20:02:19.352Z', + userId: 'userSampleX138', + channel: 'web', + context: { + os: { + name: '', + version: '', + }, + locale: 'en-IN', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 584, + innerHeight: 789, + }, + traits: { + email: 'userSampleX120@gmail.com', + phone: '9878764736', + last_name: 'Stack', + first_name: 'Rudder', + subscription: 'youtube', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', + }, + rudderId: '4a47e99b-2afc-45c6-b902-ed69282ca805', + messageId: '1659902539347900-c622426c-a1dd-44c0-ac6d-d4dbee3f4a93', + properties: { + checkout_id: '12345', + product_url: 'http://www.yourdomain.com/products/red-t-shirt', + product_name: 'Red T-shirt', + }, + anonymousId: '5f093403-1457-4a2c-b4e4-c61ec3bacf56', + integrations: { + All: true, + }, + originalTimestamp: '2022-08-07T20:02:19.347Z', + }, + writeKey: '2D0yaayoBD7bp8uFomnBONdedcA', + requestIP: '[::1]', + receivedAt: '2022-08-08T01:32:19.369+05:30', + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'The event is not associated to a RockerBox event. Aborting!', + statTags: { + errorCategory: 'dataValidation', + errorType: 'configuration', + destType: 'ROCKERBOX', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'rockerbox', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: 'test id', + eventFilteringOption: 'disable', + whitelistedEvents: [ + { + eventName: '', + }, + ], + blacklistedEvents: [ + { + eventName: '', + }, + ], + eventsMap: [ + { + from: 'Product Added', + to: 'conv.add_to_cart', + }, + ], + useNativeSDK: { + web: false, + }, + clientAuthId: { + web: 'test-client-auth-id', + }, + oneTrustCookieCategories: { + web: [ + { + oneTrustCookieCategory: 'Marketing Sample', + }, + ], + }, + customDomain: { + web: 'https://cookiedomain.com', + }, + enableCookieSync: { + web: true, + }, + }, + }, + message: { + type: 'track', + event: 'Product Added', + sentAt: '2022-08-07T20:02:19.352Z', + userId: 'userSampleX138', + channel: 'web', + context: { + os: { + name: '', + version: '', + }, + locale: 'en-IN', + traits: { + email: 'userSampleX120@gmail.com', + phone: '9878764736', + last_name: 'Stack', + first_name: 'Rudder', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', + }, + rudderId: '4a47e99b-2afc-45c6-b902-ed69282ca805', + messageId: '1659902539347900-c622426c-a1dd-44c0-ac6d-d4dbee3f4a93', + properties: { + checkout_id: '12345', + product_url: 'http://www.yourdomain.com/products/red-t-shirt', + product_name: 'Red T-shirt', + }, + anonymousId: '5f093403-1457-4a2c-b4e4-c61ec3bacf56', + integrations: { + All: true, + }, + originalTimestamp: '2022-08-07T20:02:19.347Z', + }, + writeKey: '2D0yaayoBD7bp8uFomnBONdedcA', + requestIP: '[::1]', + receivedAt: '2022-08-08T01:32:19.369+05:30', + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://webhooks.getrockerbox.com/rudderstack', + headers: {}, + params: { + advertiser: 'test id', + }, + body: { + JSON: { + customer_id: 'userSampleX138', + anonymous_id: '5f093403-1457-4a2c-b4e4-c61ec3bacf56', + email: 'userSampleX120@gmail.com', + phone: '9878764736', + timestamp: 1659902539, + conversion_source: 'RudderStack', + action: 'conv.add_to_cart', + checkout_id: '12345', + product_url: 'http://www.yourdomain.com/products/red-t-shirt', + product_name: 'Red T-shirt', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'rockerbox', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: 'test id', + eventFilteringOption: 'disable', + whitelistedEvents: [ + { + eventName: '', + }, + ], + blacklistedEvents: [ + { + eventName: '', + }, + ], + eventsMap: [ + { + from: 'Product Added', + to: 'conv.add_to_cart', + }, + ], + useNativeSDK: { + web: false, + }, + clientAuthId: { + web: 'test-client-auth-id', + }, + oneTrustCookieCategories: { + web: [ + { + oneTrustCookieCategory: 'Marketing Sample', + }, + ], + }, + customDomain: { + web: 'https://cookiedomain.com', + }, + enableCookieSync: { + web: true, + }, + }, + }, + message: { + type: 'track', + event: 'Product Added', + sentAt: '2022-08-07T20:02:19.352Z', + userId: 'userSampleX138', + channel: 'web', + context: { + os: { + name: '', + version: '', + }, + locale: 'en-IN', + traits: { + email: 'userSampleX120@gmail.com', + phone: '9878764736', + last_name: 'Stack', + first_name: 'Rudder', + }, + externalId: [ + { + type: 'rockerboxExternalId', + id: 'rbUid', + }, + ], + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', + }, + rudderId: '4a47e99b-2afc-45c6-b902-ed69282ca805', + messageId: '1659902539347900-c622426c-a1dd-44c0-ac6d-d4dbee3f4a93', + properties: { + checkout_id: '12345', + product_url: 'http://www.yourdomain.com/products/red-t-shirt', + product_name: 'Red T-shirt', + externalId: 'rbUid', + countryCode: 'IN', + listingId: '10101', + }, + anonymousId: '5f093403-1457-4a2c-b4e4-c61ec3bacf56', + integrations: { + All: true, + }, + originalTimestamp: '2022-08-07T20:02:19.347Z', + }, + writeKey: '2D0yaayoBD7bp8uFomnBONdedcA', + requestIP: '[::1]', + receivedAt: '2022-08-08T01:32:19.369+05:30', + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://webhooks.getrockerbox.com/rudderstack', + headers: {}, + params: { + advertiser: 'test id', + }, + body: { + JSON: { + customer_id: 'userSampleX138', + anonymous_id: '5f093403-1457-4a2c-b4e4-c61ec3bacf56', + email: 'userSampleX120@gmail.com', + phone: '9878764736', + timestamp: 1659902539, + country_code: 'IN', + listing_id: '10101', + conversion_source: 'RudderStack', + action: 'conv.add_to_cart', + checkout_id: '12345', + product_url: 'http://www.yourdomain.com/products/red-t-shirt', + product_name: 'Red T-shirt', + externalId: 'rbUid', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'rockerbox', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: 'hdowhfiqhfwaiwhrdafshbfacicolsa', + eventFilteringOption: 'disable', + whitelistedEvents: [ + { + eventName: '', + }, + ], + blacklistedEvents: [ + { + eventName: '', + }, + ], + eventsMap: [ + { + from: 'Product Added', + to: 'conv.add_to_cart', + }, + ], + customPropsMapping: [ + { + from: 'unit_id', + to: 'unitID', + }, + { + from: 'merch_id', + to: 'merch_id', + }, + { + from: 'bounce_id', + to: 'bounceID', + }, + ], + useNativeSDK: { + web: false, + }, + useNativeSDKToSend: { + web: false, + }, + clientAuthId: { + web: '', + }, + oneTrustCookieCategories: { + web: [ + { + oneTrustCookieCategory: '', + }, + ], + }, + customDomain: { + web: '', + }, + enableCookieSync: { + web: false, + }, + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + type: 'track', + traits: { + userId: 'anon_id', + email: 'jamesDoe@gmail.com', + name: 'James Doe', + phone: '92374162212', + gender: 'M', + employed: true, + birthday: '1614775793', + education: 'Science', + graduate: true, + married: true, + customerType: 'Prime', + msg_push: true, + msgSms: true, + msgemail: true, + msgwhatsapp: false, + custom_tags: ['Test_User', 'Interested_User', 'DIY_Hobby'], + custom_mappings: { + Office: 'Trastkiv', + Country: 'Russia', + }, + address: { + city: 'kolkata', + country: 'India', + postalCode: 789223, + state: 'WB', + street: '', + }, + }, + properties: { + unit_id: 123, + merch_id: false, + bounceiD: 'fakefake', + counce_id: '', + }, + event: 'Product Added', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + writeKey: '2D0yaayoBD7bp8uFomnBONdedcA', + requestIP: '[::1]', + receivedAt: '2022-08-08T01:32:19.369+05:30', + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://webhooks.getrockerbox.com/rudderstack', + headers: {}, + params: { + advertiser: 'hdowhfiqhfwaiwhrdafshbfacicolsa', + }, + body: { + JSON: { + customer_id: 'anon_id', + anonymous_id: 'anon_id', + email: 'jamesDoe@gmail.com', + phone: '92374162212', + timestamp: 1571043797, + conversion_source: 'RudderStack', + action: 'conv.add_to_cart', + unit_id: 123, + merch_id: false, + bounceiD: 'fakefake', + counce_id: '', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'rockerbox', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: 'KDH4JNDHCFJHJ57SJOWJE490W01JFNHGDSSFHDKDSDF', + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + traits: { + email: 'jamesDoe@gmail.com', + name: 'James Doe', + phone: '92374162212', + gender: 'M', + employed: true, + birthday: '1614775793', + education: 'Science', + graduate: true, + married: true, + customerType: 'Prime', + msg_push: true, + msgSms: true, + msgemail: true, + msgwhatsapp: false, + custom_tags: ['Test_User', 'Interested_User', 'DIY_Hobby'], + custom_mappings: { + Office: 'Trastkiv', + Country: 'Russia', + }, + address: { + city: 'kolkata', + country: 'India', + postalCode: 789223, + state: 'WB', + street: '', + }, + }, + properties: { + unit_id: 123, + merch_id: false, + bounceiD: 'fakefake', + counce_id: '', + }, + event: 'Product Added', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Anyone of userId or anonymousId is required to make the call', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'ROCKERBOX', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/salesforce/dataDelivery/business.ts b/test/integrations/destinations/salesforce/dataDelivery/business.ts new file mode 100644 index 00000000000..4e98a3fc1a3 --- /dev/null +++ b/test/integrations/destinations/salesforce/dataDelivery/business.ts @@ -0,0 +1,380 @@ +import { ProxyMetdata } from '../../../../../src/types'; +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV1Payload } from '../../../testUtils'; + +const commonHeaders = { + Authorization: 'Bearer token', + 'Content-Type': 'application/json', +}; +const params = { destination: 'salesforce' }; + +const users = [ + { + Email: 'danis.archurav@sbermarket.ru', + Company: 'itus.ru', + LastName: 'Danis', + FirstName: 'Archurav', + LeadSource: 'App Signup', + account_type__c: 'free_trial', + }, +]; + +const statTags = { + aborted: { + destType: 'SALESFORCE', + destinationId: 'dummyDestinationId', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'dummyWorkspaceId', + }, + retryable: { + destType: 'SALESFORCE', + destinationId: 'dummyDestinationId', + errorCategory: 'network', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'dummyWorkspaceId', + }, + throttled: { + destType: 'SALESFORCE', + destinationId: 'dummyDestinationId', + errorCategory: 'network', + errorType: 'throttled', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'dummyWorkspaceId', + }, +}; + +export const proxyMetdata: ProxyMetdata = { + jobId: 1, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: {}, + dontBatch: false, +}; + +export const reqMetadataArray = [proxyMetdata]; + +const commonRequestParameters = { + headers: commonHeaders, + JSON: users[0], + params, +}; + +const externalIdSearchData = { Planning_Categories__c: 'pc', External_ID__c: 123 }; +export const externalIDSearchedData = { + headers: commonHeaders, + JSON: externalIdSearchData, + params, +}; + +export const testScenariosForV1API: ProxyV1TestData[] = [ + { + id: 'salesforce_v1_scenario_1', + name: 'salesforce', + description: + '[Proxy v1 API] :: Test for a valid request - Lead creation with existing unchanged leadId and unchanged data', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: + 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/existing_unchanged_leadId', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request for destination: salesforce Processed Successfully', + response: [ + { + error: '{"statusText":"No Content"}', + metadata: proxyMetdata, + statusCode: 200, + }, + ], + }, + }, + }, + }, + }, + { + id: 'salesforce_v1_scenario_2', + name: 'salesforce', + description: '[Proxy v1 API] :: Test with session expired scenario', + successCriteria: 'Should return 5XX with error Session expired or invalid, INVALID_SESSION_ID', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: + 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/invalid_session_id', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 500, + message: + 'Salesforce Request Failed - due to "Session expired or invalid", (Retryable) during Salesforce Response Handling', + response: [ + { + error: + '[{"message":"Session expired or invalid","errorCode":"INVALID_SESSION_ID"}]', + metadata: proxyMetdata, + statusCode: 500, + }, + ], + statTags: statTags.retryable, + }, + }, + }, + }, + }, + { + id: 'salesforce_v1_scenario_3', + name: 'salesforce', + description: '[Proxy v1 API] :: Test for Invalid Auth token passed in header', + successCriteria: 'Should return 401 INVALID_AUTH_HEADER', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/2', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: + 'Salesforce Request Failed: "401" due to "INVALID_HEADER_TYPE", (Aborted) during Salesforce Response Handling', + response: [ + { + error: '[{"message":"INVALID_HEADER_TYPE","errorCode":"INVALID_AUTH_HEADER"}]', + metadata: proxyMetdata, + statusCode: 400, + }, + ], + statTags: statTags.aborted, + }, + }, + }, + }, + }, + { + id: 'salesforce_v1_scenario_4', + name: 'salesforce', + description: '[Proxy v1 API] :: Test for rate limit exceeded scenario', + successCriteria: 'Should return 429 with error message "Request limit exceeded"', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/4', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: + 'Salesforce Request Failed - due to "REQUEST_LIMIT_EXCEEDED", (Throttled) during Salesforce Response Handling', + response: [ + { + error: + '[{"message":"Request limit exceeded","errorCode":"REQUEST_LIMIT_EXCEEDED"}]', + metadata: proxyMetdata, + statusCode: 429, + }, + ], + statTags: statTags.throttled, + status: 429, + }, + }, + }, + }, + }, + { + id: 'salesforce_v1_scenario_5', + name: 'salesforce', + description: '[Proxy v1 API] :: Test for server unavailable scenario', + successCriteria: 'Should return 500 with error message "Server Unavailable"', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/5', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: + 'Salesforce Request Failed - due to "Server Unavailable", (Retryable) during Salesforce Response Handling', + response: [ + { + error: '[{"message":"Server Unavailable","errorCode":"SERVER_UNAVAILABLE"}]', + metadata: proxyMetdata, + statusCode: 500, + }, + ], + statTags: statTags.retryable, + status: 500, + }, + }, + }, + }, + }, + { + id: 'salesforce_v1_scenario_6', + name: 'salesforce', + description: '[Proxy v1 API] :: Test for invalid grant scenario due to authentication failure', + successCriteria: + 'Should return 400 with error message "invalid_grant" due to "authentication failure"', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParameters, + endpoint: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/6', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: + 'Salesforce Request Failed: "400" due to "{"error":"invalid_grant","error_description":"authentication failure"}", (Aborted) during Salesforce Response Handling', + response: [ + { + error: '{"error":"invalid_grant","error_description":"authentication failure"}', + metadata: proxyMetdata, + statusCode: 400, + }, + ], + statTags: statTags.aborted, + status: 400, + }, + }, + }, + }, + }, + { + id: 'salesforce_v1_scenario_7', + name: 'salesforce', + description: '[Proxy v1 API] :: Test for a valid request - External ID search', + successCriteria: 'Should return 200 with list of matching records with External ID', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...externalIDSearchedData, + endpoint: + 'https://rudderstack.my.salesforce.com/services/data/v50.0/parameterizedSearch/?q=123&sobject=object_name&in=External_ID__c&object_name.fields=id,External_ID__c', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Request for destination: salesforce Processed Successfully', + response: [ + { + error: + '{"searchRecords":[{"attributes":{"type":"object_name","url":"/services/data/v50.0/sobjects/object_name/a0J75100002w97gEAA"},"Id":"a0J75100002w97gEAA","External_ID__c":"external_id"},{"attributes":{"type":"object_name","url":"/services/data/v50.0/sobjects/object_name/a0J75200002w9ZsEAI"},"Id":"a0J75200002w9ZsEAI","External_ID__c":"external_id TEST"}]}', + metadata: proxyMetdata, + statusCode: 200, + }, + ], + status: 200, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/salesforce/dataDelivery/data.ts b/test/integrations/destinations/salesforce/dataDelivery/data.ts index 2f1e04815b1..d376289d97d 100644 --- a/test/integrations/destinations/salesforce/dataDelivery/data.ts +++ b/test/integrations/destinations/salesforce/dataDelivery/data.ts @@ -1,7 +1,18 @@ import { AxiosError } from 'axios'; import MockAdapter from 'axios-mock-adapter'; +import { testScenariosForV1API } from './business'; +import { otherSalesforceScenariosV1 } from './other'; -export const data = [ +const legacyDataValue = { + Email: 'danis.archurav@sbermarket.ru', + Company: 'itus.ru', + LastName: 'Danis', + FirstName: 'Archurav', + LeadSource: 'App Signup', + account_type__c: 'free_trial', +}; + +const legacyTests = [ { name: 'salesforce', description: 'Test 0', @@ -24,14 +35,7 @@ export const data = [ body: { XML: {}, FORM: {}, - JSON: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + JSON: legacyDataValue, JSON_ARRAY: {}, }, metadata: { @@ -58,11 +62,6 @@ export const data = [ statusText: 'No Content', }, status: 204, - rudderJobMetadata: { - destInfo: { - authKey: '2HezPl1w11opbFSxnLDEgZ7kWTf', - }, - }, }, }, }, @@ -91,14 +90,7 @@ export const data = [ body: { XML: {}, FORM: {}, - JSON: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + JSON: legacyDataValue, JSON_ARRAY: {}, }, metadata: { @@ -128,11 +120,6 @@ export const data = [ errorCode: 'INVALID_SESSION_ID', }, ], - rudderJobMetadata: { - destInfo: { - authKey: '2HezPl1w11opbFSxnLDEgZ7kWTf', - }, - }, status: 401, }, statTags: { @@ -172,14 +159,7 @@ export const data = [ body: { XML: {}, FORM: {}, - JSON: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + JSON: legacyDataValue, JSON_ARRAY: {}, }, metadata: { @@ -210,11 +190,6 @@ export const data = [ }, ], status: 401, - rudderJobMetadata: { - destInfo: { - authKey: '2HezPl1w11opbFSxnLDEgZ7kWTf', - }, - }, }, statTags: { destType: 'SALESFORCE', @@ -253,14 +228,7 @@ export const data = [ body: { XML: {}, FORM: {}, - JSON: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + JSON: legacyDataValue, JSON_ARRAY: {}, }, metadata: { @@ -291,11 +259,6 @@ export const data = [ }, ], status: 403, - rudderJobMetadata: { - destInfo: { - authKey: '2HezPl1w11opbFSxnLDEgZ7kWTf', - }, - }, }, statTags: { destType: 'SALESFORCE', @@ -334,14 +297,7 @@ export const data = [ body: { XML: {}, FORM: {}, - JSON: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + JSON: legacyDataValue, JSON_ARRAY: {}, }, metadata: { @@ -372,11 +328,6 @@ export const data = [ }, ], status: 503, - rudderJobMetadata: { - destInfo: { - authKey: '2HezPl1w11opbFSxnLDEgZ7kWTf', - }, - }, }, statTags: { destType: 'SALESFORCE', @@ -415,14 +366,7 @@ export const data = [ body: { XML: {}, FORM: {}, - JSON: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + JSON: legacyDataValue, JSON_ARRAY: {}, }, metadata: { @@ -451,11 +395,6 @@ export const data = [ error_description: 'authentication failure', }, status: 400, - rudderJobMetadata: { - destInfo: { - authKey: '2HezPl1w11opbFSxnLDEgZ7kWTf', - }, - }, }, statTags: { destType: 'SALESFORCE', @@ -494,14 +433,7 @@ export const data = [ body: { XML: {}, FORM: {}, - JSON: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + JSON: legacyDataValue, JSON_ARRAY: {}, }, metadata: { @@ -526,11 +458,6 @@ export const data = [ errorCode: 'SERVER_UNAVAILABLE', message: 'Server Unavailable', }, - rudderJobMetadata: { - destInfo: { - authKey: '2HezPl1w11opbFSxnLDEgZ7kWTf', - }, - }, status: 503, }, message: @@ -619,11 +546,6 @@ export const data = [ ], }, status: 200, - rudderJobMetadata: { - destInfo: { - authKey: '2HezPl1w11opbFSxnLDEgZ7kWTf', - }, - }, }, }, }, @@ -685,11 +607,6 @@ export const data = [ destinationResponse: { response: '[ECONNABORTED] :: Connection aborted', status: 500, - rudderJobMetadata: { - destInfo: { - authKey: '2HezPl1w11opbFSxnLDEgZ7kWTf', - }, - }, }, statTags: { destType: 'SALESFORCE', @@ -783,11 +700,6 @@ export const data = [ destinationResponse: { response: '[EAI_AGAIN] :: Temporary failure in name resolution', status: 500, - rudderJobMetadata: { - destInfo: { - authKey: '2HezPl1w11opbFSxnLDEgZ7kWTf', - }, - }, }, statTags: { destType: 'SALESFORCE', @@ -831,3 +743,4 @@ export const data = [ }, }, ]; +export const data = [...legacyTests, ...testScenariosForV1API, ...otherSalesforceScenariosV1]; diff --git a/test/integrations/destinations/salesforce/dataDelivery/other.ts b/test/integrations/destinations/salesforce/dataDelivery/other.ts new file mode 100644 index 00000000000..b3361caba7f --- /dev/null +++ b/test/integrations/destinations/salesforce/dataDelivery/other.ts @@ -0,0 +1,106 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV1Payload } from '../../../testUtils'; + +const statTags = { + errorCategory: 'network', + errorType: 'retryable', + destType: 'SALESFORCE', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', +}; +const metadata = { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: false, +}; + +export const otherSalesforceScenariosV1: ProxyV1TestData[] = [ + { + id: 'salesforce_v1_other_scenario_1', + name: 'salesforce', + description: + '[Proxy v1 API] :: Scenario for testing Service Unavailable error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://sf_test_url/test_for_service_not_available', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: + '{"error":{"message":"Service Unavailable","description":"The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later."}}', + statusCode: 500, + metadata, + }, + ], + statTags, + message: + 'Salesforce Request Failed - due to "{"error":{"message":"Service Unavailable","description":"The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later."}}", (Retryable) during Salesforce Response Handling', + status: 500, + }, + }, + }, + }, + }, + { + id: 'salesforce_v1_other_scenario_2', + name: 'salesforce', + description: '[Proxy v1 API] :: Scenario for testing Internal Server error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_internal_server_error', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Internal Server Error"', + statusCode: 500, + metadata, + }, + ], + statTags, + message: + 'Salesforce Request Failed - due to ""Internal Server Error"", (Retryable) during Salesforce Response Handling', + status: 500, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/salesforce/network.ts b/test/integrations/destinations/salesforce/network.ts index 396fad9d698..b422271d366 100644 --- a/test/integrations/destinations/salesforce/network.ts +++ b/test/integrations/destinations/salesforce/network.ts @@ -1,15 +1,22 @@ +const commonHeaders = { + Authorization: 'Bearer token', + 'Content-Type': 'application/json', +}; + +const dataValue = { + Email: 'danis.archurav@sbermarket.ru', + Company: 'itus.ru', + LastName: 'Danis', + FirstName: 'Archurav', + LeadSource: 'App Signup', + account_type__c: 'free_trial', +}; + const tfProxyMocksData = [ { httpReq: { url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/1', - data: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + data: dataValue, params: { destination: 'salesforce' }, headers: { 'Content-Type': 'application/json', @@ -26,14 +33,7 @@ const tfProxyMocksData = [ { httpReq: { url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/3', - data: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + data: dataValue, params: { destination: 'salesforce' }, headers: { 'Content-Type': 'application/json', @@ -50,19 +50,11 @@ const tfProxyMocksData = [ { httpReq: { url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/2', - data: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + data: dataValue, params: { destination: 'salesforce' }, headers: { 'Content-Type': 'application/json', - Authorization: 'Bearer Incorrect_token', - 'User-Agent': 'RudderLabs', + Authorization: 'Bearer token', }, method: 'POST', }, @@ -74,14 +66,7 @@ const tfProxyMocksData = [ { httpReq: { url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/4', - data: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + data: dataValue, params: { destination: 'salesforce' }, headers: { 'Content-Type': 'application/json', @@ -98,14 +83,7 @@ const tfProxyMocksData = [ { httpReq: { url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/5', - data: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + data: dataValue, params: { destination: 'salesforce' }, headers: { 'Content-Type': 'application/json', @@ -122,14 +100,7 @@ const tfProxyMocksData = [ { httpReq: { url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/6', - data: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + data: dataValue, params: { destination: 'salesforce' }, headers: { 'Content-Type': 'application/json', @@ -146,19 +117,11 @@ const tfProxyMocksData = [ { httpReq: { url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/7', - data: { - Email: 'denis.kornilov@sbermarket.ru', - Company: 'sbermarket.ru', - LastName: 'Корнилов', - FirstName: 'Денис', - LeadSource: 'App Signup', - account_type__c: 'free_trial', - }, + data: dataValue, params: { destination: 'salesforce' }, headers: { 'Content-Type': 'application/json', Authorization: 'Bearer token', - 'User-Agent': 'RudderLabs', }, method: 'POST', }, @@ -323,4 +286,185 @@ const transformationMocksData = [ }, }, ]; -export const networkCallsData = [...tfProxyMocksData, ...transformationMocksData]; + +const businessMockData = [ + { + description: + 'Mock response from destination depicting a valid lead request, with no changed data', + httpReq: { + method: 'post', + url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/existing_unchanged_leadId', + data: dataValue, + headers: commonHeaders, + }, + httpRes: { + data: { statusText: 'No Content' }, + status: 204, + }, + }, + { + description: 'Mock response from destination depicting a invalid session id', + httpReq: { + method: 'post', + url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/invalid_session_id', + data: dataValue, + headers: commonHeaders, + }, + httpRes: { + data: [{ message: 'Session expired or invalid', errorCode: 'INVALID_SESSION_ID' }], + status: 500, + }, + }, + { + httpReq: { + url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/2', + data: dataValue, + params: { destination: 'salesforce' }, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer Incorrect_token', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: [{ message: 'INVALID_HEADER_TYPE', errorCode: 'INVALID_AUTH_HEADER' }], + status: 401, + }, + }, + { + httpReq: { + url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/4', + data: dataValue, + params: { destination: 'salesforce' }, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer token', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: [{ message: 'Request limit exceeded', errorCode: 'REQUEST_LIMIT_EXCEEDED' }], + status: 403, + }, + }, + { + httpReq: { + url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/5', + data: dataValue, + params: { destination: 'salesforce' }, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer token', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: [{ message: 'Server Unavailable', errorCode: 'SERVER_UNAVAILABLE' }], + status: 503, + }, + }, + { + httpReq: { + url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/6', + data: dataValue, + params: { destination: 'salesforce' }, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer token', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: { error: 'invalid_grant', error_description: 'authentication failure' }, + status: 400, + }, + }, + { + httpReq: { + url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/7', + data: dataValue, + params: { destination: 'salesforce' }, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer token', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: { + message: 'Server Unavailable', + errorCode: 'SERVER_UNAVAILABLE', + }, + status: 503, + }, + }, + { + httpReq: { + url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/parameterizedSearch/?q=123&sobject=object_name&in=External_ID__c&object_name.fields=id,External_ID__c', + data: { Planning_Categories__c: 'pc', External_ID__c: 123 }, + params: { destination: 'salesforce' }, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer token', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: { + searchRecords: [ + { + attributes: { + type: 'object_name', + url: '/services/data/v50.0/sobjects/object_name/a0J75100002w97gEAA', + }, + Id: 'a0J75100002w97gEAA', + External_ID__c: 'external_id', + }, + { + attributes: { + type: 'object_name', + url: '/services/data/v50.0/sobjects/object_name/a0J75200002w9ZsEAI', + }, + Id: 'a0J75200002w9ZsEAI', + External_ID__c: 'external_id TEST', + }, + ], + }, + status: 200, + }, + }, +]; + +const otherMocksData = [ + { + description: + 'Mock response from destination depicting a valid lead request, with no changed data', + httpReq: { + method: 'post', + url: 'https://sf_test_url/test_for_service_not_available', + }, + httpRes: { + data: { + error: { + message: 'Service Unavailable', + description: + 'The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later.', + }, + }, + status: 503, + }, + }, +]; + +export const networkCallsData = [ + ...tfProxyMocksData, + ...transformationMocksData, + ...businessMockData, + ...otherMocksData, +]; diff --git a/test/integrations/destinations/salesforce_oauth/dataDelivery/data.ts b/test/integrations/destinations/salesforce_oauth/dataDelivery/data.ts new file mode 100644 index 00000000000..bed8eec8db9 --- /dev/null +++ b/test/integrations/destinations/salesforce_oauth/dataDelivery/data.ts @@ -0,0 +1,3 @@ +import { testScenariosForV1API } from './oauth'; + +export const data = [...testScenariosForV1API]; diff --git a/test/integrations/destinations/salesforce_oauth/dataDelivery/oauth.ts b/test/integrations/destinations/salesforce_oauth/dataDelivery/oauth.ts new file mode 100644 index 00000000000..55eaa9cca1e --- /dev/null +++ b/test/integrations/destinations/salesforce_oauth/dataDelivery/oauth.ts @@ -0,0 +1,174 @@ +import { ProxyMetdata } from '../../../../../src/types'; +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV1Payload } from '../../../testUtils'; + +const commonHeadersForWrongToken = { + Authorization: 'Bearer expiredAccessToken', + 'Content-Type': 'application/json', +}; + +const commonHeadersForRightToken = { + Authorization: 'Bearer correctAccessToken', + 'Content-Type': 'application/json', +}; +const params = { destination: 'salesforce_oauth' }; + +const users = [ + { + Email: 'danis.archurav@sbermarket.ru', + Company: 'itus.ru', + LastName: 'Danis', + FirstName: 'Archurav', + LeadSource: 'App Signup', + account_type__c: 'free_trial', + }, +]; + +const statTags = { + retryable: { + destType: 'SALESFORCE_OAUTH', + destinationId: 'dummyDestinationId', + errorCategory: 'network', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'dummyWorkspaceId', + }, +}; + +const commonRequestParametersWithWrongToken = { + headers: commonHeadersForWrongToken, + JSON: users[0], + params, +}; + +const commonRequestParametersWithRightToken = { + headers: commonHeadersForRightToken, + JSON: users[0], + params, +}; + +export const proxyMetdataWithSecretWithWrongAccessToken: ProxyMetdata = { + jobId: 1, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: { + access_token: 'expiredAccessToken', + instanceUrl: 'https://rudderstack.my.salesforce_oauth.com', + }, + destInfo: { authKey: 'dummyDestinationId' }, + dontBatch: false, +}; + +export const proxyMetdataWithSecretWithRightAccessToken: ProxyMetdata = { + jobId: 1, + attemptNum: 1, + userId: 'dummyUserId', + sourceId: 'dummySourceId', + destinationId: 'dummyDestinationId', + workspaceId: 'dummyWorkspaceId', + secret: { + access_token: 'expiredRightToken', + instanceUrl: 'https://rudderstack.my.salesforce_oauth.com', + }, + destInfo: { authKey: 'dummyDestinationId' }, + dontBatch: false, +}; + +export const reqMetadataArrayWithWrongSecret = [proxyMetdataWithSecretWithWrongAccessToken]; +export const reqMetadataArray = [proxyMetdataWithSecretWithRightAccessToken]; + +export const testScenariosForV1API: ProxyV1TestData[] = [ + { + id: 'salesforce_v1_scenario_1', + name: 'salesforce_oauth', + description: '[Proxy v1 API] :: Test with expired access token scenario', + successCriteria: + 'Should return 5XX with error category REFRESH_TOKEN and Session expired or invalid, INVALID_SESSION_ID', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParametersWithWrongToken, + endpoint: + 'https://rudderstack.my.salesforce_oauth.com/services/data/v50.0/sobjects/Lead/20', + }, + reqMetadataArrayWithWrongSecret, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + authErrorCategory: 'REFRESH_TOKEN', + message: + 'Salesforce Request Failed - due to "INVALID_SESSION_ID", (Retryable) during Salesforce Response Handling', + response: [ + { + error: + '[{"message":"Session expired or invalid","errorCode":"INVALID_SESSION_ID"}]', + metadata: proxyMetdataWithSecretWithWrongAccessToken, + statusCode: 500, + }, + ], + statTags: statTags.retryable, + }, + }, + }, + }, + }, + { + id: 'salesforce_v1_scenario_2', + name: 'salesforce', + description: + '[Proxy v1 API] :: Test for a valid request - Lead creation with existing unchanged leadId and unchanged data', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + ...commonRequestParametersWithRightToken, + endpoint: + 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/existing_unchanged_leadId', + }, + reqMetadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request for destination: salesforce Processed Successfully', + response: [ + { + error: '{"statusText":"No Content"}', + metadata: proxyMetdataWithSecretWithRightAccessToken, + statusCode: 200, + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/salesforce_oauth/network.ts b/test/integrations/destinations/salesforce_oauth/network.ts new file mode 100644 index 00000000000..ae5f9d3fe49 --- /dev/null +++ b/test/integrations/destinations/salesforce_oauth/network.ts @@ -0,0 +1,51 @@ +const headerWithWrongAccessToken = { + Authorization: 'Bearer expiredAccessToken', + 'Content-Type': 'application/json', +}; + +const headerWithRightAccessToken = { + Authorization: 'Bearer correctAccessToken', + 'Content-Type': 'application/json', +}; + +const dataValue = { + Email: 'danis.archurav@sbermarket.ru', + Company: 'itus.ru', + LastName: 'Danis', + FirstName: 'Archurav', + LeadSource: 'App Signup', + account_type__c: 'free_trial', +}; + +const businessMockData = [ + { + description: 'Mock response from destination depicting an expired access token', + httpReq: { + method: 'post', + url: 'https://rudderstack.my.salesforce_oauth.com/services/data/v50.0/sobjects/Lead/20', + headers: headerWithWrongAccessToken, + data: dataValue, + params: { destination: 'salesforce_oauth' }, + }, + httpRes: { + data: [{ message: 'Session expired or invalid', errorCode: 'INVALID_SESSION_ID' }], + status: 401, + }, + }, + { + description: + 'Mock response from destination depicting a valid lead request, with no changed data', + httpReq: { + method: 'post', + url: 'https://rudderstack.my.salesforce.com/services/data/v50.0/sobjects/Lead/existing_unchanged_leadId', + data: dataValue, + headers: headerWithRightAccessToken, + }, + httpRes: { + data: { statusText: 'No Content' }, + status: 204, + }, + }, +]; + +export const networkCallsData = [...businessMockData]; diff --git a/test/integrations/destinations/segment/processor/data.ts b/test/integrations/destinations/segment/processor/data.ts index b2b8c679a52..9ba9601d6ef 100644 --- a/test/integrations/destinations/segment/processor/data.ts +++ b/test/integrations/destinations/segment/processor/data.ts @@ -1,670 +1,675 @@ export const data = [ - { - "name": "segment", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "ID": "1afmecIpsJm7D72aRTksxyODrwR", - "Name": "Segment", - "DestinationDefinition": { - "ID": "1afjjahf0X5lSyNze7Xh7aqJs11", - "Name": "SEGMENT", - "DisplayName": "Segment", - "Config": { - "excludeKeys": [], - "includeKeys": [] - } - }, - "Config": { - "writeKey": "abcdefghijklmnopqrstuvwxyz" - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "anonymousId": "ac7722c2-ccb6-4ae2-baf6-1effe861f4cd", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.1-rc.2" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.1-rc.2" - }, - "locale": "en-GB", - "os": { - "name": "", - "version": "" - }, - "page": { - "path": "/tests/html/index4.html", - "referrer": "", - "search": "", - "title": "", - "url": "http://localhost/tests/html/index4.html" - }, - "screen": { - "density": 2 - }, - "traits": { - "age": 23, - "email": "testmp@rudderstack.com", - "firstname": "Test Kafka" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36" - }, - "integrations": { - "All": true - }, - "messageId": "258b77c6-442d-4bdc-8729-f0e4cef41353", - "name": "home", - "originalTimestamp": "2020-04-17T14:55:31.367Z", - "properties": { - "path": "/tests/html/index4.html", - "referrer": "", - "search": "", - "title": "", - "url": "http://localhost/tests/html/index4.html" - }, - "receivedAt": "2020-04-17T20:25:31.381+05:30", - "request_ip": "[::1]:57363", - "sentAt": "2020-04-17T14:55:31.367Z", - "timestamp": "2020-04-17T20:25:31.381+05:30", - "type": "page", - "userId": "user12345" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "userId": "user12345", - "endpoint": "https://api.segment.io/v1/batch", - "headers": { - "Content-Type": "application/json", - "Authorization": "Basic YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo6" - }, - "params": {}, - "body": { - "JSON": { - "batch": [ - { - "anonymousId": "ac7722c2-ccb6-4ae2-baf6-1effe861f4cd", - "type": "page", - "userId": "user12345", - "traits": { - "age": 23, - "email": "testmp@rudderstack.com", - "firstname": "Test Kafka" - }, - "properties": { - "path": "/tests/html/index4.html", - "referrer": "", - "search": "", - "title": "", - "url": "http://localhost/tests/html/index4.html" - }, - "timeStamp": "2020-04-17T20:25:31.381+05:30" - } - ] - }, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "statusCode": 200 - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "segment", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "ID": "1afmecIpsJm7D72aRTksxyODrwR", - "Name": "Segment", - "DestinationDefinition": { - "ID": "1afjjahf0X5lSyNze7Xh7aqJs11", - "Name": "SEGMENT", - "DisplayName": "Segment", - "Config": { - "excludeKeys": [], - "includeKeys": [] - } - }, - "Config": { - "writeKey": "abcdefghijklmnopqrstuvwxyz" - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "anonymousId": "ac7722c2-ccb6-4ae2-baf6-1effe861f4cd", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.1-rc.2" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.1-rc.2" - }, - "locale": "en-GB", - "os": { - "name": "", - "version": "" - }, - "page": { - "path": "/tests/html/index4.html", - "referrer": "", - "search": "", - "title": "", - "url": "http://localhost/tests/html/index4.html" - }, - "screen": { - "density": 2 - }, - "traits": { - "age": 23, - "email": "testmp@email.com", - "firstname": "Test Transformer" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36" - }, - "integrations": { - "All": true - }, - "messageId": "023a3a48-190a-4968-9394-a8e99b81a3c0", - "originalTimestamp": "2020-04-17T14:55:31.37Z", - "receivedAt": "2020-04-17T20:25:31.401+05:30", - "request_ip": "[::1]:57364", - "sentAt": "2020-04-17T14:55:31.37Z", - "timestamp": "2020-04-17T20:25:31.401+05:30", - "type": "identify", - "userId": "user12345" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "userId": "user12345", - "method": "POST", - "endpoint": "https://api.segment.io/v1/batch", - "headers": { - "Content-Type": "application/json", - "Authorization": "Basic YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo6" - }, - "params": {}, - "body": { - "JSON": { - "batch": [ - { - "anonymousId": "ac7722c2-ccb6-4ae2-baf6-1effe861f4cd", - "type": "identify", - "userId": "user12345", - "traits": { - "age": 23, - "email": "testmp@email.com", - "firstname": "Test Transformer" - }, - "timeStamp": "2020-04-17T20:25:31.401+05:30" - } - ] - }, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "statusCode": 200 - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "segment", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "ID": "1afmecIpsJm7D72aRTksxyODrwR", - "Name": "Segment", - "DestinationDefinition": { - "ID": "1afjjahf0X5lSyNze7Xh7aqJs11", - "Name": "SEGMENT", - "DisplayName": "Segment", - "Config": { - "excludeKeys": [], - "includeKeys": [] - } - }, - "Config": { - "writeKey": "abcdefghijklmnopqrstuvwxyz" - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "anonymousId": "ac7722c2-ccb6-4ae2-baf6-1effe861f4cd", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.1-rc.2" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.1-rc.2" - }, - "locale": "en-GB", - "os": { - "name": "", - "version": "" - }, - "page": { - "path": "/tests/html/index4.html", - "referrer": "", - "search": "", - "title": "", - "url": "http://localhost/tests/html/index4.html" - }, - "screen": { - "density": 2 - }, - "traits": { - "age": 23, - "email": "testmp@email.com", - "firstname": "Test Transformer" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36" - }, - "event": "test track with property", - "integrations": { - "All": true - }, - "messageId": "584fde02-901a-4964-a4a0-4078b999d5b2", - "originalTimestamp": "2020-04-17T14:55:31.372Z", - "properties": { - "test_prop_1": "test prop", - "test_prop_2": 1232 - }, - "receivedAt": "2020-04-17T20:25:31.401+05:30", - "request_ip": "[::1]:57365", - "sentAt": "2020-04-17T14:55:31.372Z", - "timestamp": "2020-04-17T20:25:31.401+05:30", - "type": "track", - "userId": "user12345" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "userId": "user12345", - "method": "POST", - "endpoint": "https://api.segment.io/v1/batch", - "headers": { - "Content-Type": "application/json", - "Authorization": "Basic YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo6" - }, - "params": {}, - "body": { - "JSON": { - "batch": [ - { - "anonymousId": "ac7722c2-ccb6-4ae2-baf6-1effe861f4cd", - "type": "track", - "userId": "user12345", - "event": "test track with property", - "traits": { - "age": 23, - "email": "testmp@email.com", - "firstname": "Test Transformer" - }, - "properties": { - "test_prop_1": "test prop", - "test_prop_2": 1232 - }, - "timeStamp": "2020-04-17T20:25:31.401+05:30" - } - ] - }, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "statusCode": 200 - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "segment", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "ID": "1afmecIpsJm7D72aRTksxyODrwR", - "Name": "Segment", - "DestinationDefinition": { - "ID": "1afjjahf0X5lSyNze7Xh7aqJs11", - "Name": "SEGMENT", - "DisplayName": "Segment", - "Config": { - "excludeKeys": [], - "includeKeys": [] - } - }, - "Config": { - "writeKey": "abcdefghijklmnopqrstuvwxyz" - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.1-rc.2" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.1-rc.2" - }, - "locale": "en-GB", - "os": { - "name": "", - "version": "" - }, - "page": { - "path": "/tests/html/index4.html", - "referrer": "", - "search": "", - "title": "", - "url": "http://localhost/tests/html/index4.html" - }, - "screen": { - "density": 2 - }, - "traits": { - "age": 23, - "email": "testmp@rudderstack.com", - "firstname": "Test Kafka" - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36" - }, - "integrations": { - "All": true - }, - "messageId": "258b77c6-442d-4bdc-8729-f0e4cef41353", - "name": "home", - "originalTimestamp": "2020-04-17T14:55:31.367Z", - "properties": { - "path": "/tests/html/index4.html", - "referrer": "", - "search": "", - "title": "", - "url": "http://localhost/tests/html/index4.html" - }, - "receivedAt": "2020-04-17T20:25:31.381+05:30", - "request_ip": "[::1]:57363", - "sentAt": "2020-04-17T14:55:31.367Z", - "timestamp": "2020-04-17T20:25:31.381+05:30", - "type": "page", - "userId": "user12345" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.segment.io/v1/batch", - "headers": { - "Content-Type": "application/json", - "Authorization": "Basic YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo6" - }, - "params": {}, - "body": { - "JSON": { - "batch": [ - { - "type": "page", - "userId": "user12345", - "traits": { - "age": 23, - "email": "testmp@rudderstack.com", - "firstname": "Test Kafka" - }, - "properties": { - "path": "/tests/html/index4.html", - "referrer": "", - "search": "", - "title": "", - "url": "http://localhost/tests/html/index4.html" - }, - "timeStamp": "2020-04-17T20:25:31.381+05:30" - } - ] - }, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "user12345", - "statusCode": 200 - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "segment", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "ID": "1afmecIpsJm7D72aRTksxyODrwR", - "Name": "Segment", - "DestinationDefinition": { - "ID": "1afjjahf0X5lSyNze7Xh7aqJs11", - "Name": "SEGMENT", - "DisplayName": "Segment", - "Config": { - "excludeKeys": [], - "includeKeys": [] - } - }, - "Config": { - "writeKey": "abcdefghijklmnopqrstuvwxyz" - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "anonymousId": "ac7722c2-ccb6-4ae2-baf6-1effe861f4cd", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.1.1-rc.2" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.1-rc.2" - }, - "locale": "en-GB", - "os": { - "name": "", - "version": "" - }, - "page": { - "path": "/tests/html/index4.html", - "referrer": "", - "search": "", - "title": "", - "url": "http://localhost/tests/html/index4.html" - }, - "screen": { - "density": 2 - }, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36" - }, - "event": "test track with property", - "integrations": { - "All": true - }, - "messageId": "584fde02-901a-4964-a4a0-4078b999d5b2", - "originalTimestamp": "2020-04-17T14:55:31.372Z", - "properties": { - "test_prop_1": "test prop", - "test_prop_2": 1232 - }, - "receivedAt": "2020-04-17T20:25:31.401+05:30", - "request_ip": "[::1]:57365", - "sentAt": "2020-04-17T14:55:31.372Z", - "timestamp": "2020-04-17T20:25:31.401+05:30", - "type": "track", - "userId": "user12345" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.segment.io/v1/batch", - "headers": { - "Content-Type": "application/json", - "Authorization": "Basic YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo6" - }, - "params": {}, - "body": { - "JSON": { - "batch": [ - { - "anonymousId": "ac7722c2-ccb6-4ae2-baf6-1effe861f4cd", - "type": "track", - "userId": "user12345", - "event": "test track with property", - "properties": { - "test_prop_1": "test prop", - "test_prop_2": 1232 - }, - "timeStamp": "2020-04-17T20:25:31.401+05:30" - } - ] - }, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {}, - "userId": "user12345", - "statusCode": 200 - }, - "statusCode": 200 - } - ] - } - } - } -] + { + name: 'segment', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ID: '1afmecIpsJm7D72aRTksxyODrwR', + Name: 'Segment', + DestinationDefinition: { + ID: '1afjjahf0X5lSyNze7Xh7aqJs11', + Name: 'SEGMENT', + DisplayName: 'Segment', + Config: { + excludeKeys: [], + includeKeys: [], + }, + }, + Config: { + writeKey: 'abcdefghijklmnopqrstuvwxyz', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + anonymousId: 'ac7722c2-ccb6-4ae2-baf6-1effe861f4cd', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.1-rc.2', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.1-rc.2', + }, + locale: 'en-GB', + os: { + name: '', + version: '', + }, + page: { + path: '/tests/html/index4.html', + referrer: '', + search: '', + title: '', + url: 'http://localhost/tests/html/index4.html', + }, + screen: { + density: 2, + }, + traits: { + age: 23, + email: 'testmp@rudderstack.com', + firstname: 'Test Kafka', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36', + }, + integrations: { + All: true, + }, + messageId: '258b77c6-442d-4bdc-8729-f0e4cef41353', + name: 'home', + originalTimestamp: '2020-04-17T14:55:31.367Z', + properties: { + path: '/tests/html/index4.html', + referrer: '', + search: '', + title: '', + url: 'http://localhost/tests/html/index4.html', + }, + receivedAt: '2020-04-17T20:25:31.381+05:30', + request_ip: '[::1]:57363', + sentAt: '2020-04-17T14:55:31.367Z', + timestamp: '2020-04-17T20:25:31.381+05:30', + type: 'page', + userId: 'user12345', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + userId: 'user12345', + endpoint: 'https://api.segment.io/v1/batch', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Basic YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo6', + }, + params: {}, + body: { + JSON: { + batch: [ + { + anonymousId: 'ac7722c2-ccb6-4ae2-baf6-1effe861f4cd', + type: 'page', + userId: 'user12345', + traits: { + age: 23, + email: 'testmp@rudderstack.com', + firstname: 'Test Kafka', + }, + properties: { + path: '/tests/html/index4.html', + referrer: '', + search: '', + title: '', + url: 'http://localhost/tests/html/index4.html', + }, + timeStamp: '2020-04-17T20:25:31.381+05:30', + }, + ], + }, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + statusCode: 200, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'segment', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ID: '1afmecIpsJm7D72aRTksxyODrwR', + Name: 'Segment', + DestinationDefinition: { + ID: '1afjjahf0X5lSyNze7Xh7aqJs11', + Name: 'SEGMENT', + DisplayName: 'Segment', + Config: { + excludeKeys: [], + includeKeys: [], + }, + }, + Config: { + writeKey: 'abcdefghijklmnopqrstuvwxyz', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + anonymousId: 'ac7722c2-ccb6-4ae2-baf6-1effe861f4cd', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.1-rc.2', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.1-rc.2', + }, + locale: 'en-GB', + os: { + name: '', + version: '', + }, + page: { + path: '/tests/html/index4.html', + referrer: '', + search: '', + title: '', + url: 'http://localhost/tests/html/index4.html', + }, + screen: { + density: 2, + }, + traits: { + age: 23, + email: 'testmp@email.com', + firstname: 'Test Transformer', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36', + }, + integrations: { + All: true, + }, + messageId: '023a3a48-190a-4968-9394-a8e99b81a3c0', + originalTimestamp: '2020-04-17T14:55:31.37Z', + receivedAt: '2020-04-17T20:25:31.401+05:30', + request_ip: '[::1]:57364', + sentAt: '2020-04-17T14:55:31.37Z', + timestamp: '2020-04-17T20:25:31.401+05:30', + type: 'identify', + userId: 'user12345', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + userId: 'user12345', + method: 'POST', + endpoint: 'https://api.segment.io/v1/batch', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Basic YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo6', + }, + params: {}, + body: { + JSON: { + batch: [ + { + anonymousId: 'ac7722c2-ccb6-4ae2-baf6-1effe861f4cd', + type: 'identify', + userId: 'user12345', + traits: { + age: 23, + email: 'testmp@email.com', + firstname: 'Test Transformer', + }, + timeStamp: '2020-04-17T20:25:31.401+05:30', + }, + ], + }, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + statusCode: 200, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'segment', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ID: '1afmecIpsJm7D72aRTksxyODrwR', + Name: 'Segment', + DestinationDefinition: { + ID: '1afjjahf0X5lSyNze7Xh7aqJs11', + Name: 'SEGMENT', + DisplayName: 'Segment', + Config: { + excludeKeys: [], + includeKeys: [], + }, + }, + Config: { + writeKey: 'abcdefghijklmnopqrstuvwxyz', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + anonymousId: 'ac7722c2-ccb6-4ae2-baf6-1effe861f4cd', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.1-rc.2', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.1-rc.2', + }, + locale: 'en-GB', + os: { + name: '', + version: '', + }, + page: { + path: '/tests/html/index4.html', + referrer: '', + search: '', + title: '', + url: 'http://localhost/tests/html/index4.html', + }, + screen: { + density: 2, + }, + traits: { + age: 23, + email: 'testmp@email.com', + firstname: 'Test Transformer', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36', + }, + event: 'test track with property', + integrations: { + All: true, + }, + messageId: '584fde02-901a-4964-a4a0-4078b999d5b2', + originalTimestamp: '2020-04-17T14:55:31.372Z', + properties: { + test_prop_1: 'test prop', + test_prop_2: 1232, + }, + receivedAt: '2020-04-17T20:25:31.401+05:30', + request_ip: '[::1]:57365', + sentAt: '2020-04-17T14:55:31.372Z', + timestamp: '2020-04-17T20:25:31.401+05:30', + type: 'track', + userId: 'user12345', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + userId: 'user12345', + method: 'POST', + endpoint: 'https://api.segment.io/v1/batch', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Basic YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo6', + }, + params: {}, + body: { + JSON: { + batch: [ + { + anonymousId: 'ac7722c2-ccb6-4ae2-baf6-1effe861f4cd', + type: 'track', + userId: 'user12345', + event: 'test track with property', + traits: { + age: 23, + email: 'testmp@email.com', + firstname: 'Test Transformer', + }, + properties: { + test_prop_1: 'test prop', + test_prop_2: 1232, + }, + timeStamp: '2020-04-17T20:25:31.401+05:30', + }, + ], + }, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + statusCode: 200, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'segment', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ID: '1afmecIpsJm7D72aRTksxyODrwR', + Name: 'Segment', + DestinationDefinition: { + ID: '1afjjahf0X5lSyNze7Xh7aqJs11', + Name: 'SEGMENT', + DisplayName: 'Segment', + Config: { + excludeKeys: [], + includeKeys: [], + }, + }, + Config: { + writeKey: 'abcdefghijklmnopqrstuvwxyz', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.1-rc.2', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.1-rc.2', + }, + locale: 'en-GB', + os: { + name: '', + version: '', + }, + page: { + path: '/tests/html/index4.html', + referrer: '', + search: '', + title: '', + url: 'http://localhost/tests/html/index4.html', + }, + screen: { + density: 2, + }, + traits: { + age: 23, + email: 'testmp@rudderstack.com', + firstname: 'Test Kafka', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36', + }, + integrations: { + All: true, + }, + messageId: '258b77c6-442d-4bdc-8729-f0e4cef41353', + name: 'home', + originalTimestamp: '2020-04-17T14:55:31.367Z', + properties: { + path: '/tests/html/index4.html', + referrer: '', + search: '', + title: '', + url: 'http://localhost/tests/html/index4.html', + }, + receivedAt: '2020-04-17T20:25:31.381+05:30', + request_ip: '[::1]:57363', + sentAt: '2020-04-17T14:55:31.367Z', + timestamp: '2020-04-17T20:25:31.381+05:30', + type: 'page', + userId: 'user12345', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.segment.io/v1/batch', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Basic YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo6', + }, + params: {}, + body: { + JSON: { + batch: [ + { + type: 'page', + userId: 'user12345', + traits: { + age: 23, + email: 'testmp@rudderstack.com', + firstname: 'Test Kafka', + }, + properties: { + path: '/tests/html/index4.html', + referrer: '', + search: '', + title: '', + url: 'http://localhost/tests/html/index4.html', + }, + timeStamp: '2020-04-17T20:25:31.381+05:30', + }, + ], + }, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: 'user12345', + statusCode: 200, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'segment', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ID: '1afmecIpsJm7D72aRTksxyODrwR', + Name: 'Segment', + DestinationDefinition: { + ID: '1afjjahf0X5lSyNze7Xh7aqJs11', + Name: 'SEGMENT', + DisplayName: 'Segment', + Config: { + excludeKeys: [], + includeKeys: [], + }, + }, + Config: { + writeKey: 'abcdefghijklmnopqrstuvwxyz', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + anonymousId: 'ac7722c2-ccb6-4ae2-baf6-1effe861f4cd', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.1-rc.2', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.1-rc.2', + }, + locale: 'en-GB', + os: { + name: '', + version: '', + }, + page: { + path: '/tests/html/index4.html', + referrer: '', + search: '', + title: '', + url: 'http://localhost/tests/html/index4.html', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36', + }, + event: 'test track with property', + integrations: { + All: true, + }, + messageId: '584fde02-901a-4964-a4a0-4078b999d5b2', + originalTimestamp: '2020-04-17T14:55:31.372Z', + properties: { + test_prop_1: 'test prop', + test_prop_2: 1232, + }, + receivedAt: '2020-04-17T20:25:31.401+05:30', + request_ip: '[::1]:57365', + sentAt: '2020-04-17T14:55:31.372Z', + timestamp: '2020-04-17T20:25:31.401+05:30', + type: 'track', + userId: 'user12345', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.segment.io/v1/batch', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Basic YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo6', + }, + params: {}, + body: { + JSON: { + batch: [ + { + anonymousId: 'ac7722c2-ccb6-4ae2-baf6-1effe861f4cd', + type: 'track', + userId: 'user12345', + event: 'test track with property', + properties: { + test_prop_1: 'test prop', + test_prop_2: 1232, + }, + timeStamp: '2020-04-17T20:25:31.401+05:30', + }, + ], + }, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: 'user12345', + statusCode: 200, + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/sfmc/processor/data.ts b/test/integrations/destinations/sfmc/processor/data.ts index 406ed82ace5..b2839908ad6 100644 --- a/test/integrations/destinations/sfmc/processor/data.ts +++ b/test/integrations/destinations/sfmc/processor/data.ts @@ -1732,4 +1732,166 @@ export const data = [ }, }, }, + { + name: 'sfmc', + description: 'Test 12', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'message event', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + campaign: { + name: 'Demo Campaign', + source: 'facebook', + medium: 'online', + term: 'Demo terms', + content: 'Demo content', + }, + traits: { + email: 'tonmoy@rudderstack.com', + name: 'Tonmoy Labs', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', + locale: 'en-GB', + ip: '0.0.0.0', + screen: { + density: 2, + height: 860, + width: 1280, + }, + }, + type: 'track', + userId: '12345', + properties: { + id: 'id101', + contactId: 'cid101', + email: 'testemail@gmail.com', + accountNumber: '99110099', + patronName: 'SP', + }, + sentAt: '2019-10-14T09:03:22.563Z', + integrations: { + All: true, + }, + }, + destination: { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'SFMC', + DestinationDefinition: { + ID: '1pYpYSeQd8OeN6xPdw6VGDzqUd1', + Name: 'SFMC', + DisplayName: 'Salesforce Marketing Cloud', + Config: { + destConfig: [], + excludeKeys: [], + includeKeys: [], + saveDestinationResponse: false, + supportedSourceTypes: [], + transformAt: 'processor', + }, + ResponseRules: {}, + }, + Config: { + clientId: 'vcn7AQ2W9GGIAZSsN6Mfq', + clientSecret: 'vcn7AQ2W9GGIAZSsN6Mfq', + createOrUpdateContacts: false, + eventDelivery: true, + eventDeliveryTS: 1615371070621, + eventToExternalKey: [ + { + from: 'Event Name', + to: 'C500FD37-155C-49BD-A21B-AFCEF3D1A9CB', + }, + { + from: 'Watch', + to: 'C500FD37-155C-49BD-A21B-AFCEF3D1A9CB', + }, + ], + eventToPrimaryKey: [ + { + from: 'userId', + to: 'User Key', + }, + { + from: 'watch', + to: 'Guest Key, Contact Key', + }, + ], + eventToUUID: [ + { + event: 'Event Name', + uuid: true, + }, + ], + eventToDefinitionMapping: [ + { + from: 'message event', + to: 'test-event-definition', + }, + ], + externalKey: 'f3ffa19b-e0b3-4967-829f-549b781080e6', + subDomain: 'vcn7AQ2W9GGIAZSsN6Mfq', + }, + Enabled: true, + Transformations: [], + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + JSON: { + ContactKey: 'cid101', + Data: { + accountNumber: '99110099', + email: 'testemail@gmail.com', + id: 'id101', + patronName: 'SP', + }, + EventDefinitionKey: 'test-event-definition', + }, + }, + type: 'REST', + files: {}, + method: 'POST', + params: {}, + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer yourAuthToken', + }, + version: '1', + endpoint: + 'https://vcn7AQ2W9GGIAZSsN6Mfq.rest.marketingcloudapis.com/interaction/v1/events', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, ]; diff --git a/test/integrations/destinations/snapchat_custom_audience/dataDelivery/business.ts b/test/integrations/destinations/snapchat_custom_audience/dataDelivery/business.ts new file mode 100644 index 00000000000..4ee646bedbf --- /dev/null +++ b/test/integrations/destinations/snapchat_custom_audience/dataDelivery/business.ts @@ -0,0 +1,118 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { + generateMetadata, + generateProxyV0Payload, + generateProxyV1Payload, +} from '../../../testUtils'; + +const commonHeaders = { + Authorization: 'Bearer abcd123', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', +}; + +const commonRequestParameters = { + headers: commonHeaders, + JSON: { + users: [ + { + schema: ['EMAIL_SHA256'], + data: [['938758751f5af66652a118e26503af824404bc13acd1cb7642ddff99916f0e1c']], + }, + ], + }, +}; + +export const businessV0TestScenarios = [ + { + id: 'snapchat_custom_audience_v0_oauth_scenario_1', + name: 'snapchat_custom_audience', + description: '[Proxy v0 API] :: successfull call', + successCriteria: 'Proper response from destination is received', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://adsapi.snapchat.com/v1/segments/123/users', + params: { + destination: 'snapchat_custom_audience', + }, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + destinationResponse: { + response: { + request_status: 'SUCCESS', + request_id: '12345', + users: [ + { + sub_request_status: 'SUCCESS', + user: { + number_uploaded_users: 1, + }, + }, + ], + }, + status: 200, + }, + }, + }, + }, + }, + }, +]; + +export const businessV1TestScenarios: ProxyV1TestData[] = [ + { + id: 'snapchat_custom_audience_v1_oauth_scenario_1', + name: 'snapchat_custom_audience', + description: '[Proxy v1 API] :: successfull oauth', + successCriteria: 'Proper response from destination is received', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + ...commonRequestParameters, + endpoint: 'https://adsapi.snapchat.com/v1/segments/123/users', + params: { + destination: 'snapchat_custom_audience', + }, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + response: [ + { + error: `{\"request_status\":\"SUCCESS\",\"request_id\":\"12345\",\"users\":[{\"sub_request_status\":\"SUCCESS\",\"user\":{\"number_uploaded_users\":1}}]}`, + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/snapchat_custom_audience/dataDelivery/data.ts b/test/integrations/destinations/snapchat_custom_audience/dataDelivery/data.ts index 1903938660d..4991ed1d38a 100644 --- a/test/integrations/destinations/snapchat_custom_audience/dataDelivery/data.ts +++ b/test/integrations/destinations/snapchat_custom_audience/dataDelivery/data.ts @@ -1,222 +1,11 @@ +import { businessV0TestScenarios, businessV1TestScenarios } from './business'; +import { v0OauthScenarios, v1OauthScenarios } from './oauth'; +import { otherScenariosV1 } from './other'; + export const data = [ - { - "name": "snapchat_custom_audience", - "description": "Test 0", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://adsapi.snapchat.com/v1/segments/123/users", - "headers": { - "Authorization": "Bearer abcd123", - "Content-Type": "application/json" - }, - "body": { - "JSON": { - "users": [ - { - "schema": [ - "EMAIL_SHA256" - ], - "data": [ - [ - "938758751f5af66652a118e26503af824404bc13acd1cb7642ddff99916f0e1c" - ] - ] - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "params": { - "destination": "snapchat_custom_audience" - } - }, - "method": "POST" - } - }, - "output": { - "response": { - "status": 200, - "body": { - "output": { - "status": 200, - "message": "Request Processed Successfully", - "destinationResponse": { - "response": { - "request_status": "SUCCESS", - "request_id": "12345", - "users": [ - { - "sub_request_status": "SUCCESS", - "user": { - "number_uploaded_users": 1 - } - } - ] - }, - "status": 200 - } - } - } - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 1", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://adsapi.snapchat.com/v1/segments/456/users", - "headers": { - "Authorization": "Bearer abcd123", - "Content-Type": "application/json" - }, - "body": { - "JSON": { - "users": [ - { - "schema": [ - "EMAIL_SHA256" - ], - "data": [ - [ - "938758751f5af66652a118e26503af824404bc13acd1cb7642ddff99916f0e1c" - ] - ] - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "params": { - "destination": "snapchat_custom_audience" - } - }, - "method": "POST" - } - }, - "output": { - "response": { - "status": 500, - "body": { - "output": { - "status": 500, - "destinationResponse": { - "response": "unauthorized", - "status": 401 - }, - "message": "Failed with unauthorized during snapchat_custom_audience response transformation", - "statTags": { - "destType": "SNAPCHAT_CUSTOM_AUDIENCE", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "retryable", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - }, - "authErrorCategory": "REFRESH_TOKEN" - } - } - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 2", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "DELETE", - "endpoint": "https://adsapi.snapchat.com/v1/segments/789/users", - "headers": { - "Authorization": "Bearer abcd123", - "Content-Type": "application/json" - }, - "body": { - "JSON": { - "users": [ - { - "id": "123456", - "schema": [ - "EMAIL_SHA256" - ], - "data": [ - [ - "938758751f5af66652a118e26503af824404bc13acd1cb7642ddff99916f0e1c" - ] - ] - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "params": { - "destination": "snapchat_custom_audience" - } - }, - "method": "POST" - } - }, - "output": { - "response": { - "status": 400, - "body": { - "output": { - "authErrorCategory": "AUTH_STATUS_INACTIVE", - "status": 400, - "destinationResponse": { - "response": { - "request_status": "ERROR", - "request_id": "98e2a602-3cf4-4596-a8f9-7f034161f89a", - "debug_message": "Caller does not have permission", - "display_message": "We're sorry, but the requested resource is not available at this time", - "error_code": "E3002" - }, - "status": 403 - }, - "message": "undefined during snapchat_custom_audience response transformation", - "statTags": { - "destType": "SNAPCHAT_CUSTOM_AUDIENCE", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } - } -] + ...v0OauthScenarios, + ...v1OauthScenarios, + ...businessV0TestScenarios, + ...businessV1TestScenarios, + ...otherScenariosV1, +]; diff --git a/test/integrations/destinations/snapchat_custom_audience/dataDelivery/oauth.ts b/test/integrations/destinations/snapchat_custom_audience/dataDelivery/oauth.ts new file mode 100644 index 00000000000..e4bf5d45882 --- /dev/null +++ b/test/integrations/destinations/snapchat_custom_audience/dataDelivery/oauth.ts @@ -0,0 +1,244 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { + generateMetadata, + generateProxyV0Payload, + generateProxyV1Payload, +} from '../../../testUtils'; + +const commonHeaders = { + Authorization: 'Bearer abcd123', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', +}; + +const commonRequestParameters = { + headers: commonHeaders, + JSON: { + users: [ + { + schema: ['EMAIL_SHA256'], + data: [['938758751f5af66652a118e26503af824404bc13acd1cb7642ddff99916f0e1c']], + }, + ], + }, +}; + +const commonDeleteRequestParameters = { + headers: commonHeaders, + JSON: { + users: [ + { + id: '123456', + schema: ['EMAIL_SHA256'], + data: [['938758751f5af66652a118e26503af824404bc13acd1cb7642ddff99916f0e1c']], + }, + ], + }, +}; + +const retryStatTags = { + destType: 'SNAPCHAT_CUSTOM_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', +}; + +const abortStatTags = { + destType: 'SNAPCHAT_CUSTOM_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', +}; + +export const v0OauthScenarios = [ + { + id: 'snapchat_custom_audience_v0_oauth_scenario_2', + name: 'snapchat_custom_audience', + description: + '[Proxy v0 API] :: Oauth where valid credentials are missing as mock response from destination', + successCriteria: + 'Since the error from the destination is 401 - the proxy should return 500 with authErrorCategory as REFRESH_TOKEN', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://adsapi.snapchat.com/v1/segments/456/users', + params: { + destination: 'snapchat_custom_audience', + }, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + destinationResponse: { + response: 'unauthorized', + status: 401, + }, + message: + 'Failed with unauthorized during snapchat_custom_audience response transformation', + statTags: retryStatTags, + authErrorCategory: 'REFRESH_TOKEN', + }, + }, + }, + }, + }, + { + id: 'snapchat_custom_audience_v0_oauth_scenario_3', + name: 'snapchat_custom_audience', + description: + '[Proxy v0 API] :: Oauth where ACCESS_TOKEN_SCOPE_INSUFFICIENT error as mock response from destination', + successCriteria: + 'Since the error from the destination is 403 - the proxy should return 500 with authErrorCategory as AUTH_STATUS_INACTIVE', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: generateProxyV0Payload({ + ...commonRequestParameters, + endpoint: 'https://adsapi.snapchat.com/v1/segments/999/users', + params: { + destination: 'snapchat_custom_audience', + }, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 400, + body: { + output: { + authErrorCategory: 'AUTH_STATUS_INACTIVE', + status: 400, + destinationResponse: { + response: { + request_status: 'ERROR', + request_id: '98e2a602-3cf4-4596-a8f9-7f034161f89a', + debug_message: 'Caller does not have permission', + display_message: + "We're sorry, but the requested resource is not available at this time", + error_code: 'E3002', + }, + status: 403, + }, + message: 'undefined during snapchat_custom_audience response transformation', + statTags: abortStatTags, + }, + }, + }, + }, + }, +]; + +export const v1OauthScenarios: ProxyV1TestData[] = [ + { + id: 'snapchat_custom_audience_v1_oauth_scenario_1', + name: 'snapchat_custom_audience', + description: + '[Proxy v1 API] :: Oauth where valid credentials are missing as mock response from destination', + successCriteria: + 'Since the error from the destination is 401 - the proxy should return 500 with authErrorCategory as REFRESH_TOKEN', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + ...commonRequestParameters, + endpoint: 'https://adsapi.snapchat.com/v1/segments/456/users', + params: { + destination: 'snapchat_custom_audience', + }, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + response: [ + { + error: '"unauthorized"', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: retryStatTags, + authErrorCategory: 'REFRESH_TOKEN', + message: + 'Failed with unauthorized during snapchat_custom_audience response transformation', + status: 500, + }, + }, + }, + }, + }, + { + id: 'snapchat_custom_audience_v1_oauth_scenario_2', + name: 'snapchat_custom_audience', + description: + '[Proxy v1 API] :: Oauth where ACCESS_TOKEN_SCOPE_INSUFFICIENT error as mock response from destination', + successCriteria: + 'Since the error from the destination is 403 - the proxy should return 500 with authErrorCategory as AUTH_STATUS_INACTIVE', + scenario: 'Oauth', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + ...commonRequestParameters, + endpoint: 'https://adsapi.snapchat.com/v1/segments/999/users', + params: { + destination: 'snapchat_custom_audience', + }, + }), + method: 'POST', + }, + }, + output: { + response: { + status: 400, + body: { + output: { + response: [ + { + error: `{"request_status":"ERROR","request_id":"98e2a602-3cf4-4596-a8f9-7f034161f89a","debug_message":"Caller does not have permission","display_message":"We're sorry, but the requested resource is not available at this time","error_code":"E3002"}`, + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + statTags: abortStatTags, + message: 'undefined during snapchat_custom_audience response transformation', + status: 400, + authErrorCategory: 'AUTH_STATUS_INACTIVE', + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/snapchat_custom_audience/dataDelivery/other.ts b/test/integrations/destinations/snapchat_custom_audience/dataDelivery/other.ts new file mode 100644 index 00000000000..90508c2481c --- /dev/null +++ b/test/integrations/destinations/snapchat_custom_audience/dataDelivery/other.ts @@ -0,0 +1,204 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; + +const expectedStatTags = { + destType: 'SNAPCHAT_CUSTOM_AUDIENCE', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', +}; + +export const otherScenariosV1: ProxyV1TestData[] = [ + { + id: 'snapchat_custom_audience_v1_other_scenario_1', + name: 'snapchat_custom_audience', + description: + '[Proxy v1 API] :: Scenario for testing Service Unavailable error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_service_not_available', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: + '{"error":{"message":"Service Unavailable","description":"The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later."}}', + statusCode: 503, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + status: 503, + message: 'Service Unavailable during snapchat_custom_audience response transformation', + }, + }, + }, + }, + }, + { + id: 'snapchat_custom_audience_v1_other_scenario_2', + name: 'snapchat_custom_audience', + description: '[Proxy v1 API] :: Scenario for testing Internal Server error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_internal_server_error', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Internal Server Error"', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + status: 500, + message: 'undefined during snapchat_custom_audience response transformation', + }, + }, + }, + }, + }, + { + id: 'snapchat_custom_audience_v1_other_scenario_3', + name: 'snapchat_custom_audience', + description: '[Proxy v1 API] :: Scenario for testing Gateway Time Out error from destination', + successCriteria: 'Should return 504 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_gateway_time_out', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Gateway Timeout"', + statusCode: 504, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + status: 504, + message: 'undefined during snapchat_custom_audience response transformation', + }, + }, + }, + }, + }, + { + id: 'snapchat_custom_audience_v1_other_scenario_4', + name: 'snapchat_custom_audience', + description: '[Proxy v1 API] :: Scenario for testing null response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_response', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + status: 500, + message: 'undefined during snapchat_custom_audience response transformation', + }, + }, + }, + }, + }, + { + id: 'snapchat_custom_audience_v1_other_scenario_5', + name: 'snapchat_custom_audience', + description: + '[Proxy v1 API] :: Scenario for testing null and no status response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload({ + endpoint: 'https://random_test_url/test_for_null_and_no_status', + }), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: expectedStatTags, + status: 500, + message: 'undefined during snapchat_custom_audience response transformation', + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/snapchat_custom_audience/network.ts b/test/integrations/destinations/snapchat_custom_audience/network.ts index 9be134c2026..39bd46122dd 100644 --- a/test/integrations/destinations/snapchat_custom_audience/network.ts +++ b/test/integrations/destinations/snapchat_custom_audience/network.ts @@ -81,4 +81,35 @@ export const networkCallsData = [ statusText: 'Forbidden', }, }, + { + httpReq: { + url: 'https://adsapi.snapchat.com/v1/segments/999/users', + data: { + users: [ + { + schema: ['EMAIL_SHA256'], + data: [['938758751f5af66652a118e26503af824404bc13acd1cb7642ddff99916f0e1c']], + }, + ], + }, + params: { destination: 'snapchat_custom_audience' }, + headers: { + Authorization: 'Bearer abcd123', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: { + request_status: 'ERROR', + request_id: '98e2a602-3cf4-4596-a8f9-7f034161f89a', + debug_message: 'Caller does not have permission', + display_message: "We're sorry, but the requested resource is not available at this time", + error_code: 'E3002', + }, + status: 403, + statusText: 'Forbidden', + }, + }, ]; diff --git a/test/integrations/destinations/snapchat_custom_audience/processor/data.ts b/test/integrations/destinations/snapchat_custom_audience/processor/data.ts index a73a9596994..546f056fa43 100644 --- a/test/integrations/destinations/snapchat_custom_audience/processor/data.ts +++ b/test/integrations/destinations/snapchat_custom_audience/processor/data.ts @@ -1,1404 +1,1351 @@ export const data = [ - { - "name": "snapchat_custom_audience", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": false, - "schema": "email" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [ - { - "email": "test@abc.com", - "phone": "@09876543210", - "firstName": "test", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://adsapi.snapchat.com/v1/segments/123/users", - "headers": { - "Authorization": "Bearer dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "users": [ - { - "schema": [ - "EMAIL_SHA256" - ], - "data": [ - [ - "d3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419" - ] - ] - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": true, - "schema": "email" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "remove": [ - { - "email": "d3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419", - "phone": "@09876543210", - "firstName": "test", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "DELETE", - "endpoint": "https://adsapi.snapchat.com/v1/segments/123/users", - "headers": { - "Authorization": "Bearer dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "users": [ - { - "schema": [ - "EMAIL_SHA256" - ], - "data": [ - [ - "d3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419" - ] - ], - "id": "123" - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": false, - "schema": "email" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [ - { - "email": "test@abc.com", - "phone": "@09876543210", - "firstName": "test", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - } - ], - "remove": [ - { - "email": "test@abc.com", - "phone": "@09876543210", - "firstName": "test", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://adsapi.snapchat.com/v1/segments/123/users", - "headers": { - "Authorization": "Bearer dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "users": [ - { - "schema": [ - "EMAIL_SHA256" - ], - "data": [ - [ - "d3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419" - ] - ] - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 200 - }, - { - "output": { - "version": "1", - "type": "REST", - "method": "DELETE", - "endpoint": "https://adsapi.snapchat.com/v1/segments/123/users", - "headers": { - "Authorization": "Bearer dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "users": [ - { - "schema": [ - "EMAIL_SHA256" - ], - "data": [ - [ - "d3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419" - ] - ], - "id": "123" - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": false, - "schema": "email" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [ - { - "email": "test@abc.com", - "phone": "@09876543210", - "firstName": "test", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - }, - { - "email": "test@rudderstack.com", - "phone": "@09876543210", - "firstName": "rudderlabs", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://adsapi.snapchat.com/v1/segments/123/users", - "headers": { - "Authorization": "Bearer dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "users": [ - { - "schema": [ - "EMAIL_SHA256" - ], - "data": [ - [ - "d3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419" - ], - [ - "1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd" - ] - ] - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": false, - "schema": "email" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "remove": [ - { - "email": "test@abc.com", - "phone": "@09876543210", - "firstName": "test", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - }, - { - "email": "test@rudderstack.com", - "phone": "@09876543210", - "firstName": "rudderlabs", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "DELETE", - "endpoint": "https://adsapi.snapchat.com/v1/segments/123/users", - "headers": { - "Authorization": "Bearer dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "users": [ - { - "schema": [ - "EMAIL_SHA256" - ], - "data": [ - [ - "d3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419" - ], - [ - "1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd" - ] - ], - "id": "123" - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 5", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": false, - "schema": "email" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audience", - "properties": { - "listData": { - "add": [ - { - "email": "test@rudderstack.com", - "phone": "@09876543210", - "firstName": "rudderlabs", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 400, - "error": "Event type audience is not supported", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "SNAPCHAT_CUSTOM_AUDIENCE", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 6", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": false, - "schema": "email" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "properties": { - "listData": { - "add": [ - { - "email": "test@rudderstack.com", - "phone": "@09876543210", - "firstName": "rudderlabs", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 400, - "error": "Event type is required", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "SNAPCHAT_CUSTOM_AUDIENCE", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 7", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": false, - "schema": "email" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 400, - "error": "Message properties is not present. Aborting message", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "SNAPCHAT_CUSTOM_AUDIENCE", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 8", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": false, - "schema": "email" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 400, - "error": "listData is not present inside properties. Aborting message", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "SNAPCHAT_CUSTOM_AUDIENCE", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 9", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": false, - "schema": "email" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "abc": "123" - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 400, - "error": "Neither 'add' nor 'remove' property is present inside 'listData'. Aborting message", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "SNAPCHAT_CUSTOM_AUDIENCE", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 10", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": false, - "schema": "email" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "remove": [ - { - "email": "", - "phone": "@09876543210", - "firstName": "test", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - }, - { - "phone": "@09876543210", - "firstName": "test", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 400, - "error": "Required schema parameter email is not found from payload", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "SNAPCHAT_CUSTOM_AUDIENCE", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 11", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": false, - "schema": "email" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "remove": [ - { - "email": "abcd@abc.com", - "phone": "@09876543210", - "firstName": "test", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - }, - { - "phone": "@09876543210", - "firstName": "test", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "DELETE", - "endpoint": "https://adsapi.snapchat.com/v1/segments/123/users", - "headers": { - "Authorization": "Bearer dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "users": [ - { - "schema": [ - "EMAIL_SHA256" - ], - "data": [ - [ - "8c37cbc5d9abb3082303c6548571cfc7655a4546ddc1e943f041fc9126e7274a" - ] - ], - "id": "123" - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 12", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": false, - "schema": "phone" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [ - { - "email": "test@abc.com", - "phone": "09876543210", - "firstName": "test", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://adsapi.snapchat.com/v1/segments/123/users", - "headers": { - "Authorization": "Bearer dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "users": [ - { - "schema": [ - "PHONE_SHA256" - ], - "data": [ - [ - "7619ee8cea49187f309616e30ecf54be072259b43760f1f550a644945d5572f2" - ] - ] - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "snapchat_custom_audience", - "description": "Test 13", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "destination": { - "Config": { - "segmentId": "123", - "disableHashing": false, - "schema": "mobileAdId" - } - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [ - { - "email": "test@abc.com", - "phone": "09876543210", - "mobileId": "1334", - "firstName": "test", - "lastName": "rudderlabs", - "country": "US", - "postalCode": "1245" - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://adsapi.snapchat.com/v1/segments/123/users", - "headers": { - "Authorization": "Bearer dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "users": [ - { - "schema": [ - "MOBILE_AD_ID_SHA256" - ], - "data": [ - [ - "eb43272640b269219a01caf99c5a4122d6edc0916d45ac13c0ce80ca3ad2def0" - ] - ] - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "secret": { - "access_token": "dummyAccessToken", - "refresh_token": "dummyRefreshToken", - "developer_token": "dummyDeveloperToken" - } - }, - "statusCode": 200 - } - ] - } - } - } -] + { + name: 'snapchat_custom_audience', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: false, + schema: 'email', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + email: 'test@abc.com', + phone: '@09876543210', + firstName: 'test', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + ], + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://adsapi.snapchat.com/v1/segments/123/users', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + users: [ + { + schema: ['EMAIL_SHA256'], + data: [['d3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419']], + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'snapchat_custom_audience', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: true, + schema: 'email', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + remove: [ + { + email: 'd3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419', + phone: '@09876543210', + firstName: 'test', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + ], + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://adsapi.snapchat.com/v1/segments/123/users', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + users: [ + { + schema: ['EMAIL_SHA256'], + data: [['d3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419']], + id: '123', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'snapchat_custom_audience', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: false, + schema: 'email', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + email: 'test@abc.com', + phone: '@09876543210', + firstName: 'test', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + ], + remove: [ + { + email: 'test@abc.com', + phone: '@09876543210', + firstName: 'test', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + ], + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://adsapi.snapchat.com/v1/segments/123/users', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + users: [ + { + schema: ['EMAIL_SHA256'], + data: [['d3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419']], + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://adsapi.snapchat.com/v1/segments/123/users', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + users: [ + { + schema: ['EMAIL_SHA256'], + data: [['d3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419']], + id: '123', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'snapchat_custom_audience', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: false, + schema: 'email', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + email: 'test@abc.com', + phone: '@09876543210', + firstName: 'test', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + { + email: 'test@rudderstack.com', + phone: '@09876543210', + firstName: 'rudderlabs', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + ], + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://adsapi.snapchat.com/v1/segments/123/users', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + users: [ + { + schema: ['EMAIL_SHA256'], + data: [ + ['d3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419'], + ['1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd'], + ], + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'snapchat_custom_audience', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: false, + schema: 'email', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + remove: [ + { + email: 'test@abc.com', + phone: '@09876543210', + firstName: 'test', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + { + email: 'test@rudderstack.com', + phone: '@09876543210', + firstName: 'rudderlabs', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + ], + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://adsapi.snapchat.com/v1/segments/123/users', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + users: [ + { + schema: ['EMAIL_SHA256'], + data: [ + ['d3142c8f9c9129484daf28df80cc5c955791efed5e69afabb603bc8cb9ffd419'], + ['1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd'], + ], + id: '123', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'snapchat_custom_audience', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: false, + schema: 'email', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audience', + properties: { + listData: { + add: [ + { + email: 'test@rudderstack.com', + phone: '@09876543210', + firstName: 'rudderlabs', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + ], + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 400, + error: 'Event type audience is not supported', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'SNAPCHAT_CUSTOM_AUDIENCE', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'snapchat_custom_audience', + description: 'Test 6', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: false, + schema: 'email', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + properties: { + listData: { + add: [ + { + email: 'test@rudderstack.com', + phone: '@09876543210', + firstName: 'rudderlabs', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + ], + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 400, + error: 'Event type is required', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'SNAPCHAT_CUSTOM_AUDIENCE', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'snapchat_custom_audience', + description: 'Test 7', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: false, + schema: 'email', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 400, + error: 'Message properties is not present. Aborting message', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'SNAPCHAT_CUSTOM_AUDIENCE', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'snapchat_custom_audience', + description: 'Test 8', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: false, + schema: 'email', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 400, + error: 'listData is not present inside properties. Aborting message', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'SNAPCHAT_CUSTOM_AUDIENCE', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'snapchat_custom_audience', + description: 'Test 9', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: false, + schema: 'email', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + abc: '123', + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 400, + error: + "Neither 'add' nor 'remove' property is present inside 'listData'. Aborting message", + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'SNAPCHAT_CUSTOM_AUDIENCE', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'snapchat_custom_audience', + description: 'Test 10', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: false, + schema: 'email', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + remove: [ + { + email: '', + phone: '@09876543210', + firstName: 'test', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + { + phone: '@09876543210', + firstName: 'test', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + ], + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 400, + error: 'Required schema parameter email is not found from payload', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'SNAPCHAT_CUSTOM_AUDIENCE', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'snapchat_custom_audience', + description: 'Test 11', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: false, + schema: 'email', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + remove: [ + { + email: 'abcd@abc.com', + phone: '@09876543210', + firstName: 'test', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + { + phone: '@09876543210', + firstName: 'test', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + ], + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://adsapi.snapchat.com/v1/segments/123/users', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + users: [ + { + schema: ['EMAIL_SHA256'], + data: [['8c37cbc5d9abb3082303c6548571cfc7655a4546ddc1e943f041fc9126e7274a']], + id: '123', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'snapchat_custom_audience', + description: 'Test 12', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: false, + schema: 'phone', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + email: 'test@abc.com', + phone: '09876543210', + firstName: 'test', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + ], + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://adsapi.snapchat.com/v1/segments/123/users', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + users: [ + { + schema: ['PHONE_SHA256'], + data: [['7619ee8cea49187f309616e30ecf54be072259b43760f1f550a644945d5572f2']], + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'snapchat_custom_audience', + description: 'Test 13', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + destination: { + Config: { + segmentId: '123', + disableHashing: false, + schema: 'mobileAdId', + }, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + email: 'test@abc.com', + phone: '09876543210', + mobileId: '1334', + firstName: 'test', + lastName: 'rudderlabs', + country: 'US', + postalCode: '1245', + }, + ], + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://adsapi.snapchat.com/v1/segments/123/users', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + users: [ + { + schema: ['MOBILE_AD_ID_SHA256'], + data: [['eb43272640b269219a01caf99c5a4122d6edc0916d45ac13c0ce80ca3ad2def0']], + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + secret: { + access_token: 'dummyAccessToken', + refresh_token: 'dummyRefreshToken', + developer_token: 'dummyDeveloperToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/splitio/processor/data.ts b/test/integrations/destinations/splitio/processor/data.ts index 20ffa00fc2e..3fda93cc30e 100644 --- a/test/integrations/destinations/splitio/processor/data.ts +++ b/test/integrations/destinations/splitio/processor/data.ts @@ -1,915 +1,905 @@ export const data = [ - { - "name": "splitio", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "traits": { - "martin": 21.565, - "trafficTypeName": "user", - "vertical": "restaurant", - "eventTypeId": "page_load end to end", - "timestamp": 1513357833000, - "GMV": false - }, - "userId": "user123", - "messageId": "c73198a8-41d8-4426-9fd9-de167194d5f3", - "rudderId": "bda76e3e-87eb-4153-9d1e-e9c2ed48b7a5", - "context": { - "ip": "14.5.67.21", - "traits": { - "abc": "new-val", - "key": "key_user_0", - "value": "0.93" - }, - "library": { - "name": "http" - } - }, - "type": "group", - "groupId": "group1", - "timestamp": "2020-01-21T00:21:34.208Z", - "writeKey": "1pe7u01A7rYOrvacE6WSgI6ESXh", - "receivedAt": "2021-04-19T14:53:18.215+05:30", - "requestIP": "[::1]" - }, - "destination": { - "Config": { - "apiKey": "abcde", - "environment": "staging", - "trafficType": "user" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://events.split.io/api/events", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer abcde" - }, - "params": {}, - "body": { - "JSON": { - "eventTypeId": "group", - "key": "user123", - "timestamp": 1579566094208, - "environmentName": "staging", - "trafficTypeName": "user", - "properties": { - "martin": 21.565, - "vertical": "restaurant", - "GMV": false - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "splitio", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "traits": { - "martin": 21.565, - "trafficTypeName": "user", - "eventTypeId": "page_load end to end", - "timestamp": 1513357833000, - "address": { - "city": "San Francisco", - "state": "CA", - "country": "USA" - }, - "key1": { - "a": "a" - }, - "key2": [ - 1, - 2, - 3 - ], - "key3": { - "key4": {} - }, - "key5": null - }, - "userId": "user123", - "messageId": "c73198a8-41d8-4426-9fd9-de167194d5f3", - "rudderId": "bda76e3e-87eb-4153-9d1e-e9c2ed48b7a5", - "context": { - "ip": "14.5.67.21", - "traits": { - "abc": "new-val", - "key": "key_user_0" - }, - "library": { - "name": "http" - } - }, - "type": "identify", - "timestamp": "2020-01-21T00:21:34.208Z", - "writeKey": "1pe7u01A7rYOrvacE6WSgI6ESXh", - "receivedAt": "2021-04-19T14:53:18.215+05:30", - "requestIP": "[::1]" - }, - "destination": { - "Config": { - "apiKey": "abcde", - "environment": "staging", - "trafficType": "user" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://events.split.io/api/events", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer abcde" - }, - "params": {}, - "body": { - "JSON": { - "eventTypeId": "identify", - "key": "user123", - "timestamp": 1579566094208, - "environmentName": "staging", - "trafficTypeName": "user", - "properties": { - "martin": 21.565, - "address.city": "San Francisco", - "address.state": "CA", - "address.country": "USA", - "key1.a": "a", - "key2[0]": 1, - "key2[1]": 2, - "key2[2]": 3 - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "splitio", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "event": "splitio_test_1", - "messageId": "9b200548-5961-4448-9dbc-098b7ce85751", - "properties": { - "eventTypeId": "page_load", - "trafficTypeName": "user", - "key": "key_user_0", - "timestamp": 1513357833000, - "value": "0.93", - "martin": 21.565, - "vertical": "restaurant", - "GMV": true, - "abc": "new-val", - "property1": { - "property2": 1, - "property3": "test", - "property4": { - "subProp1": { - "a": "a", - "b": "b" - }, - "subProp2": [ - "a", - "b" - ], - "subProp3": { - "prop": {} - } - } - }, - "properties5": null - }, - "receivedAt": "2021-03-01T22:55:54.806Z", - "rudderId": "6886eb9e-215d-4f61-a651-4b8ef18aaea3", - "timestamp": "2021-03-01T22:55:54.771Z", - "type": "track", - "userId": "user 1" - }, - "destination": { - "Config": { - "apiKey": "abcde", - "environment": "production", - "trafficType": "user" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://events.split.io/api/events", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer abcde" - }, - "params": {}, - "body": { - "JSON": { - "eventTypeId": "splitio_test_1", - "key": "user 1", - "timestamp": 1614639354771, - "value": 0.93, - "environmentName": "production", - "trafficTypeName": "user", - "properties": { - "martin": 21.565, - "vertical": "restaurant", - "GMV": true, - "abc": "new-val", - "property1.property2": 1, - "property1.property3": "test", - "property1.property4.subProp1.a": "a", - "property1.property4.subProp1.b": "b", - "property1.property4.subProp2[0]": "a", - "property1.property4.subProp2[1]": "b" - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "splitio", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "name": "splitio_test_1", - "messageId": "9b200548-5961-4448-9dbc-098b7ce85751", - "properties": { - "eventTypeId": "page_load", - "trafficTypeName": "user", - "key": "key_user_0", - "timestamp": 1513357833000, - "value": "0.93", - "martin": 21.565, - "vertical": "restaurant", - "GMV": true, - "abc": "new-val" - }, - "receivedAt": "2021-03-01T22:55:54.806Z", - "rudderId": "6886eb9e-215d-4f61-a651-4b8ef18aaea3", - "timestamp": "2021-03-01T22:55:54.771Z", - "type": "page", - "userId": "user 1" - }, - "destination": { - "Config": { - "apiKey": "abcde", - "environment": "production", - "trafficType": "user" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://events.split.io/api/events", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer abcde" - }, - "params": {}, - "body": { - "JSON": { - "eventTypeId": "Viewed_splitio_test_1_page", - "key": "user 1", - "timestamp": 1614639354771, - "value": 0.93, - "environmentName": "production", - "trafficTypeName": "user", - "properties": { - "martin": 21.565, - "vertical": "restaurant", - "GMV": true, - "abc": "new-val" - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "splitio", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "name": "splitio_test_1", - "messageId": "9b200548-5961-4448-9dbc-098b7ce85751", - "properties": { - "eventTypeId": "page_load", - "trafficTypeName": "user", - "key": "key_user_0", - "timestamp": 1513357833000, - "value": "0.93", - "martin": 21.565, - "vertical": "restaurant", - "GMV": true, - "abc": "new-val" - }, - "receivedAt": "2021-03-01T22:55:54.806Z", - "rudderId": "6886eb9e-215d-4f61-a651-4b8ef18aaea3", - "timestamp": "2021-03-01T22:55:54.771Z", - "type": "screen", - "userId": "user 1" - }, - "destination": { - "Config": { - "apiKey": "abcde", - "environment": "staging", - "trafficType": "user" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://events.split.io/api/events", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer abcde" - }, - "params": {}, - "body": { - "JSON": { - "eventTypeId": "Viewed_splitio_test_1_screen", - "key": "user 1", - "timestamp": 1614639354771, - "value": 0.93, - "environmentName": "staging", - "trafficTypeName": "user", - "properties": { - "martin": 21.565, - "vertical": "restaurant", - "GMV": true, - "abc": "new-val" - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "splitio", - "description": "Test 5", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "userId": "user123", - "messageId": "c73198a8-41d8-4426-9fd9-de167194d5f3", - "rudderId": "bda76e3e-87eb-4153-9d1e-e9c2ed48b7a5", - "context": { - "ip": "14.5.67.21", - "traits": { - "abc": "new-val", - "key": "key_user_0", - "newProperty": "1", - "martin": 21.565, - "vertical": "restaurant", - "GMV": false - }, - "library": { - "name": "http" - } - }, - "type": "identify", - "timestamp": "2020-01-21T00:21:34.208Z", - "writeKey": "1pe7u01A7rYOrvacE6WSgI6ESXh", - "receivedAt": "2021-04-19T14:53:18.215+05:30", - "requestIP": "[::1]" - }, - "destination": { - "Config": { - "apiKey": "abcde", - "environment": "staging", - "trafficType": "user" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://events.split.io/api/events", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer abcde" - }, - "params": {}, - "body": { - "JSON": { - "eventTypeId": "identify", - "key": "user123", - "timestamp": 1579566094208, - "environmentName": "staging", - "trafficTypeName": "user", - "properties": { - "abc": "new-val", - "newProperty": "1", - "martin": 21.565, - "vertical": "restaurant", - "GMV": false - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "splitio", - "description": "Test 6", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "userId": "user123", - "messageId": "c73198a8-41d8-4426-9fd9-de167194d5f3", - "rudderId": "bda76e3e-87eb-4153-9d1e-e9c2ed48b7a5", - "context": { - "ip": "14.5.67.21", - "traits": { - "abc": "new-val", - "key": "key_user_0", - "newProperty": "1" - }, - "library": { - "name": "http" - } - }, - "timestamp": "2020-01-21T00:21:34.208Z", - "writeKey": "1pe7u01A7rYOrvacE6WSgI6ESXh", - "receivedAt": "2021-04-19T14:53:18.215+05:30", - "requestIP": "[::1]" - }, - "destination": { - "Config": { - "apiKey": "abcde", - "environment": "staging", - "trafficType": "user" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "Event type is required", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "SPLITIO", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "splitio", - "description": "Test 7", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "userId": "user123", - "messageId": "c73198a8-41d8-4426-9fd9-de167194d5f3", - "rudderId": "bda76e3e-87eb-4153-9d1e-e9c2ed48b7a5", - "context": { - "ip": "14.5.67.21", - "traits": { - "abc": "new-val", - "key": "key_user_0", - "newProperty": "1" - }, - "library": { - "name": "http" - } - }, - "type": "abc", - "timestamp": "2020-01-21T00:21:34.208Z", - "writeKey": "1pe7u01A7rYOrvacE6WSgI6ESXh", - "receivedAt": "2021-04-19T14:53:18.215+05:30", - "requestIP": "[::1]" - }, - "destination": { - "Config": { - "apiKey": "abcde", - "environment": "staging", - "trafficType": "user" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "Event type abc is not supported", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "SPLITIO", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "splitio", - "description": "Test 8", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "name": "@$%%^&", - "messageId": "9b200548-5961-4448-9dbc-098b7ce85751", - "properties": { - "eventTypeId": "page_load", - "trafficTypeName": "user", - "key": "key_user_0", - "timestamp": 1513357833000, - "value": "0.93", - "martin": 21.565, - "vertical": "restaurant", - "GMV": true, - "abc": "new-val" - }, - "receivedAt": "2021-03-01T22:55:54.806Z", - "rudderId": "6886eb9e-215d-4f61-a651-4b8ef18aaea3", - "timestamp": "2021-03-01T22:55:54.771Z", - "type": "page", - "userId": "user 1" - }, - "destination": { - "Config": { - "apiKey": "abcde", - "environment": "production", - "trafficType": "user" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "eventTypeId does not match with ideal format /^[\\dA-Za-z][\\w.-]{0,79}$/", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "SPLITIO", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "splitio", - "description": "Test 9", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "name": "1pplication accepted", - "messageId": "9b200548-5961-4448-9dbc-098b7ce85751", - "category": "food", - "properties": { - "eventTypeId": "page_load", - "trafficTypeName": "user", - "key": "key_user_0", - "timestamp": 1513357833000, - "value": "bc2", - "martin": 21.565, - "vertical": [ - "restaurant", - "mall" - ], - "GMV": true, - "abc": "new-val" - }, - "receivedAt": "2021-03-01T22:55:54.806Z", - "rudderId": "6886eb9e-215d-4f61-a651-4b8ef18aaea3", - "timestamp": "2021-03-01T22:55:54.771Z", - "type": "page", - "userId": "user 1" - }, - "destination": { - "Config": { - "apiKey": "abcde", - "environment": "production", - "trafficType": "user" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://events.split.io/api/events", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer abcde" - }, - "params": {}, - "body": { - "JSON": { - "eventTypeId": "Viewed_1pplication_accepted_page", - "key": "user 1", - "timestamp": 1614639354771, - "environmentName": "production", - "trafficTypeName": "user", - "properties": { - "martin": 21.565, - "vertical[0]": "restaurant", - "vertical[1]": "mall", - "GMV": true, - "abc": "new-val", - "category": "food" - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "splitio", - "description": "Test 10", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "userId": "user123", - "messageId": "c73198a8-41d8-4426-9fd9-de167194d5f3", - "rudderId": "bda76e3e-87eb-4153-9d1e-e9c2ed48b7a5", - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "type": "identify", - "timestamp": "2020-01-21T00:21:34.208Z", - "writeKey": "1pe7u01A7rYOrvacE6WSgI6ESXh", - "receivedAt": "2021-04-19T14:53:18.215+05:30", - "requestIP": "[::1]" - }, - "destination": { - "Config": { - "apiKey": "abcde", - "environment": "staging", - "trafficType": "user" - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://events.split.io/api/events", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer abcde" - }, - "params": {}, - "body": { - "JSON": { - "eventTypeId": "identify", - "key": "user123", - "timestamp": 1579566094208, - "environmentName": "staging", - "trafficTypeName": "user", - "properties": {} - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - } -] + { + name: 'splitio', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + traits: { + martin: 21.565, + trafficTypeName: 'user', + vertical: 'restaurant', + eventTypeId: 'page_load end to end', + timestamp: 1513357833000, + GMV: false, + }, + userId: 'user123', + messageId: 'c73198a8-41d8-4426-9fd9-de167194d5f3', + rudderId: 'bda76e3e-87eb-4153-9d1e-e9c2ed48b7a5', + context: { + ip: '14.5.67.21', + traits: { + abc: 'new-val', + key: 'key_user_0', + value: '0.93', + }, + library: { + name: 'http', + }, + }, + type: 'group', + groupId: 'group1', + timestamp: '2020-01-21T00:21:34.208Z', + writeKey: '1pe7u01A7rYOrvacE6WSgI6ESXh', + receivedAt: '2021-04-19T14:53:18.215+05:30', + requestIP: '[::1]', + }, + destination: { + Config: { + apiKey: 'abcde', + environment: 'staging', + trafficType: 'user', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://events.split.io/api/events', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer abcde', + }, + params: {}, + body: { + JSON: { + eventTypeId: 'group', + key: 'user123', + timestamp: 1579566094208, + environmentName: 'staging', + trafficTypeName: 'user', + properties: { + martin: 21.565, + vertical: 'restaurant', + GMV: false, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'splitio', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + traits: { + martin: 21.565, + trafficTypeName: 'user', + eventTypeId: 'page_load end to end', + timestamp: 1513357833000, + address: { + city: 'San Francisco', + state: 'CA', + country: 'USA', + }, + key1: { + a: 'a', + }, + key2: [1, 2, 3], + key3: { + key4: {}, + }, + key5: null, + }, + userId: 'user123', + messageId: 'c73198a8-41d8-4426-9fd9-de167194d5f3', + rudderId: 'bda76e3e-87eb-4153-9d1e-e9c2ed48b7a5', + context: { + ip: '14.5.67.21', + traits: { + abc: 'new-val', + key: 'key_user_0', + }, + library: { + name: 'http', + }, + }, + type: 'identify', + timestamp: '2020-01-21T00:21:34.208Z', + writeKey: '1pe7u01A7rYOrvacE6WSgI6ESXh', + receivedAt: '2021-04-19T14:53:18.215+05:30', + requestIP: '[::1]', + }, + destination: { + Config: { + apiKey: 'abcde', + environment: 'staging', + trafficType: 'user', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://events.split.io/api/events', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer abcde', + }, + params: {}, + body: { + JSON: { + eventTypeId: 'identify', + key: 'user123', + timestamp: 1579566094208, + environmentName: 'staging', + trafficTypeName: 'user', + properties: { + martin: 21.565, + 'address.city': 'San Francisco', + 'address.state': 'CA', + 'address.country': 'USA', + 'key1.a': 'a', + 'key2[0]': 1, + 'key2[1]': 2, + 'key2[2]': 3, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'splitio', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'splitio_test_1', + messageId: '9b200548-5961-4448-9dbc-098b7ce85751', + properties: { + eventTypeId: 'page_load', + trafficTypeName: 'user', + key: 'key_user_0', + timestamp: 1513357833000, + value: '0.93', + martin: 21.565, + vertical: 'restaurant', + GMV: true, + abc: 'new-val', + property1: { + property2: 1, + property3: 'test', + property4: { + subProp1: { + a: 'a', + b: 'b', + }, + subProp2: ['a', 'b'], + subProp3: { + prop: {}, + }, + }, + }, + properties5: null, + }, + receivedAt: '2021-03-01T22:55:54.806Z', + rudderId: '6886eb9e-215d-4f61-a651-4b8ef18aaea3', + timestamp: '2021-03-01T22:55:54.771Z', + type: 'track', + userId: 'user 1', + }, + destination: { + Config: { + apiKey: 'abcde', + environment: 'production', + trafficType: 'user', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://events.split.io/api/events', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer abcde', + }, + params: {}, + body: { + JSON: { + eventTypeId: 'splitio_test_1', + key: 'user 1', + timestamp: 1614639354771, + value: 0.93, + environmentName: 'production', + trafficTypeName: 'user', + properties: { + martin: 21.565, + vertical: 'restaurant', + GMV: true, + abc: 'new-val', + 'property1.property2': 1, + 'property1.property3': 'test', + 'property1.property4.subProp1.a': 'a', + 'property1.property4.subProp1.b': 'b', + 'property1.property4.subProp2[0]': 'a', + 'property1.property4.subProp2[1]': 'b', + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'splitio', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + name: 'splitio_test_1', + messageId: '9b200548-5961-4448-9dbc-098b7ce85751', + properties: { + eventTypeId: 'page_load', + trafficTypeName: 'user', + key: 'key_user_0', + timestamp: 1513357833000, + value: '0.93', + martin: 21.565, + vertical: 'restaurant', + GMV: true, + abc: 'new-val', + }, + receivedAt: '2021-03-01T22:55:54.806Z', + rudderId: '6886eb9e-215d-4f61-a651-4b8ef18aaea3', + timestamp: '2021-03-01T22:55:54.771Z', + type: 'page', + userId: 'user 1', + }, + destination: { + Config: { + apiKey: 'abcde', + environment: 'production', + trafficType: 'user', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://events.split.io/api/events', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer abcde', + }, + params: {}, + body: { + JSON: { + eventTypeId: 'Viewed_splitio_test_1_page', + key: 'user 1', + timestamp: 1614639354771, + value: 0.93, + environmentName: 'production', + trafficTypeName: 'user', + properties: { + martin: 21.565, + vertical: 'restaurant', + GMV: true, + abc: 'new-val', + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'splitio', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + name: 'splitio_test_1', + messageId: '9b200548-5961-4448-9dbc-098b7ce85751', + properties: { + eventTypeId: 'page_load', + trafficTypeName: 'user', + key: 'key_user_0', + timestamp: 1513357833000, + value: '0.93', + martin: 21.565, + vertical: 'restaurant', + GMV: true, + abc: 'new-val', + }, + receivedAt: '2021-03-01T22:55:54.806Z', + rudderId: '6886eb9e-215d-4f61-a651-4b8ef18aaea3', + timestamp: '2021-03-01T22:55:54.771Z', + type: 'screen', + userId: 'user 1', + }, + destination: { + Config: { + apiKey: 'abcde', + environment: 'staging', + trafficType: 'user', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://events.split.io/api/events', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer abcde', + }, + params: {}, + body: { + JSON: { + eventTypeId: 'Viewed_splitio_test_1_screen', + key: 'user 1', + timestamp: 1614639354771, + value: 0.93, + environmentName: 'staging', + trafficTypeName: 'user', + properties: { + martin: 21.565, + vertical: 'restaurant', + GMV: true, + abc: 'new-val', + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'splitio', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user123', + messageId: 'c73198a8-41d8-4426-9fd9-de167194d5f3', + rudderId: 'bda76e3e-87eb-4153-9d1e-e9c2ed48b7a5', + context: { + ip: '14.5.67.21', + traits: { + abc: 'new-val', + key: 'key_user_0', + newProperty: '1', + martin: 21.565, + vertical: 'restaurant', + GMV: false, + }, + library: { + name: 'http', + }, + }, + type: 'identify', + timestamp: '2020-01-21T00:21:34.208Z', + writeKey: '1pe7u01A7rYOrvacE6WSgI6ESXh', + receivedAt: '2021-04-19T14:53:18.215+05:30', + requestIP: '[::1]', + }, + destination: { + Config: { + apiKey: 'abcde', + environment: 'staging', + trafficType: 'user', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://events.split.io/api/events', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer abcde', + }, + params: {}, + body: { + JSON: { + eventTypeId: 'identify', + key: 'user123', + timestamp: 1579566094208, + environmentName: 'staging', + trafficTypeName: 'user', + properties: { + abc: 'new-val', + newProperty: '1', + martin: 21.565, + vertical: 'restaurant', + GMV: false, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'splitio', + description: 'Test 6', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user123', + messageId: 'c73198a8-41d8-4426-9fd9-de167194d5f3', + rudderId: 'bda76e3e-87eb-4153-9d1e-e9c2ed48b7a5', + context: { + ip: '14.5.67.21', + traits: { + abc: 'new-val', + key: 'key_user_0', + newProperty: '1', + }, + library: { + name: 'http', + }, + }, + timestamp: '2020-01-21T00:21:34.208Z', + writeKey: '1pe7u01A7rYOrvacE6WSgI6ESXh', + receivedAt: '2021-04-19T14:53:18.215+05:30', + requestIP: '[::1]', + }, + destination: { + Config: { + apiKey: 'abcde', + environment: 'staging', + trafficType: 'user', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Event type is required', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'SPLITIO', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'splitio', + description: 'Test 7', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user123', + messageId: 'c73198a8-41d8-4426-9fd9-de167194d5f3', + rudderId: 'bda76e3e-87eb-4153-9d1e-e9c2ed48b7a5', + context: { + ip: '14.5.67.21', + traits: { + abc: 'new-val', + key: 'key_user_0', + newProperty: '1', + }, + library: { + name: 'http', + }, + }, + type: 'abc', + timestamp: '2020-01-21T00:21:34.208Z', + writeKey: '1pe7u01A7rYOrvacE6WSgI6ESXh', + receivedAt: '2021-04-19T14:53:18.215+05:30', + requestIP: '[::1]', + }, + destination: { + Config: { + apiKey: 'abcde', + environment: 'staging', + trafficType: 'user', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Event type abc is not supported', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'SPLITIO', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'splitio', + description: 'Test 8', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + name: '@$%%^&', + messageId: '9b200548-5961-4448-9dbc-098b7ce85751', + properties: { + eventTypeId: 'page_load', + trafficTypeName: 'user', + key: 'key_user_0', + timestamp: 1513357833000, + value: '0.93', + martin: 21.565, + vertical: 'restaurant', + GMV: true, + abc: 'new-val', + }, + receivedAt: '2021-03-01T22:55:54.806Z', + rudderId: '6886eb9e-215d-4f61-a651-4b8ef18aaea3', + timestamp: '2021-03-01T22:55:54.771Z', + type: 'page', + userId: 'user 1', + }, + destination: { + Config: { + apiKey: 'abcde', + environment: 'production', + trafficType: 'user', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'eventTypeId does not match with ideal format /^[\\dA-Za-z][\\w.-]{0,79}$/', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'SPLITIO', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'splitio', + description: 'Test 9', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + name: '1pplication accepted', + messageId: '9b200548-5961-4448-9dbc-098b7ce85751', + category: 'food', + properties: { + eventTypeId: 'page_load', + trafficTypeName: 'user', + key: 'key_user_0', + timestamp: 1513357833000, + value: 'bc2', + martin: 21.565, + vertical: ['restaurant', 'mall'], + GMV: true, + abc: 'new-val', + }, + receivedAt: '2021-03-01T22:55:54.806Z', + rudderId: '6886eb9e-215d-4f61-a651-4b8ef18aaea3', + timestamp: '2021-03-01T22:55:54.771Z', + type: 'page', + userId: 'user 1', + }, + destination: { + Config: { + apiKey: 'abcde', + environment: 'production', + trafficType: 'user', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://events.split.io/api/events', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer abcde', + }, + params: {}, + body: { + JSON: { + eventTypeId: 'Viewed_1pplication_accepted_page', + key: 'user 1', + timestamp: 1614639354771, + environmentName: 'production', + trafficTypeName: 'user', + properties: { + martin: 21.565, + 'vertical[0]': 'restaurant', + 'vertical[1]': 'mall', + GMV: true, + abc: 'new-val', + category: 'food', + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'splitio', + description: 'Test 10', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user123', + messageId: 'c73198a8-41d8-4426-9fd9-de167194d5f3', + rudderId: 'bda76e3e-87eb-4153-9d1e-e9c2ed48b7a5', + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + type: 'identify', + timestamp: '2020-01-21T00:21:34.208Z', + writeKey: '1pe7u01A7rYOrvacE6WSgI6ESXh', + receivedAt: '2021-04-19T14:53:18.215+05:30', + requestIP: '[::1]', + }, + destination: { + Config: { + apiKey: 'abcde', + environment: 'staging', + trafficType: 'user', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://events.split.io/api/events', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer abcde', + }, + params: {}, + body: { + JSON: { + eventTypeId: 'identify', + key: 'user123', + timestamp: 1579566094208, + environmentName: 'staging', + trafficTypeName: 'user', + properties: {}, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/the_trade_desk/common.ts b/test/integrations/destinations/the_trade_desk/common.ts index d792c7faaec..08ba0ee6ea3 100644 --- a/test/integrations/destinations/the_trade_desk/common.ts +++ b/test/integrations/destinations/the_trade_desk/common.ts @@ -1,9 +1,13 @@ +import { Destination } from '../../../../src/types'; + const destType = 'the_trade_desk'; const destTypeInUpperCase = 'THE_TRADE_DESK'; const advertiserId = 'test-advertiser-id'; const dataProviderId = 'rudderstack'; const segmentName = 'test-segment'; -const sampleDestination = { +const firstPartyDataEndpoint = 'https://sin-data.adsrvr.org/data/advertiser'; + +const sampleDestination: Destination = { Config: { advertiserId, advertiserSecretKey: 'test-advertiser-secret-key', @@ -11,7 +15,17 @@ const sampleDestination = { ttlInDays: 30, audienceId: segmentName, }, - DestinationDefinition: { Config: { cdkV2Enabled: true } }, + DestinationDefinition: { + Config: { cdkV2Enabled: true }, + ID: '123', + Name: 'TRADEDESK', + DisplayName: 'Trade Desk', + }, + ID: '345', + Name: 'Test', + Enabled: true, + WorkspaceID: '', + Transformations: [], }; const sampleSource = { @@ -33,6 +47,22 @@ const sampleContext = { sources: sampleSource, }; +const proxyV1AbortableErrorStatTags = { + destType: destTypeInUpperCase, + destinationId: 'default-destinationId', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'default-workspaceId', +}; + +const { errorType: _, ...proxyV1PlatformErrorStatTags } = proxyV1AbortableErrorStatTags; +proxyV1PlatformErrorStatTags.errorCategory = 'platform'; + +const proxyV1RetryableErrorStatTags = { ...proxyV1AbortableErrorStatTags, errorType: 'retryable' }; + export { destType, destTypeInUpperCase, @@ -41,4 +71,8 @@ export { segmentName, sampleDestination, sampleContext, + proxyV1AbortableErrorStatTags, + proxyV1PlatformErrorStatTags, + proxyV1RetryableErrorStatTags, + firstPartyDataEndpoint, }; diff --git a/test/integrations/destinations/the_trade_desk/delivery/business.ts b/test/integrations/destinations/the_trade_desk/delivery/business.ts new file mode 100644 index 00000000000..0406a5f0bc7 --- /dev/null +++ b/test/integrations/destinations/the_trade_desk/delivery/business.ts @@ -0,0 +1,175 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV1Payload, generateMetadata } from '../../../testUtils'; +import { + destType, + advertiserId, + dataProviderId, + segmentName, + sampleDestination, + proxyV1AbortableErrorStatTags, + firstPartyDataEndpoint, +} from '../common'; + +const validRequestPayload1 = { + AdvertiserId: advertiserId, + DataProviderId: dataProviderId, + Items: [ + { + DAID: 'test-daid-1', + Data: [ + { + Name: segmentName, + TTLInMinutes: 43200, + }, + ], + }, + { + Data: [ + { + Name: segmentName, + TTLInMinutes: 43200, + }, + ], + UID2: 'test-uid2-1', + }, + { + DAID: 'test-daid-2', + Data: [ + { + Name: segmentName, + TTLInMinutes: 0, + }, + ], + }, + { + Data: [ + { + Name: segmentName, + TTLInMinutes: 0, + }, + ], + UID2: 'test-uid2-2', + }, + ], +}; + +const invalidRequestPayload1 = { + AdvertiserId: advertiserId, + DataProviderId: dataProviderId, + Items: [ + { + DAID: 'test-daid', + Data: [ + { + Name: segmentName, + TTLInMinutes: 43200, + }, + ], + }, + { + Data: [ + { + Name: segmentName, + TTLInMinutes: 43200, + }, + ], + UID2: 'test-invalid-uid2', + }, + ], +}; + +const metadataArray = [generateMetadata(1)]; + +export const businessProxyV1: ProxyV1TestData[] = [ + { + id: 'ttd_v1_scenario_1', + name: destType, + description: + '[Proxy v1 API] :: Test for a valid request - Successful delivery of Add/Remove IDs to Trade Desk', + successCriteria: 'Should return 200 with no error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: {}, + params: {}, + JSON: validRequestPayload1, + endpoint: firstPartyDataEndpoint, + }, + metadataArray, + sampleDestination.Config, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + response: [ + { + statusCode: 200, + metadata: generateMetadata(1), + error: '{}', + }, + ], + }, + }, + }, + }, + }, + { + id: 'ttd_v1_scenario_2', + name: destType, + description: + '[Proxy v1 API] :: Test for invalid ID - where the destination responds with 200 with invalid ID', + successCriteria: 'Should return 400 with error with destination response', + scenario: 'Business', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: {}, + params: {}, + JSON: invalidRequestPayload1, + endpoint: firstPartyDataEndpoint, + }, + metadataArray, + sampleDestination.Config, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: + 'Request failed with status: 200 due to {"FailedLines":[{"ErrorCode":"MissingUserId","Message":"Invalid UID2, item #2"}]}', + response: [ + { + error: + '{"FailedLines":[{"ErrorCode":"MissingUserId","Message":"Invalid UID2, item #2"}]}', + metadata: generateMetadata(1), + statusCode: 400, + }, + ], + statTags: proxyV1AbortableErrorStatTags, + status: 400, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/the_trade_desk/delivery/data.ts b/test/integrations/destinations/the_trade_desk/delivery/data.ts index 320eb6dcfe2..5099eafce72 100644 --- a/test/integrations/destinations/the_trade_desk/delivery/data.ts +++ b/test/integrations/destinations/the_trade_desk/delivery/data.ts @@ -1,248 +1,3 @@ -import { - destType, - destTypeInUpperCase, - advertiserId, - dataProviderId, - segmentName, - sampleDestination, -} from '../common'; - -beforeAll(() => { - process.env.THE_TRADE_DESK_DATA_PROVIDER_SECRET_KEY = 'mockedDataProviderSecretKey'; -}); - -afterAll(() => { - delete process.env.THE_TRADE_DESK_DATA_PROVIDER_SECRET_KEY; -}); - -export const data = [ - { - name: destType, - description: 'Successful delivery of Add/Remove IDs to/from Trade Desk', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://sin-data.adsrvr.org/data/advertiser', - headers: {}, - params: {}, - destinationConfig: sampleDestination.Config, - body: { - JSON: { - AdvertiserId: advertiserId, - DataProviderId: dataProviderId, - Items: [ - { - DAID: 'test-daid-1', - Data: [ - { - Name: segmentName, - TTLInMinutes: 43200, - }, - ], - }, - { - Data: [ - { - Name: segmentName, - TTLInMinutes: 43200, - }, - ], - UID2: 'test-uid2-1', - }, - { - DAID: 'test-daid-2', - Data: [ - { - Name: segmentName, - TTLInMinutes: 0, - }, - ], - }, - { - Data: [ - { - Name: segmentName, - TTLInMinutes: 0, - }, - ], - UID2: 'test-uid2-2', - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: { - output: { - destinationResponse: { - response: {}, - status: 200, - }, - message: 'Request Processed Successfully', - status: 200, - }, - }, - }, - }, - }, - { - name: destType, - description: 'Error response from The Trade Desk due to invalid IDs', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://sin-data.adsrvr.org/data/advertiser', - headers: {}, - params: {}, - destinationConfig: sampleDestination.Config, - body: { - JSON: { - AdvertiserId: advertiserId, - DataProviderId: dataProviderId, - Items: [ - { - DAID: 'test-daid', - Data: [ - { - Name: segmentName, - TTLInMinutes: 43200, - }, - ], - }, - { - Data: [ - { - Name: segmentName, - TTLInMinutes: 43200, - }, - ], - UID2: 'test-invalid-uid2', - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - method: 'POST', - }, - }, - output: { - response: { - status: 400, - body: { - output: { - destinationResponse: { - response: { - FailedLines: [{ ErrorCode: 'MissingUserId', Message: 'Invalid UID2, item #2' }], - }, - status: 200, - }, - message: - 'Request failed with status: 200 due to {"FailedLines":[{"ErrorCode":"MissingUserId","Message":"Invalid UID2, item #2"}]}', - statTags: { - destType: destTypeInUpperCase, - destinationId: 'Non-determininable', - errorCategory: 'network', - errorType: 'aborted', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', - workspaceId: 'Non-determininable', - }, - status: 400, - }, - }, - }, - }, - }, - { - name: destType, - description: - 'Missing advertiser secret key in destination config from proxy request from server', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://sin-data.adsrvr.org/data/advertiser', - headers: {}, - params: {}, - body: { - JSON: { - AdvertiserId: advertiserId, - DataProviderId: dataProviderId, - Items: [ - { - DAID: 'test-daid-1', - Data: [ - { - Name: segmentName, - TTLInMinutes: 43200, - }, - ], - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - method: 'POST', - }, - }, - output: { - response: { - status: 400, - body: { - output: { - destinationResponse: '', - message: 'Advertiser secret key is missing in destination config. Aborting', - statTags: { - destType: destTypeInUpperCase, - destinationId: 'Non-determininable', - errorCategory: 'platform', - feature: 'dataDelivery', - implementation: 'native', - module: 'destination', - workspaceId: 'Non-determininable', - }, - status: 400, - }, - }, - }, - }, - }, -]; +import { businessProxyV1 } from './business'; +import { otherProxyV1 } from './other'; +export const data = [...businessProxyV1, ...otherProxyV1]; diff --git a/test/integrations/destinations/the_trade_desk/delivery/other.ts b/test/integrations/destinations/the_trade_desk/delivery/other.ts new file mode 100644 index 00000000000..bed10e6ec58 --- /dev/null +++ b/test/integrations/destinations/the_trade_desk/delivery/other.ts @@ -0,0 +1,290 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateProxyV1Payload, generateMetadata } from '../../../testUtils'; +import { + destType, + advertiserId, + dataProviderId, + segmentName, + proxyV1PlatformErrorStatTags, + proxyV1RetryableErrorStatTags, + firstPartyDataEndpoint, + sampleDestination, +} from '../common'; +import { envMock } from '../mocks'; + +envMock(); + +const validRequestPayload1 = { + AdvertiserId: advertiserId, + DataProviderId: dataProviderId, + Items: [ + { + DAID: 'test-daid-1', + Data: [ + { + Name: segmentName, + TTLInMinutes: 43200, + }, + ], + }, + ], +}; + +const metadataArray = [generateMetadata(1)]; + +// https://partner.thetradedesk.com/v3/portal/data/doc/post-data-advertiser-external#error-codes-messages +export const otherProxyV1: ProxyV1TestData[] = [ + { + id: 'ttd_v1_other_scenario_1', + name: destType, + description: + '[Proxy v1 API] :: Missing advertiser secret key in destination config from proxy request from server', + successCriteria: 'Should return 400 with platform error', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: {}, + params: {}, + JSON: validRequestPayload1, + endpoint: firstPartyDataEndpoint, + }, + metadataArray, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + message: 'Advertiser secret key is missing in destination config. Aborting', + response: [ + { + error: 'Advertiser secret key is missing in destination config. Aborting', + metadata: generateMetadata(1), + statusCode: 400, + }, + ], + statTags: proxyV1PlatformErrorStatTags, + status: 400, + }, + }, + }, + }, + }, + { + id: 'ttd_v1_other_scenario_2', + name: destType, + description: + '[Proxy v1 API] :: Scenario for testing Service Unavailable error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + endpoint: 'https://random_test_url/test_for_service_not_available', + }, + metadataArray, + sampleDestination.Config, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: + '{"error":{"message":"Service Unavailable","description":"The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later."}}', + statusCode: 503, + metadata: generateMetadata(1), + }, + ], + statTags: proxyV1RetryableErrorStatTags, + message: + 'Request failed with status: 503 due to {"error":{"message":"Service Unavailable","description":"The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later."}}', + status: 503, + }, + }, + }, + }, + }, + { + id: 'ttd_v1_other_scenario_3', + name: destType, + description: '[Proxy v1 API] :: Scenario for testing Internal Server error from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + endpoint: 'https://random_test_url/test_for_internal_server_error', + }, + metadataArray, + sampleDestination.Config, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Internal Server Error"', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: proxyV1RetryableErrorStatTags, + message: 'Request failed with status: 500 due to "Internal Server Error"', + status: 500, + }, + }, + }, + }, + }, + { + id: 'ttd_v1_other_scenario_4', + name: destType, + description: '[Proxy v1 API] :: Scenario for testing Gateway Time Out error from destination', + successCriteria: 'Should return 504 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + endpoint: 'https://random_test_url/test_for_gateway_time_out', + }, + metadataArray, + sampleDestination.Config, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '"Gateway Timeout"', + statusCode: 504, + metadata: generateMetadata(1), + }, + ], + statTags: proxyV1RetryableErrorStatTags, + message: 'Request failed with status: 504 due to "Gateway Timeout"', + status: 504, + }, + }, + }, + }, + }, + { + id: 'ttd_v1_other_scenario_5', + name: destType, + description: '[Proxy v1 API] :: Scenario for testing null response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + endpoint: 'https://random_test_url/test_for_null_response', + }, + metadataArray, + sampleDestination.Config, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: proxyV1RetryableErrorStatTags, + message: 'Request failed with status: 500 due to ""', + status: 500, + }, + }, + }, + }, + }, + { + id: 'ttd_v1_other_scenario_6', + name: destType, + description: + '[Proxy v1 API] :: Scenario for testing null and no status response from destination', + successCriteria: 'Should return 500 status code with error message', + scenario: 'Framework', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + endpoint: 'https://random_test_url/test_for_null_and_no_status', + }, + metadataArray, + sampleDestination.Config, + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '""', + statusCode: 500, + metadata: generateMetadata(1), + }, + ], + statTags: proxyV1RetryableErrorStatTags, + message: 'Request failed with status: 500 due to ""', + status: 500, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/the_trade_desk/mocks.ts b/test/integrations/destinations/the_trade_desk/mocks.ts index ddcbebae880..bf9d910d426 100644 --- a/test/integrations/destinations/the_trade_desk/mocks.ts +++ b/test/integrations/destinations/the_trade_desk/mocks.ts @@ -3,3 +3,12 @@ import config from '../../../../src/cdk/v2/destinations/the_trade_desk/config'; export const defaultMockFns = () => { jest.replaceProperty(config, 'MAX_REQUEST_SIZE_IN_BYTES', 250); }; + +export const envMock = () => { + process.env.THE_TRADE_DESK_DATA_PROVIDER_SECRET_KEY = 'mockedDataProviderSecretKey'; + + // Clean up after all tests are done + afterAll(() => { + delete process.env.THE_TRADE_DESK_DATA_PROVIDER_SECRET_KEY; + }); +}; diff --git a/test/integrations/destinations/the_trade_desk/router/data.ts b/test/integrations/destinations/the_trade_desk/router/data.ts index b02a80f563c..f095f561dbd 100644 --- a/test/integrations/destinations/the_trade_desk/router/data.ts +++ b/test/integrations/destinations/the_trade_desk/router/data.ts @@ -360,7 +360,7 @@ export const data = [ { jobId: 2, userId: 'u1' }, ], statusCode: 400, - error: 'Segment name is not present. Aborting', + error: 'Segment name/Audience ID is not present. Aborting', statTags: { destType: destTypeInUpperCase, implementation: 'cdkV2', @@ -403,6 +403,24 @@ export const data = [ userId: 'u1', }, }, + { + message: { + type: 'record', + action: 'insert', + fields: { + DAID: 'test-daid-2', + UID2: 'test-uid2-2', + }, + channel: 'sources', + context: sampleContext, + recordId: '1', + }, + destination: overrideDestination(sampleDestination, { advertiserId: '' }), + metadata: { + jobId: 2, + userId: 'u1', + }, + }, ], destType, }, @@ -416,7 +434,10 @@ export const data = [ output: [ { batched: false, - metadata: [{ jobId: 1, userId: 'u1' }], + metadata: [ + { jobId: 1, userId: 'u1' }, + { jobId: 2, userId: 'u1' }, + ], statusCode: 400, error: 'Advertiser ID is not present. Aborting', statTags: { @@ -658,7 +679,8 @@ export const data = [ batched: false, metadata: [{ jobId: 2 }], statusCode: 400, - error: 'Invalid action type', + error: + 'Invalid action type. You can only add or remove IDs from the audience/segment', statTags: { destType: destTypeInUpperCase, implementation: 'cdkV2', @@ -771,7 +793,7 @@ export const data = [ batched: false, metadata: [{ jobId: 1 }], statusCode: 400, - error: 'Fields cannot be empty', + error: '`fields` cannot be empty', statTags: { destType: destTypeInUpperCase, implementation: 'cdkV2', @@ -826,7 +848,7 @@ export const data = [ batched: false, metadata: [{ jobId: 1 }], statusCode: 400, - error: 'Fields cannot be empty', + error: '`fields` cannot be empty', statTags: { destType: destTypeInUpperCase, implementation: 'cdkV2', @@ -843,4 +865,118 @@ export const data = [ }, mockFns: defaultMockFns, }, + { + name: destType, + description: 'Batch call with different event types', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + type: 'record', + action: 'insert', + fields: { + DAID: 'test-daid-1', + }, + channel: 'sources', + context: sampleContext, + recordId: '1', + }, + destination: sampleDestination, + metadata: { + jobId: 1, + }, + }, + { + message: { + type: 'identify', + context: { + traits: { + name: 'John Doe', + email: 'johndoe@gmail.com', + age: 25, + }, + }, + }, + destination: sampleDestination, + metadata: { + jobId: 2, + }, + }, + ], + destType, + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://sin-data.adsrvr.org/data/advertiser', + headers: {}, + params: {}, + body: { + JSON: { + DataProviderId: dataProviderId, + AdvertiserId: advertiserId, + Items: [ + { + DAID: 'test-daid-1', + Data: [ + { + Name: segmentName, + TTLInMinutes: 43200, + }, + ], + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 1, + }, + ], + batched: true, + statusCode: 200, + destination: sampleDestination, + }, + { + batched: false, + metadata: [{ jobId: 2 }], + statusCode: 400, + error: 'Event type identify is not supported', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'THE_TRADE_DESK', + module: 'destination', + implementation: 'cdkV2', + feature: 'router', + }, + destination: sampleDestination, + }, + ], + }, + }, + }, + }, ]; diff --git a/test/integrations/destinations/the_trade_desk_real_time_conversions/common.ts b/test/integrations/destinations/the_trade_desk_real_time_conversions/common.ts new file mode 100644 index 00000000000..9b79a7bcbd5 --- /dev/null +++ b/test/integrations/destinations/the_trade_desk_real_time_conversions/common.ts @@ -0,0 +1,91 @@ +import { Destination } from '../../../../src/types'; + +const destType = 'the_trade_desk_real_time_conversions'; +const destTypeInUpperCase = 'THE_TRADE_DESK_REAL_TIME_CONVERSIONS'; +const advertiserId = 'test-advertiser-id'; +const trackerId = 'test-trackerId'; +const sampleDestination: Destination = { + Config: { + advertiserId, + trackerId, + }, + Enabled: true, + ID: '123', + Name: 'TRADE_DESK_REAL_TIME_CONVERSIONS', + WorkspaceID: 'test-workspace-id', + Transformations: [], + DestinationDefinition: { + ID: '123', + DisplayName: 'Trade Desk', + Name: 'TRADE_DESK', + Config: { cdkV2Enabled: true }, + }, +}; + +const sampleContextForConversion = { + app: { + build: '1.0.0', + name: 'RudderLabs Android SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.5', + }, + device: { + adTrackingEnabled: true, + advertisingId: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + externalId: [ + { + type: 'daid', + id: 'test-daid', + }, + ], + ip: '0.0.0.0', + page: { + referrer: 'https://docs.rudderstack.com/destinations/trade_desk', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.5', + }, + locale: 'en-GB', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36', +}; + +const integrationObject = { + All: true, + THE_TRADE_DESK: { + policies: ['LDU'], + region: 'US-CA', + privacy_settings: [ + { + privacy_type: 'GDPR', + is_applicable: 1, + consent_string: 'ok', + }, + ], + }, +}; + +export { + destType, + destTypeInUpperCase, + advertiserId, + trackerId, + sampleDestination, + sampleContextForConversion, + integrationObject, +}; diff --git a/test/integrations/destinations/the_trade_desk_real_time_conversions/processor/data.ts b/test/integrations/destinations/the_trade_desk_real_time_conversions/processor/data.ts new file mode 100644 index 00000000000..264c7600883 --- /dev/null +++ b/test/integrations/destinations/the_trade_desk_real_time_conversions/processor/data.ts @@ -0,0 +1,984 @@ +import { overrideDestination } from '../../../testUtils'; +import { + destType, + destTypeInUpperCase, + advertiserId, + trackerId, + sampleDestination, + sampleContextForConversion, + integrationObject, +} from '../common'; + +export const data = [ + { + name: destType, + description: 'Missing advertiser ID in the config', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 'custom event abc', + properties: { + key1: 'value1', + value: 25, + product_id: 'prd123', + key2: true, + test: 'test123', + }, + }, + destination: overrideDestination(sampleDestination, { advertiserId: '' }), + metadata: { + jobId: 1, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Advertiser ID is not present. Aborting: Workflow: procWorkflow, Step: validateConfig, ChildStep: undefined, OriginalError: Advertiser ID is not present. Aborting', + statTags: { + destType: destTypeInUpperCase, + implementation: 'cdkV2', + feature: 'processor', + module: 'destination', + errorCategory: 'dataValidation', + errorType: 'configuration', + }, + metadata: { + jobId: 1, + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: destType, + description: 'Tracker id is not present', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 'custom event abc', + properties: { + key1: 'value1', + value: 25, + product_id: 'prd123', + key2: true, + test: 'test123', + }, + }, + destination: overrideDestination(sampleDestination, { trackerId: '' }), + metadata: { + jobId: 1, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Tracking Tag ID is not present. Aborting: Workflow: procWorkflow, Step: validateConfig, ChildStep: undefined, OriginalError: Tracking Tag ID is not present. Aborting', + statTags: { + destType: destTypeInUpperCase, + implementation: 'cdkV2', + feature: 'processor', + module: 'destination', + errorCategory: 'dataValidation', + errorType: 'configuration', + }, + metadata: { + jobId: 1, + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: destType, + description: 'Unsupported event type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'identify', + context: { + traits: { + name: 'John Doe', + email: 'johndoe@gmail.com', + age: 25, + }, + }, + }, + destination: sampleDestination, + metadata: { + jobId: 1, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Event type identify is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Event type identify is not supported', + statTags: { + destType: destTypeInUpperCase, + implementation: 'cdkV2', + feature: 'processor', + module: 'destination', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + }, + metadata: { + jobId: 1, + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: destType, + description: 'Product Added', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 'Product Added', + messageId: 'messageId123', + context: sampleContextForConversion, + properties: { + product_id: '622c6f5d5cf86a4c77358033', + sku: '8472-998-0112', + category: 'Games', + name: 'Cones of Dunshire', + brand: 'Wyatt Games', + variant: 'expansion pack', + price: 49.99, + quantity: 5, + coupon: 'PREORDER15', + position: 1, + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.webp', + key1: 'value1', + }, + integrations: integrationObject, + }, + destination: overrideDestination(sampleDestination, { + customProperties: [ + { + rudderProperty: 'properties.key1', + tradeDeskProperty: 'td1', + }, + { + rudderProperty: 'properties.key2', + tradeDeskProperty: 'td2', + }, + ], + }), + metadata: { + jobId: 1, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insight.adsrvr.org/track/realtimeconversion', + headers: { 'Content-Type': 'application/json' }, + params: {}, + body: { + JSON: { + data: [ + { + tracker_id: trackerId, + adv: advertiserId, + event_name: 'addtocart', + value: 249.95000000000002, + adid: 'test-daid', + adid_type: 'DAID', + client_ip: '0.0.0.0', + referrer_url: 'https://docs.rudderstack.com/destinations/trade_desk', + imp: 'messageId123', + items: [ + { + item_code: '622c6f5d5cf86a4c77358033', + name: 'Cones of Dunshire', + qty: 5, + price: 49.99, + }, + ], + td1: 'value1', + category: 'Games', + brand: 'Wyatt Games', + variant: 'expansion pack', + coupon: 'PREORDER15', + position: 1, + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.webp', + data_processing_option: { + policies: ['LDU'], + region: 'US-CA', + }, + privacy_settings: [ + { + privacy_type: 'GDPR', + is_applicable: 1, + consent_string: 'ok', + }, + ], + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: destType, + description: 'Product Viewed', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 'Product Viewed', + properties: { + product_id: '622c6f5d5cf86a4c77358033', + sku: '8472-998-0112', + category: 'Games', + name: 'Cones of Dunshire', + brand: 'Wyatt Games', + variant: 'expansion pack', + price: 49.99, + quantity: 5, + coupon: 'PREORDER15', + currency: 'USD', + position: 1, + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.webp', + }, + }, + destination: sampleDestination, + metadata: { + jobId: 1, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insight.adsrvr.org/track/realtimeconversion', + headers: { 'Content-Type': 'application/json' }, + params: {}, + body: { + JSON: { + data: [ + { + tracker_id: trackerId, + adv: advertiserId, + currency: 'USD', + event_name: 'viewitem', + value: 249.95000000000002, + items: [ + { + item_code: '622c6f5d5cf86a4c77358033', + name: 'Cones of Dunshire', + qty: 5, + price: 49.99, + }, + ], + category: 'Games', + brand: 'Wyatt Games', + variant: 'expansion pack', + coupon: 'PREORDER15', + position: 1, + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.webp', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: destType, + description: 'Product Added to Wishlist', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 'Product Added to Wishlist', + properties: { + wishlist_id: '74fkdjfl0jfdkdj29j030', + wishlist_name: 'New Games', + product_id: '622c6f5d5cf86a4c77358033', + sku: '8472-998-0112', + category: 'Games', + name: 'Cones of Dunshire', + brand: 'Wyatt Games', + variant: 'expansion pack', + price: 49.99, + quantity: 1, + coupon: 'PREORDER15', + position: 1, + url: 'https://www.site.com/product/path', + image_url: 'https://www.site.com/product/path.jpg', + }, + }, + destination: sampleDestination, + metadata: { + jobId: 1, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insight.adsrvr.org/track/realtimeconversion', + headers: { 'Content-Type': 'application/json' }, + params: {}, + body: { + JSON: { + data: [ + { + tracker_id: trackerId, + adv: advertiserId, + event_name: 'wishlistitem', + value: 49.99, + items: [ + { + item_code: '622c6f5d5cf86a4c77358033', + name: 'Cones of Dunshire', + qty: 1, + price: 49.99, + }, + ], + wishlist_id: '74fkdjfl0jfdkdj29j030', + wishlist_name: 'New Games', + category: 'Games', + brand: 'Wyatt Games', + variant: 'expansion pack', + coupon: 'PREORDER15', + position: 1, + url: 'https://www.site.com/product/path', + image_url: 'https://www.site.com/product/path.jpg', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: destType, + description: 'Cart Viewed', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 'Cart Viewed', + properties: { + cart_id: '6b2c6f5aecf86a4ae77358ae3', + products: [ + { + product_id: '622c6f5d5cf86a4c77358033', + sku: '8472-998-0112', + name: 'Cones of Dunshire', + price: 49.99, + position: 5, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + product_id: '577c6f5d5cf86a4c7735ba03', + sku: '3309-483-2201', + name: 'Five Crowns', + price: 5.99, + position: 2, + category: 'Games', + }, + ], + }, + }, + destination: sampleDestination, + metadata: { + jobId: 1, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insight.adsrvr.org/track/realtimeconversion', + headers: { 'Content-Type': 'application/json' }, + params: {}, + body: { + JSON: { + data: [ + { + tracker_id: trackerId, + adv: advertiserId, + event_name: 'viewcart', + items: [ + { + item_code: '622c6f5d5cf86a4c77358033', + name: 'Cones of Dunshire', + price: 49.99, + position: 5, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + item_code: '577c6f5d5cf86a4c7735ba03', + name: 'Five Crowns', + price: 5.99, + position: 2, + category: 'Games', + }, + ], + cart_id: '6b2c6f5aecf86a4ae77358ae3', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: destType, + description: 'Checkout Started', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 'Checkout Started', + properties: { + order_id: '40684e8f0eaf000000000000', + affiliation: 'Vandelay Games', + value: 52, + revenue: 50.0, + shipping: 4, + tax: 3, + discount: 5, + coupon: 'NEWCUST5', + currency: 'USD', + products: [ + { + product_id: '622c6f5d5cf86a4c77358033', + sku: '8472-998-0112', + name: 'Cones of Dunshire', + price: 40, + position: 1, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + product_id: '577c6f5d5cf86a4c7735ba03', + sku: '3309-483-2201', + name: 'Five Crowns', + price: 5, + position: 2, + category: 'Games', + }, + ], + }, + }, + destination: sampleDestination, + metadata: { + jobId: 1, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insight.adsrvr.org/track/realtimeconversion', + headers: { 'Content-Type': 'application/json' }, + params: {}, + body: { + JSON: { + data: [ + { + tracker_id: trackerId, + adv: advertiserId, + currency: 'USD', + order_id: '40684e8f0eaf000000000000', + event_name: 'startcheckout', + value: 50, + items: [ + { + item_code: '622c6f5d5cf86a4c77358033', + name: 'Cones of Dunshire', + price: 40, + position: 1, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + item_code: '577c6f5d5cf86a4c7735ba03', + name: 'Five Crowns', + price: 5, + position: 2, + category: 'Games', + }, + ], + affiliation: 'Vandelay Games', + shipping: 4, + tax: 3, + discount: 5, + coupon: 'NEWCUST5', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: destType, + description: 'Order Completed', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 'Order Completed', + properties: { + checkout_id: '70324a1f0eaf000000000000', + order_id: '40684e8f0eaf000000000000', + affiliation: 'Vandelay Games', + total: 52.0, + subtotal: 45.0, + revenue: 50.0, + shipping: 4.0, + tax: 3.0, + discount: 5.0, + coupon: 'NEWCUST5', + currency: 'USD', + products: [ + { + product_id: '622c6f5d5cf86a4c77358033', + sku: '8472-998-0112', + name: 'Cones of Dunshire', + price: 40, + position: 1, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + product_id: '577c6f5d5cf86a4c7735ba03', + sku: '3309-483-2201', + name: 'Five Crowns', + price: 5, + position: 2, + category: 'Games', + }, + ], + }, + }, + destination: sampleDestination, + metadata: { + jobId: 1, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insight.adsrvr.org/track/realtimeconversion', + headers: { 'Content-Type': 'application/json' }, + params: {}, + body: { + JSON: { + data: [ + { + tracker_id: trackerId, + adv: advertiserId, + currency: 'USD', + order_id: '40684e8f0eaf000000000000', + event_name: 'purchase', + value: 50, + items: [ + { + item_code: '622c6f5d5cf86a4c77358033', + name: 'Cones of Dunshire', + price: 40, + position: 1, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + item_code: '577c6f5d5cf86a4c7735ba03', + name: 'Five Crowns', + price: 5, + position: 2, + category: 'Games', + }, + ], + checkout_id: '70324a1f0eaf000000000000', + affiliation: 'Vandelay Games', + total: 52.0, + subtotal: 45.0, + shipping: 4.0, + tax: 3.0, + discount: 5.0, + coupon: 'NEWCUST5', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: destType, + description: 'Custom event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 'custom event abc', + properties: { + key1: 'value1', + value: 25, + product_id: 'prd123', + key2: true, + test: 'test123', + }, + }, + destination: overrideDestination(sampleDestination, { + customProperties: [ + { + rudderProperty: 'properties.key1', + tradeDeskProperty: 'td1', + }, + { + rudderProperty: 'properties.key2', + tradeDeskProperty: 'td2', + }, + ], + }), + metadata: { + jobId: 1, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insight.adsrvr.org/track/realtimeconversion', + headers: { 'Content-Type': 'application/json' }, + params: {}, + body: { + JSON: { + data: [ + { + tracker_id: trackerId, + adv: advertiserId, + event_name: 'custom event abc', + value: 25, + product_id: 'prd123', + test: 'test123', + td1: 'value1', + td2: true, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: destType, + description: 'Mapped standard trade desk event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 'custom event abc', + properties: { + key1: 'value1', + value: 25, + product_id: 'prd123', + key2: true, + test: 'test123', + }, + }, + destination: overrideDestination(sampleDestination, { + eventsMapping: [ + { + from: 'custom event abc', + to: 'direction', + }, + ], + }), + metadata: { + jobId: 1, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insight.adsrvr.org/track/realtimeconversion', + headers: { 'Content-Type': 'application/json' }, + params: {}, + body: { + JSON: { + data: [ + { + tracker_id: trackerId, + adv: advertiserId, + event_name: 'direction', + value: 25, + product_id: 'prd123', + test: 'test123', + key1: 'value1', + key2: true, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/tiktok_ads/dataDelivery/business.ts b/test/integrations/destinations/tiktok_ads/dataDelivery/business.ts new file mode 100644 index 00000000000..895188fa3f6 --- /dev/null +++ b/test/integrations/destinations/tiktok_ads/dataDelivery/business.ts @@ -0,0 +1,249 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; + +export const commonHeaderPart = { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', +}; + +export const params = { + destination: 'tiktok_ads', +}; + +export const statTags = { + destType: 'TIKTOK_ADS', + errorCategory: 'network', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', +}; + +export const commonParts = { + context: { + ad: { + callback: '123ATXSfe', + }, + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + external_id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + phone_number: '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + ip: '13.57.97.131', + user_agent: 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + partner_name: 'RudderStack', + event: 'CompletePayment', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', +}; + +export const V1BusinessTestScenarion: ProxyV1TestData[] = [ + { + id: 'tiktok_ads_business_0', + name: 'tiktok_ads', + description: '[Business]:: Test for tiktok_ads with multiple contents in properties', + feature: 'dataDelivery', + scenario: 'business', + successCriteria: 'Should return 200 after successfully sending the request', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: { + ...commonHeaderPart, + 'test-dest-response-key': 'successResponse', + }, + params, + endpoint: 'https://business-api.tiktok.com/open_api/v1.2/pixel/batch/', + JSON: { + ...commonParts, + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + }, + }, + [generateMetadata(1234)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: '[TIKTOK_ADS Response Handler] - Request Processed Successfully', + response: [ + { + error: '{"code":0,"message":"OK"}', + statusCode: 200, + metadata: generateMetadata(1234), + }, + ], + }, + }, + }, + }, + }, + { + id: 'tiktok_ads_business_1', + name: 'tiktok_ads', + description: + '[Business]:: Test for tiktok_ads with multiple contents in properties but content_id is not a string', + feature: 'dataDelivery', + scenario: 'business', + successCriteria: 'Should return 400 after successfully processing the request with code 40002', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + params, + headers: { + ...commonHeaderPart, + 'test-dest-response-key': 'invalidDataTypeResponse', + }, + endpoint: 'https://business-api.tiktok.com/open_api/v1.2/pixel/batch/', + JSON: { + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: 1077218, + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: 1197218, + }, + ], + currency: 'USD', + value: 46, + }, + ...commonParts, + }, + }, + [generateMetadata(1234)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'Request failed with status: 40002', + response: [ + { + statusCode: 400, + error: + '{"code":40002,"message":"Batch.0.properties.contents.0.content_id: Not a valid string"}', + metadata: generateMetadata(1234), + }, + ], + statTags, + }, + }, + }, + }, + }, + { + id: 'tiktok_ads_business_2', + name: 'tiktok_ads', + description: '[Business]:: Test for tiktok_ads with wrong pixel code', + feature: 'dataDelivery', + scenario: 'business', + successCriteria: 'Should return 400 after successfully processing the request with code 40001', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + params, + endpoint: 'https://business-api.tiktok.com/open_api/v1.2/pixel/batch/', + headers: { + ...commonHeaderPart, + 'test-dest-response-key': 'invalidPermissionsResponse', + }, + JSON: { + ...commonParts, + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: 1077218, + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: 1197218, + }, + ], + currency: 'USD', + value: 46, + }, + }, + }, + [generateMetadata(1234)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 400, + message: 'Request failed with status: 40001', + response: [ + { + statusCode: 400, + error: + '{"code":40001,"message":"No permission to operate pixel code: BU35TSQHT2A1QT375OMG. You must be an admin or operator of this advertiser account."}', + metadata: generateMetadata(1234), + }, + ], + statTags, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/tiktok_ads/dataDelivery/data.ts b/test/integrations/destinations/tiktok_ads/dataDelivery/data.ts index 810e1de4756..399fd26649a 100644 --- a/test/integrations/destinations/tiktok_ads/dataDelivery/data.ts +++ b/test/integrations/destinations/tiktok_ads/dataDelivery/data.ts @@ -1,8 +1,10 @@ import { AxiosError } from 'axios'; import MockAxiosAdapter from 'axios-mock-adapter'; import lodash from 'lodash'; +import { V1BusinessTestScenarion } from './business'; +import { v1OtherScenarios } from './other'; -export const data = [ +const oldV0TestCases = [ { name: 'tiktok_ads', description: 'Test 0', @@ -670,3 +672,5 @@ export const data = [ }, }, ]; + +export const data = [...oldV0TestCases, ...V1BusinessTestScenarion, ...v1OtherScenarios]; diff --git a/test/integrations/destinations/tiktok_ads/dataDelivery/other.ts b/test/integrations/destinations/tiktok_ads/dataDelivery/other.ts new file mode 100644 index 00000000000..0675ebcd051 --- /dev/null +++ b/test/integrations/destinations/tiktok_ads/dataDelivery/other.ts @@ -0,0 +1,175 @@ +import { ProxyV1TestData } from '../../../testTypes'; +import { generateMetadata, generateProxyV1Payload } from '../../../testUtils'; +import { commonHeaderPart, params, statTags, commonParts } from './business'; + +const commonProperties = { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: 1077218, + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: 1197218, + }, + ], + currency: 'USD', + value: 46, +}; + +export const v1OtherScenarios: ProxyV1TestData[] = [ + { + id: 'tiktok_ads_other_0', + name: 'tiktok_ads', + description: '[Other]:: Test for tiktok_ads when rate limit is reached', + feature: 'dataDelivery', + scenario: 'other', + successCriteria: 'Should return 429 after successfully sending the request', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + params, + endpoint: 'https://business-api.tiktok.com/open_api/v1.2/pixel/batch/', + headers: { ...commonHeaderPart, 'test-dest-response-key': 'tooManyRequests' }, + JSON: { + ...commonParts, + properties: commonProperties, + }, + }, + [generateMetadata(1234)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 429, + message: 'Request failed with status: 40100', + response: [ + { + error: '{"code":40100,"message":"Too many requests. Please retry in some time."}', + statusCode: 429, + metadata: generateMetadata(1234), + }, + ], + statTags: { + ...statTags, + errorType: 'throttled', + }, + }, + }, + }, + }, + }, + { + id: 'tiktok_ads_other_1', + name: 'tiktok_ads', + description: '[Other]:: Test for tiktok_ads when request failed due to bad gateway', + feature: 'dataDelivery', + scenario: 'other', + successCriteria: 'Should return 500 status code after successfully sending the request', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + params, + endpoint: 'https://business-api.tiktok.com/open_api/v1.2/pixel/batch/', + headers: { ...commonHeaderPart, 'test-dest-response-key': '502-BadGateway' }, + JSON: { + ...commonParts, + properties: commonProperties, + }, + }, + [generateMetadata(1234)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 502, + message: 'Request failed with status: 502', + response: [ + { + error: + '"\\r\\n502 Bad Gateway\\r\\n\\r\\n

502 Bad Gateway

\\r\\n
nginx
\\r\\n\\r\\n\\r\\n"', + statusCode: 502, + metadata: generateMetadata(1234), + }, + ], + statTags: { + ...statTags, + errorType: 'retryable', + }, + }, + }, + }, + }, + }, + { + id: 'tiktok_ads_other_2', + name: 'tiktok_ads', + description: + '[Other]:: Test for tiktok_ads when request failed due to unavailability of service', + feature: 'dataDelivery', + scenario: 'other', + successCriteria: 'Should return 500 status code after successfully sending the request', + module: 'destination', + version: 'v1', + input: { + request: { + body: generateProxyV1Payload( + { + headers: commonHeaderPart, + params, + endpoint: 'https://random_test_url/test_for_service_not_available', + JSON: { + ...commonParts, + properties: commonProperties, + }, + }, + [generateMetadata(1234)], + ), + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 503, + message: 'Request failed with status: 503', + response: [ + { + error: + '{"error":{"message":"Service Unavailable","description":"The server is currently unable to handle the request due to temporary overloading or maintenance of the server. Please try again later."}}', + statusCode: 503, + metadata: generateMetadata(1234), + }, + ], + statTags: { + ...statTags, + errorType: 'retryable', + }, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/tiktok_ads/processor/data.ts b/test/integrations/destinations/tiktok_ads/processor/data.ts index 9d7c3a8d109..429024b8a92 100644 --- a/test/integrations/destinations/tiktok_ads/processor/data.ts +++ b/test/integrations/destinations/tiktok_ads/processor/data.ts @@ -1369,7 +1369,7 @@ export const data = [ body: [ { statusCode: 400, - error: 'Event name is required', + error: 'Event is a required field and should be a string', statTags: { errorCategory: 'dataValidation', errorType: 'instrumentation', @@ -6055,7 +6055,7 @@ export const data = [ body: [ { statusCode: 400, - error: 'Event name is required', + error: 'Event is a required field and should be a string', statTags: { errorCategory: 'dataValidation', errorType: 'instrumentation', @@ -6870,4 +6870,152 @@ export const data = [ }, }, }, + { + name: 'tiktok_ads', + description: 'Test 46 -> V2 -> Event with no properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + traits: { + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'customEvent', + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + version: 'v2', + accessToken: 'dummyAccessToken', + pixelCode: '{{PIXEL-CODE}}', + hashUserProperties: false, + sendCustomEvents: true, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/event/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + event_source: 'web', + event_source_id: '{{PIXEL-CODE}}', + partner_name: 'RudderStack', + data: [ + { + event: 'customEvent', + event_id: '84e26acc-56a5-4835-8233-591137fca468', + event_time: 1600372167, + properties: { content_type: 'product' }, + user: { + locale: 'en-US', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Testing if the event name provided as a string or not', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + event: 123, + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: '{{PIXEL-CODE}}', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Event is a required field and should be a string', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'TIKTOK_ADS', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, ]; diff --git a/test/integrations/destinations/tiktok_ads_offline_events/processor/data.ts b/test/integrations/destinations/tiktok_ads_offline_events/processor/data.ts index 2b9341b8519..81e125eacab 100644 --- a/test/integrations/destinations/tiktok_ads_offline_events/processor/data.ts +++ b/test/integrations/destinations/tiktok_ads_offline_events/processor/data.ts @@ -614,4 +614,248 @@ export const data = [ }, }, }, + { + name: 'tiktok_ads_offline_events', + description: 'Test 7 -> `search` standard tiktok Event through event mapping from UI', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + accessToken: 'dummyAccessToken', + hashUserProperties: true, + eventsToStandard: [ + { + from: 'custom event', + to: 'Search', + }, + ], + }, + }, + message: { + type: 'track', + event: 'custom event', + sentAt: '2023-03-22T00:02:33.802Z', + traits: { + email: [ + 'efaaf5c8803af4fbf305d7a110c832673d89ed40983770329092fd04b0ba7900', + '078d6c8e19f24093368d1712d7801970467f59216f7ccc087bf81b91e0e1f68f', + ], + phone: [ + 'c4994d14e724936f1169147dddf1673a09af69b55cc54bc695dbe246bd093b05', + '078d6c8e19f24093368d1712d7801970467f59216f7ccc087bf81b91e0e1f68f', + ], + }, + userId: '60241286212', + channel: 'sources', + context: { + sources: { + job_id: '2N4WuoNQpGYmCPASUvnV86QyhY4/Syncher', + version: 'v1.20.0', + job_run_id: 'cgd4a063b2fn2e1j0q90', + task_run_id: 'cgd4a063b2fn2e1j0qa0', + }, + }, + recordId: '16322', + rudderId: '5b4ed73f-69aa-4198-88d1-3d4d509acbf1', + messageId: 'cgd4b663b2fn2e1j8th0', + timestamp: '2023-03-22T00:02:33.170Z', + properties: { + phone: 'c4994d14e724936f1169147dddf1673a09af69b55cc54bc695dbe246bd093b05', + value: 32.839999999999996, + emails: + '["efaaf5c8803af4fbf305d7a110c832673d89ed40983770329092fd04b0ba7900","078d6c8e19f24093368d1712d7801970467f59216f7ccc087bf81b91e0e1f68f","","","","","","","",""]', + eventId: '8965fb56-090f-47a5-aa7f-bbab22d9ec90', + currency: 'USD', + order_id: 60241286212, + eventSetId: '7211223771099742210', + event_name: 'CompletePayment', + }, + receivedAt: '2023-03-22T00:02:33.171Z', + request_ip: '10.7.78.187', + anonymousId: '60241286212', + originalTimestamp: '2023-03-22T00:02:33.802Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/offline/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + event_set_id: '7211223771099742210', + event_id: '8965fb56-090f-47a5-aa7f-bbab22d9ec90', + timestamp: '2023-03-22T00:02:33.170Z', + properties: { + order_id: 60241286212, + currency: 'USD', + value: 32.839999999999996, + }, + event: 'Search', + partner_name: 'RudderStack', + context: { + user: { + emails: [ + '4dc75b075057df6f6b729e74a9feed1244dcf8ceb7903eaba13203f3268ae4b9', + '77b639edeb3cd6c801ea05176b8acbfa38d5f38490b764cd0c80756d0cf9ec68', + ], + phone_numbers: [ + '28b7b205c2936d2ded022d2587fb2677a76e560e921b3ad615b739b0238baa5d', + '77b639edeb3cd6c801ea05176b8acbfa38d5f38490b764cd0c80756d0cf9ec68', + ], + }, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + event_set_id: '7211223771099742210', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads_offline_events', + description: + 'Test 8 -> `PlaceAnOrder` standard tiktok Event through event `order completed` in payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + accessToken: 'dummyAccessToken', + hashUserProperties: true, + eventsToStandard: [], + }, + }, + message: { + type: 'track', + event: 'order completed', + sentAt: '2023-03-22T00:02:33.802Z', + traits: { + email: [ + 'efaaf5c8803af4fbf305d7a110c832673d89ed40983770329092fd04b0ba7900', + '078d6c8e19f24093368d1712d7801970467f59216f7ccc087bf81b91e0e1f68f', + ], + phone: [ + 'c4994d14e724936f1169147dddf1673a09af69b55cc54bc695dbe246bd093b05', + '078d6c8e19f24093368d1712d7801970467f59216f7ccc087bf81b91e0e1f68f', + ], + }, + userId: '60241286212', + channel: 'sources', + context: { + sources: { + job_id: '2N4WuoNQpGYmCPASUvnV86QyhY4/Syncher', + version: 'v1.20.0', + job_run_id: 'cgd4a063b2fn2e1j0q90', + task_run_id: 'cgd4a063b2fn2e1j0qa0', + }, + }, + recordId: '16322', + rudderId: '5b4ed73f-69aa-4198-88d1-3d4d509acbf1', + messageId: 'cgd4b663b2fn2e1j8th0', + timestamp: '2023-03-22T00:02:33.170Z', + properties: { + phone: 'c4994d14e724936f1169147dddf1673a09af69b55cc54bc695dbe246bd093b05', + value: 32.839999999999996, + emails: + '["efaaf5c8803af4fbf305d7a110c832673d89ed40983770329092fd04b0ba7900","078d6c8e19f24093368d1712d7801970467f59216f7ccc087bf81b91e0e1f68f","","","","","","","",""]', + eventId: '8965fb56-090f-47a5-aa7f-bbab22d9ec90', + currency: 'USD', + order_id: 60241286212, + eventSetId: '7211223771099742210', + event_name: 'CompletePayment', + }, + receivedAt: '2023-03-22T00:02:33.171Z', + request_ip: '10.7.78.187', + anonymousId: '60241286212', + originalTimestamp: '2023-03-22T00:02:33.802Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/offline/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + event_set_id: '7211223771099742210', + event_id: '8965fb56-090f-47a5-aa7f-bbab22d9ec90', + timestamp: '2023-03-22T00:02:33.170Z', + properties: { + order_id: 60241286212, + currency: 'USD', + value: 32.839999999999996, + }, + event: 'PlaceAnOrder', + partner_name: 'RudderStack', + context: { + user: { + emails: [ + '4dc75b075057df6f6b729e74a9feed1244dcf8ceb7903eaba13203f3268ae4b9', + '77b639edeb3cd6c801ea05176b8acbfa38d5f38490b764cd0c80756d0cf9ec68', + ], + phone_numbers: [ + '28b7b205c2936d2ded022d2587fb2677a76e560e921b3ad615b739b0238baa5d', + '77b639edeb3cd6c801ea05176b8acbfa38d5f38490b764cd0c80756d0cf9ec68', + ], + }, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + event_set_id: '7211223771099742210', + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, ]; diff --git a/test/integrations/destinations/tiktok_audience/processor/data.ts b/test/integrations/destinations/tiktok_audience/processor/data.ts index 42f235c1a40..0395ff48e00 100644 --- a/test/integrations/destinations/tiktok_audience/processor/data.ts +++ b/test/integrations/destinations/tiktok_audience/processor/data.ts @@ -1,854 +1,746 @@ export const data = [ { - "name": "tiktok_audience", - "description": "Test 1: Containing SHA256 traits only", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ + name: 'tiktok_audience', + description: 'Test 1: Containing SHA256 traits only', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user 1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + EMAIL_SHA256: 'alex@email.com', + }, + { + EMAIL_SHA256: 'amy@abc.com', + }, + { + EMAIL_SHA256: 'van@abc.com', + }, + ], + remove: [ + { + EMAIL_SHA256: 'alex@email.com', + }, + { + EMAIL_SHA256: 'amy@abc.com', + }, + { + EMAIL_SHA256: 'van@abc.com', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + externalId: [ { - "message": { - "userId": "user 1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [ - { - "EMAIL_SHA256": "alex@email.com" - }, - { - "EMAIL_SHA256": "amy@abc.com" - }, - { - "EMAIL_SHA256": "van@abc.com" - } - ], - "remove": [ - { - "EMAIL_SHA256": "alex@email.com" - }, - { - "EMAIL_SHA256": "amy@abc.com" - }, - { - "EMAIL_SHA256": "van@abc.com" - } - ] - } - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - }, - "externalId": [ - { - "type": "TIKTOK_AUDIENCE-23856594064540489", - "identifierType": "EMAIL_SHA256" - } - ], - "destinationFields": "EMAIL_SHA256" - }, - "timestamp": "2020-02-02T00:23:09.544Z" - }, - "metadata": { - "jobId": 1, - "secret": { - "accessToken": "dummyAccessToken", - "advertiserIds": [ - "dummyAdverTiserID" - ] - } - }, - "destination": { - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - }, - "Config": { - "isHashRequired": true, - "registerDeviceOrBrowserApiKey": true, - "apiKey": "intercomApiKey", - "appId": "9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0", - "collectContext": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/segment/mapping/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "batch_data": [ - [ - { - "id": "ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b", - "audience_ids": [ - "23856594064540489" - ] - } - ], - [ - { - "id": "49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579", - "audience_ids": [ - "23856594064540489" - ] - } - ], - [ - { - "id": "2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c", - "audience_ids": [ - "23856594064540489" - ] - } - ] - ], - "id_schema": [ - "EMAIL_SHA256" - ], - "advertiser_ids": [ - "dummyAdverTiserID" - ], - "action": "add" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "jobId": 1, - "secret": { - "accessToken": "dummyAccessToken", - "advertiserIds": [ - "dummyAdverTiserID" - ] - } - }, - "statusCode": 200 + type: 'TIKTOK_AUDIENCE-23856594064540489', + identifierType: 'EMAIL_SHA256', }, - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/segment/mapping/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "batch_data": [ - [ - { - "id": "ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b", - "audience_ids": [ - "23856594064540489" - ] - } - ], - [ - { - "id": "49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579", - "audience_ids": [ - "23856594064540489" - ] - } - ], - [ - { - "id": "2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c", - "audience_ids": [ - "23856594064540489" - ] - } - ] - ], - "id_schema": [ - "EMAIL_SHA256" - ], - "advertiser_ids": [ - "dummyAdverTiserID" - ], - "action": "delete" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "jobId": 1, - "secret": { - "accessToken": "dummyAccessToken", - "advertiserIds": [ - "dummyAdverTiserID" - ] - } - }, - "statusCode": 200 - } - ] - } - } + ], + destinationFields: 'EMAIL_SHA256', + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + metadata: { + jobId: 1, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/segment/mapping/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + batch_data: [ + [ + { + id: 'ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c', + audience_ids: ['23856594064540489'], + }, + ], + ], + id_schema: ['EMAIL_SHA256'], + advertiser_ids: ['dummyAdverTiserID'], + action: 'add', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/segment/mapping/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + batch_data: [ + [ + { + id: 'ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c', + audience_ids: ['23856594064540489'], + }, + ], + ], + id_schema: ['EMAIL_SHA256'], + advertiser_ids: ['dummyAdverTiserID'], + action: 'delete', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + statusCode: 200, + }, + ], + }, + }, }, { - "name": "tiktok_audience", - "description": "Test 2: Containing SHA256 and MD5 traits", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "userId": "user 1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [ - { - "EMAIL_SHA256": "alex@email.com", - "AAID_MD5": "1234567" - }, - { - "EMAIL_SHA256": "amy@abc.com", - "AAID_MD5": "1234568" - }, - { - "EMAIL_SHA256": "van@abc.com", - "AAID_MD5": "1234569" - } - ], - "remove": [ - { - "EMAIL_SHA256": "alex@email.com", - "AAID_MD5": "1234570" - }, - { - "EMAIL_SHA256": "amy@abc.com", - "AAID_MD5": "1234571" - }, - { - "EMAIL_SHA256": "van@abc.com", - "AAID_MD5": "1234572" - } - ] - } - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - }, - "externalId": [ - { - "type": "TIKTOK_AUDIENCE-23856594064540489", - "identifierType": "EMAIL_SHA256" - } - ], - "destinationFields": "EMAIL_SHA256, AAID_MD5" - }, - "timestamp": "2020-02-02T00:23:09.544Z" - }, - "metadata": { - "jobId": 1, - "secret": { - "accessToken": "dummyAccessToken", - "advertiserIds": [ - "dummyAdverTiserID" - ] - } - }, - "destination": { - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - }, - "Config": { - "isHashRequired": true, - "registerDeviceOrBrowserApiKey": true, - "apiKey": "intercomApiKey", - "appId": "9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0", - "collectContext": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ + name: 'tiktok_audience', + description: 'Test 2: Containing SHA256 and MD5 traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user 1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + EMAIL_SHA256: 'alex@email.com', + AAID_MD5: '1234567', + }, + { + EMAIL_SHA256: 'amy@abc.com', + AAID_MD5: '1234568', + }, + { + EMAIL_SHA256: 'van@abc.com', + AAID_MD5: '1234569', + }, + ], + remove: [ + { + EMAIL_SHA256: 'alex@email.com', + AAID_MD5: '1234570', + }, + { + EMAIL_SHA256: 'amy@abc.com', + AAID_MD5: '1234571', + }, + { + EMAIL_SHA256: 'van@abc.com', + AAID_MD5: '1234572', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + externalId: [ { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/segment/mapping/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "batch_data": [ - [ - { - "id": "ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b", - "audience_ids": [ - "23856594064540489" - ] - }, - { - "id": "fcea920f7412b5da7be0cf42b8c93759", - "audience_ids": [ - "23856594064540489" - ] - } - ], - [ - { - "id": "49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579", - "audience_ids": [ - "23856594064540489" - ] - }, - { - "id": "fe743d8d97aa7dfc6c93ccdc2e749513", - "audience_ids": [ - "23856594064540489" - ] - } - ], - [ - { - "id": "2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c", - "audience_ids": [ - "23856594064540489" - ] - }, - { - "id": "e36a2f90240e9e84483504fd4a704452", - "audience_ids": [ - "23856594064540489" - ] - } - ] - ], - "id_schema": [ - "EMAIL_SHA256", - "AAID_MD5" - ], - "advertiser_ids": [ - "dummyAdverTiserID" - ], - "action": "add" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "jobId": 1, - "secret": { - "accessToken": "dummyAccessToken", - "advertiserIds": [ - "dummyAdverTiserID" - ] - } - }, - "statusCode": 200 + type: 'TIKTOK_AUDIENCE-23856594064540489', + identifierType: 'EMAIL_SHA256', }, - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/segment/mapping/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "batch_data": [ - [ - { - "id": "ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b", - "audience_ids": [ - "23856594064540489" - ] - }, - { - "id": "c1abd65fea29d573ddef1bce925e3276", - "audience_ids": [ - "23856594064540489" - ] - } - ], - [ - { - "id": "49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579", - "audience_ids": [ - "23856594064540489" - ] - }, - { - "id": "7298110702a080dfc6903f13333eb04a", - "audience_ids": [ - "23856594064540489" - ] - } - ], - [ - { - "id": "2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c", - "audience_ids": [ - "23856594064540489" - ] - }, - { - "id": "d9cb68b1fd3b9d32abc5f4cab8b42b68", - "audience_ids": [ - "23856594064540489" - ] - } - ] - ], - "id_schema": [ - "EMAIL_SHA256", - "AAID_MD5" - ], - "advertiser_ids": [ - "dummyAdverTiserID" - ], - "action": "delete" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "jobId": 1, - "secret": { - "accessToken": "dummyAccessToken", - "advertiserIds": [ - "dummyAdverTiserID" - ] - } - }, - "statusCode": 200 - } - ] - } - } + ], + destinationFields: 'EMAIL_SHA256, AAID_MD5', + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + metadata: { + jobId: 1, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/segment/mapping/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + batch_data: [ + [ + { + id: 'ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b', + audience_ids: ['23856594064540489'], + }, + { + id: 'fcea920f7412b5da7be0cf42b8c93759', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579', + audience_ids: ['23856594064540489'], + }, + { + id: 'fe743d8d97aa7dfc6c93ccdc2e749513', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c', + audience_ids: ['23856594064540489'], + }, + { + id: 'e36a2f90240e9e84483504fd4a704452', + audience_ids: ['23856594064540489'], + }, + ], + ], + id_schema: ['EMAIL_SHA256', 'AAID_MD5'], + advertiser_ids: ['dummyAdverTiserID'], + action: 'add', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/segment/mapping/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + batch_data: [ + [ + { + id: 'ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b', + audience_ids: ['23856594064540489'], + }, + { + id: 'c1abd65fea29d573ddef1bce925e3276', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579', + audience_ids: ['23856594064540489'], + }, + { + id: '7298110702a080dfc6903f13333eb04a', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c', + audience_ids: ['23856594064540489'], + }, + { + id: 'd9cb68b1fd3b9d32abc5f4cab8b42b68', + audience_ids: ['23856594064540489'], + }, + ], + ], + id_schema: ['EMAIL_SHA256', 'AAID_MD5'], + advertiser_ids: ['dummyAdverTiserID'], + action: 'delete', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + statusCode: 200, + }, + ], + }, + }, }, { - "name": "tiktok_audience", - "description": "Test 3: Containing all possible traits", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ + name: 'tiktok_audience', + description: 'Test 3: Containing all possible traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user 1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + EMAIL_SHA256: 'alex@email.com', + PHONE_SHA256: '+129988776655', + IDFA_SHA256: '1234lkasfjdalj12321', + AAID_SHA256: '000999OOOQQQQ', + AAID_MD5: '000999OOOQQQQ', + IDFA_MD5: '1234lkasfjdalj12321', + }, + { + EMAIL_SHA256: 'amy@abc.com', + PHONE_SHA256: '+129988776677', + IDFA_SHA256: '1234lkasfjdalj114455', + AAID_SHA256: '000999OOOPPPP', + AAID_MD5: '000999OOOPPPP', + IDFA_MD5: '1234lkasfjdalj114455', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + externalId: [ { - "message": { - "userId": "user 1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [ - { - "EMAIL_SHA256": "alex@email.com", - "PHONE_SHA256": "+129988776655", - "IDFA_SHA256": "1234lkasfjdalj12321", - "AAID_SHA256": "000999OOOQQQQ", - "AAID_MD5": "000999OOOQQQQ", - "IDFA_MD5": "1234lkasfjdalj12321" - }, - { - "EMAIL_SHA256": "amy@abc.com", - "PHONE_SHA256": "+129988776677", - "IDFA_SHA256": "1234lkasfjdalj114455", - "AAID_SHA256": "000999OOOPPPP", - "AAID_MD5": "000999OOOPPPP", - "IDFA_MD5": "1234lkasfjdalj114455" - } - ] - } - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - }, - "externalId": [ - { - "type": "TIKTOK_AUDIENCE-23856594064540489", - "identifierType": "EMAIL_SHA256" - } - ], - "destinationFields": "EMAIL_SHA256, PHONE_SHA256, IDFA_SHA256, AAID_SHA256, AAID_MD, IDFA_MD5" - }, - "timestamp": "2020-02-02T00:23:09.544Z" - }, - "metadata": { - "jobId": 1, - "secret": { - "accessToken": "dummyAccessToken", - "advertiserIds": [ - "dummyAdverTiserID" - ] - } - }, - "destination": { - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - }, - "Config": { - "isHashRequired": true, - "registerDeviceOrBrowserApiKey": true, - "apiKey": "intercomApiKey", - "appId": "9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0", - "collectContext": false - } - } - } - ] - } + type: 'TIKTOK_AUDIENCE-23856594064540489', + identifierType: 'EMAIL_SHA256', + }, + ], + destinationFields: + 'EMAIL_SHA256, PHONE_SHA256, IDFA_SHA256, AAID_SHA256, AAID_MD, IDFA_MD5', + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + metadata: { + jobId: 1, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/segment/mapping/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "batch_data": [ - [ - { - "id": "ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b", - "audience_ids": [ - "23856594064540489" - ] - }, - { - "id": "31e78a3bf9ce2b43316f64fe883a531d6266938091e94e2f2480272481163dee", - "audience_ids": [ - "23856594064540489" - ] - }, - { - "id": "0259f595f7172c8dd692a5c37b4d296939555f862aae8adb964391bdb65006ab", - "audience_ids": [ - "23856594064540489" - ] - }, - { - "id": "b06fbe7a29f33576a792ba3df3c9bf838cd26ea88cf574285fa60dc0234a8485", - "audience_ids": [ - "23856594064540489" - ] - }, - {}, - { - "id": "32ee3d063320815a13e0058c2498ff76", - "audience_ids": [ - "23856594064540489" - ] - } - ], - [ - { - "id": "49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579", - "audience_ids": [ - "23856594064540489" - ] - }, - { - "id": "fb40adc7debbf40e7b45b0a4a91886785dff1a28809276f95f1c44f7045f9b4d", - "audience_ids": [ - "23856594064540489" - ] - }, - { - "id": "e6bbdf34c5f3472f31b2923a26811560a599233f3dea4c9971595c3bb7b1e8dc", - "audience_ids": [ - "23856594064540489" - ] - }, - { - "id": "661125f7d337811256c5b55996b22c89047804dcec494db72659e4be71e03091", - "audience_ids": [ - "23856594064540489" - ] - }, - {}, - { - "id": "94162773066d6ae88b2658dc58ca2317", - "audience_ids": [ - "23856594064540489" - ] - } - ] - ], - "id_schema": [ - "EMAIL_SHA256", - "PHONE_SHA256", - "IDFA_SHA256", - "AAID_SHA256", - "AAID_MD", - "IDFA_MD5" - ], - "advertiser_ids": [ - "dummyAdverTiserID" - ], - "action": "add" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "jobId": 1, - "secret": { - "accessToken": "dummyAccessToken", - "advertiserIds": [ - "dummyAdverTiserID" - ] - } - }, - "statusCode": 200 - } - ] - } - } + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/segment/mapping/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + batch_data: [ + [ + { + id: 'ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b', + audience_ids: ['23856594064540489'], + }, + { + id: '31e78a3bf9ce2b43316f64fe883a531d6266938091e94e2f2480272481163dee', + audience_ids: ['23856594064540489'], + }, + { + id: '0259f595f7172c8dd692a5c37b4d296939555f862aae8adb964391bdb65006ab', + audience_ids: ['23856594064540489'], + }, + { + id: 'b06fbe7a29f33576a792ba3df3c9bf838cd26ea88cf574285fa60dc0234a8485', + audience_ids: ['23856594064540489'], + }, + {}, + { + id: '32ee3d063320815a13e0058c2498ff76', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579', + audience_ids: ['23856594064540489'], + }, + { + id: 'fb40adc7debbf40e7b45b0a4a91886785dff1a28809276f95f1c44f7045f9b4d', + audience_ids: ['23856594064540489'], + }, + { + id: 'e6bbdf34c5f3472f31b2923a26811560a599233f3dea4c9971595c3bb7b1e8dc', + audience_ids: ['23856594064540489'], + }, + { + id: '661125f7d337811256c5b55996b22c89047804dcec494db72659e4be71e03091', + audience_ids: ['23856594064540489'], + }, + {}, + { + id: '94162773066d6ae88b2658dc58ca2317', + audience_ids: ['23856594064540489'], + }, + ], + ], + id_schema: [ + 'EMAIL_SHA256', + 'PHONE_SHA256', + 'IDFA_SHA256', + 'AAID_SHA256', + 'AAID_MD', + 'IDFA_MD5', + ], + advertiser_ids: ['dummyAdverTiserID'], + action: 'add', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + statusCode: 200, + }, + ], + }, + }, }, { - "name": "tiktok_audience", - "description": "Test 4: Considering some null values", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ + name: 'tiktok_audience', + description: 'Test 4: Considering some null values', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user 1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + EMAIL_SHA256: 'alex@email.com', + PHONE_SHA256: '+129988776655', + AAID_MD5: '000999OOOQQQQ', + IDFA_MD5: '1234lkasfjdalj12321', + }, + { + EMAIL_SHA256: 'amy@abc.com', + AAID_SHA256: '000999OOOPPPP', + AAID_MD5: '000999OOOPPPP', + IDFA_MD5: '1234lkasfjdalj114455', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + externalId: [ { - "message": { - "userId": "user 1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [ - { - "EMAIL_SHA256": "alex@email.com", - "PHONE_SHA256": "+129988776655", - "AAID_MD5": "000999OOOQQQQ", - "IDFA_MD5": "1234lkasfjdalj12321" - }, - { - "EMAIL_SHA256": "amy@abc.com", - "AAID_SHA256": "000999OOOPPPP", - "AAID_MD5": "000999OOOPPPP", - "IDFA_MD5": "1234lkasfjdalj114455" - } - ] - } - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - }, - "externalId": [ - { - "type": "TIKTOK_AUDIENCE-23856594064540489", - "identifierType": "EMAIL_SHA256" - } - ], - "destinationFields": "EMAIL_SHA256, PHONE_SHA256, IDFA_SHA256, AAID_SHA256, AAID_MD, IDFA_MD5" - }, - "timestamp": "2020-02-02T00:23:09.544Z" - }, - "metadata": { - "jobId": 1, - "secret": { - "accessToken": "dummyAccessToken", - "advertiserIds": [ - "dummyAdverTiserID" - ] - } - }, - "destination": { - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - }, - "Config": { - "isHashRequired": true, - "registerDeviceOrBrowserApiKey": true, - "apiKey": "intercomApiKey", - "appId": "9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0", - "collectContext": false - } - } - } - ] - } + type: 'TIKTOK_AUDIENCE-23856594064540489', + identifierType: 'EMAIL_SHA256', + }, + ], + destinationFields: + 'EMAIL_SHA256, PHONE_SHA256, IDFA_SHA256, AAID_SHA256, AAID_MD, IDFA_MD5', + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + metadata: { + jobId: 1, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + }, + ], }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/segment/mapping/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "batch_data": [ - [ - { - "id": "ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b", - "audience_ids": [ - "23856594064540489" - ] - }, - { - "id": "31e78a3bf9ce2b43316f64fe883a531d6266938091e94e2f2480272481163dee", - "audience_ids": [ - "23856594064540489" - ] - }, - {}, - {}, - {}, - { - "id": "32ee3d063320815a13e0058c2498ff76", - "audience_ids": [ - "23856594064540489" - ] - } - ], - [ - { - "id": "49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579", - "audience_ids": [ - "23856594064540489" - ] - }, - {}, - {}, - { - "id": "661125f7d337811256c5b55996b22c89047804dcec494db72659e4be71e03091", - "audience_ids": [ - "23856594064540489" - ] - }, - {}, - { - "id": "94162773066d6ae88b2658dc58ca2317", - "audience_ids": [ - "23856594064540489" - ] - } - ] - ], - "id_schema": [ - "EMAIL_SHA256", - "PHONE_SHA256", - "IDFA_SHA256", - "AAID_SHA256", - "AAID_MD", - "IDFA_MD5" - ], - "advertiser_ids": [ - "dummyAdverTiserID" - ], - "action": "add" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "metadata": { - "jobId": 1, - "secret": { - "accessToken": "dummyAccessToken", - "advertiserIds": [ - "dummyAdverTiserID" - ] - } - }, - "statusCode": 200 - } - ] - } - } - } -] + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/segment/mapping/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + batch_data: [ + [ + { + id: 'ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b', + audience_ids: ['23856594064540489'], + }, + { + id: '31e78a3bf9ce2b43316f64fe883a531d6266938091e94e2f2480272481163dee', + audience_ids: ['23856594064540489'], + }, + {}, + {}, + {}, + { + id: '32ee3d063320815a13e0058c2498ff76', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579', + audience_ids: ['23856594064540489'], + }, + {}, + {}, + { + id: '661125f7d337811256c5b55996b22c89047804dcec494db72659e4be71e03091', + audience_ids: ['23856594064540489'], + }, + {}, + { + id: '94162773066d6ae88b2658dc58ca2317', + audience_ids: ['23856594064540489'], + }, + ], + ], + id_schema: [ + 'EMAIL_SHA256', + 'PHONE_SHA256', + 'IDFA_SHA256', + 'AAID_SHA256', + 'AAID_MD', + 'IDFA_MD5', + ], + advertiser_ids: ['dummyAdverTiserID'], + action: 'add', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + jobId: 1, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/vero/processor/data.ts b/test/integrations/destinations/vero/processor/data.ts index 3f8c750da69..cf210f38be7 100644 --- a/test/integrations/destinations/vero/processor/data.ts +++ b/test/integrations/destinations/vero/processor/data.ts @@ -1,818 +1,808 @@ export const data = [ - { - "name": "vero", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "authToken": "testAuthToken" - } - }, - "message": { - "context": { - "traits": { - "homwTown": "kanpur", - "age": "24" - } - }, - "type": "Identify", - "userId": "yash001", - "originalTimestamp": "2019-10-14T09:03:17.562Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getvero.com/api/v2/users/track", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "id": "yash001", - "data": { - "homwTown": "kanpur", - "age": "24" - }, - "auth_token": "testAuthToken" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "vero", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "authToken": "testAuthToken" - } - }, - "message": { - "context": { - "traits": { - "email": "user1001@tech.com" - } - }, - "type": "Identify", - "userId": "user1001" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getvero.com/api/v2/users/track", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "id": "user1001", - "email": "user1001@tech.com", - "data": {}, - "auth_token": "testAuthToken" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "vero", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "authToken": "testAuthToken" - } - }, - "message": { - "context": { - "traits": { - "email": "user1002@tech.com" - } - }, - "type": "Identify", - "anonymousId": "b4ffheww8eisndbdjgdewifewfgerwibderv" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getvero.com/api/v2/users/track", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "id": "b4ffheww8eisndbdjgdewifewfgerwibderv", - "email": "user1002@tech.com", - "data": {}, - "auth_token": "testAuthToken" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "vero", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "authToken": "testAuthToken" - } - }, - "message": { - "context": { - "traits": { - "address": "Caravela Beach Goa", - "homwTown": "Mawsynram", - "email": "user1005@tech.com" - } - }, - "integrations": { - "vero": { - "tags": { - "add": [ - "a", - "b" - ] - } - } - }, - "type": "Identify", - "userId": "fprediruser001" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getvero.com/api/v2/users/track", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "id": "fprediruser001", - "email": "user1005@tech.com", - "data": { - "address": "Caravela Beach Goa", - "homwTown": "Mawsynram" - }, - "auth_token": "testAuthToken" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - }, - { - "output": { - "version": "1", - "type": "REST", - "method": "PUT", - "endpoint": "https://api.getvero.com/api/v2/users/tags/edit", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "id": "fprediruser001", - "auth_token": "testAuthToken", - "add": [ - "a", - "b" - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "vero", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "authToken": "testAuthToken" - } - }, - "message": { - "event": "Random event with nonexisting userId and email", - "properties": { - "movieWatched": 3, - "gamesPlayed": 4, - "email": "eventIdn01@sample.com" - }, - "type": "track", - "userId": "eventIdn01" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getvero.com/api/v2/events/track", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "identity": { - "id": "eventIdn01", - "email": "eventIdn01@sample.com" - }, - "event_name": "Random event with nonexisting userId and email", - "data": { - "movieWatched": 3, - "gamesPlayed": 4, - "email": "eventIdn01@sample.com" - }, - "auth_token": "testAuthToken" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "vero", - "description": "Test 5", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "authToken": "testAuthToken" - } - }, - "message": { - "event": "Random event with existing userId and some tags removed", - "properties": { - "movieWatched": 3, - "gamesPlayed": 4, - "email": "eventIdn01@sample.com" - }, - "integrations": { - "Vero": { - "tags": { - "remove": [ - "a" - ] - } - } - }, - "type": "track", - "userId": "fprediruser001" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getvero.com/api/v2/events/track", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "identity": { - "id": "fprediruser001", - "email": "eventIdn01@sample.com" - }, - "event_name": "Random event with existing userId and some tags removed", - "data": { - "movieWatched": 3, - "gamesPlayed": 4, - "email": "eventIdn01@sample.com" - }, - "auth_token": "testAuthToken" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - }, - { - "output": { - "version": "1", - "type": "REST", - "method": "PUT", - "endpoint": "https://api.getvero.com/api/v2/users/tags/edit", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "id": "fprediruser001", - "auth_token": "testAuthToken", - "remove": [ - "a" - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "vero", - "description": "Test 6", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "authToken": "testAuthToken" - } - }, - "message": { - "type": "alias", - "userId": "sample101", - "previousId": "newsamplel01" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "PUT", - "endpoint": "https://api.getvero.com/api/v2/users/reidentify", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "new_id": "sample101", - "id": "newsamplel01", - "auth_token": "testAuthToken" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "vero", - "description": "Test 7", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "authToken": "testAuthToken" - } - }, - "message": { - "context": { - "traits": { - "email": "user1001@tech.com" - }, - "os": { - "name": "android" - }, - "device": { - "token": "qwertyuioiuytrewwertyu", - "name": "Mi" - } - }, - "type": "Identify", - "userId": "user1001" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getvero.com/api/v2/users/track", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "id": "user1001", - "email": "user1001@tech.com", - "data": {}, - "channels": { - "platform": "android", - "address": "qwertyuioiuytrewwertyu", - "device": "Mi", - "type": "push" - }, - "auth_token": "testAuthToken" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "vero", - "description": "Test 8", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "authToken": "testAuthToken" - } - }, - "message": { - "context": { - "traits": { - "email": "user1001@tech.com" - }, - "device": { - "token": "qwertyuioiuytrewwertyu", - "name": "Mi" - } - }, - "type": "Identify", - "userId": "user1001" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getvero.com/api/v2/users/track", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "id": "user1001", - "email": "user1001@tech.com", - "data": {}, - "auth_token": "testAuthToken" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "vero", - "description": "Test 9", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "authToken": "testAuthToken" - } - }, - "message": { - "event": "unsubscribe", - "type": "track", - "userId": "eventIdn01" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getvero.com/api/v2/users/unsubscribe", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "id": "eventIdn01", - "auth_token": "testAuthToken" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "vero", - "description": "Test 10", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "authToken": "testAuthToken" - } - }, - "message": { - "name": "Rudderstack", - "properties": { - "title": "rudderstack", - "path": "/" - }, - "type": "page", - "userId": "eventIdn01" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.getvero.com/api/v2/events/track", - "headers": {}, - "params": {}, - "body": { - "JSON": { - "identity": { - "id": "eventIdn01" - }, - "event_name": "Viewed Rudderstack Page", - "data": { - "title": "rudderstack", - "path": "/" - }, - "auth_token": "testAuthToken" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "vero", - "description": "Test 11", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "authToken": "testAuthToken" - } - }, - "message": { - "groupId": "1234", - "traits": { - "name": "MyGroup", - "industry": "IT", - "employees": 450, - "plan": "basic" - }, - "type": "group", - "userId": "eventIdn01" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "Event type group is not supported", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "VERO", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - } -] + { + name: 'vero', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + authToken: 'testAuthToken', + }, + }, + message: { + context: { + traits: { + homwTown: 'kanpur', + age: '24', + }, + }, + type: 'Identify', + userId: 'yash001', + originalTimestamp: '2019-10-14T09:03:17.562Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getvero.com/api/v2/users/track', + headers: {}, + params: {}, + body: { + JSON: { + id: 'yash001', + data: { + homwTown: 'kanpur', + age: '24', + }, + auth_token: 'testAuthToken', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'vero', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + authToken: 'testAuthToken', + }, + }, + message: { + context: { + traits: { + email: 'user1001@tech.com', + }, + }, + type: 'Identify', + userId: 'user1001', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getvero.com/api/v2/users/track', + headers: {}, + params: {}, + body: { + JSON: { + id: 'user1001', + email: 'user1001@tech.com', + data: {}, + auth_token: 'testAuthToken', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'vero', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + authToken: 'testAuthToken', + }, + }, + message: { + context: { + traits: { + email: 'user1002@tech.com', + }, + }, + type: 'Identify', + anonymousId: 'b4ffheww8eisndbdjgdewifewfgerwibderv', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getvero.com/api/v2/users/track', + headers: {}, + params: {}, + body: { + JSON: { + id: 'b4ffheww8eisndbdjgdewifewfgerwibderv', + email: 'user1002@tech.com', + data: {}, + auth_token: 'testAuthToken', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'vero', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + authToken: 'testAuthToken', + }, + }, + message: { + context: { + traits: { + address: 'Caravela Beach Goa', + homwTown: 'Mawsynram', + email: 'user1005@tech.com', + }, + }, + integrations: { + vero: { + tags: { + add: ['a', 'b'], + }, + }, + }, + type: 'Identify', + userId: 'fprediruser001', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getvero.com/api/v2/users/track', + headers: {}, + params: {}, + body: { + JSON: { + id: 'fprediruser001', + email: 'user1005@tech.com', + data: { + address: 'Caravela Beach Goa', + homwTown: 'Mawsynram', + }, + auth_token: 'testAuthToken', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'PUT', + endpoint: 'https://api.getvero.com/api/v2/users/tags/edit', + headers: {}, + params: {}, + body: { + JSON: { + id: 'fprediruser001', + auth_token: 'testAuthToken', + add: ['a', 'b'], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'vero', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + authToken: 'testAuthToken', + }, + }, + message: { + event: 'Random event with nonexisting userId and email', + properties: { + movieWatched: 3, + gamesPlayed: 4, + email: 'eventIdn01@sample.com', + }, + type: 'track', + userId: 'eventIdn01', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getvero.com/api/v2/events/track', + headers: {}, + params: {}, + body: { + JSON: { + identity: { + id: 'eventIdn01', + email: 'eventIdn01@sample.com', + }, + event_name: 'Random event with nonexisting userId and email', + data: { + movieWatched: 3, + gamesPlayed: 4, + email: 'eventIdn01@sample.com', + }, + auth_token: 'testAuthToken', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'vero', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + authToken: 'testAuthToken', + }, + }, + message: { + event: 'Random event with existing userId and some tags removed', + properties: { + movieWatched: 3, + gamesPlayed: 4, + email: 'eventIdn01@sample.com', + }, + integrations: { + Vero: { + tags: { + remove: ['a'], + }, + }, + }, + type: 'track', + userId: 'fprediruser001', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getvero.com/api/v2/events/track', + headers: {}, + params: {}, + body: { + JSON: { + identity: { + id: 'fprediruser001', + email: 'eventIdn01@sample.com', + }, + event_name: 'Random event with existing userId and some tags removed', + data: { + movieWatched: 3, + gamesPlayed: 4, + email: 'eventIdn01@sample.com', + }, + auth_token: 'testAuthToken', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'PUT', + endpoint: 'https://api.getvero.com/api/v2/users/tags/edit', + headers: {}, + params: {}, + body: { + JSON: { + id: 'fprediruser001', + auth_token: 'testAuthToken', + remove: ['a'], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'vero', + description: 'Test 6', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + authToken: 'testAuthToken', + }, + }, + message: { + type: 'alias', + userId: 'sample101', + previousId: 'newsamplel01', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'PUT', + endpoint: 'https://api.getvero.com/api/v2/users/reidentify', + headers: {}, + params: {}, + body: { + JSON: { + new_id: 'sample101', + id: 'newsamplel01', + auth_token: 'testAuthToken', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'vero', + description: 'Test 7', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + authToken: 'testAuthToken', + }, + }, + message: { + context: { + traits: { + email: 'user1001@tech.com', + }, + os: { + name: 'android', + }, + device: { + token: 'qwertyuioiuytrewwertyu', + name: 'Mi', + }, + }, + type: 'Identify', + userId: 'user1001', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getvero.com/api/v2/users/track', + headers: {}, + params: {}, + body: { + JSON: { + id: 'user1001', + email: 'user1001@tech.com', + data: {}, + channels: { + platform: 'android', + address: 'qwertyuioiuytrewwertyu', + device: 'Mi', + type: 'push', + }, + auth_token: 'testAuthToken', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'vero', + description: 'Test 8', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + authToken: 'testAuthToken', + }, + }, + message: { + context: { + traits: { + email: 'user1001@tech.com', + }, + device: { + token: 'qwertyuioiuytrewwertyu', + name: 'Mi', + }, + }, + type: 'Identify', + userId: 'user1001', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getvero.com/api/v2/users/track', + headers: {}, + params: {}, + body: { + JSON: { + id: 'user1001', + email: 'user1001@tech.com', + data: {}, + auth_token: 'testAuthToken', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'vero', + description: 'Test 9', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + authToken: 'testAuthToken', + }, + }, + message: { + event: 'unsubscribe', + type: 'track', + userId: 'eventIdn01', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getvero.com/api/v2/users/unsubscribe', + headers: {}, + params: {}, + body: { + JSON: { + id: 'eventIdn01', + auth_token: 'testAuthToken', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'vero', + description: 'Test 10', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + authToken: 'testAuthToken', + }, + }, + message: { + name: 'Rudderstack', + properties: { + title: 'rudderstack', + path: '/', + }, + type: 'page', + userId: 'eventIdn01', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.getvero.com/api/v2/events/track', + headers: {}, + params: {}, + body: { + JSON: { + identity: { + id: 'eventIdn01', + }, + event_name: 'Viewed Rudderstack Page', + data: { + title: 'rudderstack', + path: '/', + }, + auth_token: 'testAuthToken', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'vero', + description: 'Test 11', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + authToken: 'testAuthToken', + }, + }, + message: { + groupId: '1234', + traits: { + name: 'MyGroup', + industry: 'IT', + employees: 450, + plan: 'basic', + }, + type: 'group', + userId: 'eventIdn01', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Event type group is not supported', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'VERO', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/webhook/processor/data.ts b/test/integrations/destinations/webhook/processor/data.ts index dbe83a79a51..e9629041fe7 100644 --- a/test/integrations/destinations/webhook/processor/data.ts +++ b/test/integrations/destinations/webhook/processor/data.ts @@ -2758,4 +2758,221 @@ export const data = [ }, }, }, + { + name: 'webhook', + description: 'Test POST method with track message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + level: 1, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + headers: [ + { + from: 'Content-Type', + to: 'application/xml', + }, + { + from: 'test2', + to: 'value2', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + level: 1, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'POST', + endpoint: 'http://6b0e6a60.ngrok.io', + headers: { + 'content-type': 'application/xml', + test2: 'value2', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test method PATCH', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + prop1: 1, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + user_properties: { + coin_balance: 9466052, + }, + }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + webhookMethod: 'PATCH', + headers: [ + { + from: 'test2', + to: 'value2', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + prop1: 1, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + user_properties: { + coin_balance: 9466052, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'PATCH', + endpoint: 'http://6b0e6a60.ngrok.io', + headers: { + 'content-type': 'application/json', + test2: 'value2', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, ]; diff --git a/test/integrations/destinations/webhook/router/data.ts b/test/integrations/destinations/webhook/router/data.ts index a082eb12f17..6c738ee8a77 100644 --- a/test/integrations/destinations/webhook/router/data.ts +++ b/test/integrations/destinations/webhook/router/data.ts @@ -419,4 +419,391 @@ export const data = [ }, }, }, + { + name: 'webhook', + description: 'Identify payload with 3 events in 1 batch', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + anonymousId: '234234234234234', + channel: 'mobile', + context: { + app: { + build: '1', + name: 'AMTestProject', + namespace: 'com.rudderstack.android.rudderstack.sampleAndroidApp', + version: '1.0', + }, + device: { + id: '8d872292709c6fbe', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'android', + }, + library: { + name: 'com.rudderstack.android.sdk.core', + version: '1.0.2', + }, + locale: 'en-US', + network: { + carrier: 'Android', + bluetooth: false, + cellular: true, + wifi: true, + }, + os: { + name: 'Android', + version: '9', + }, + screen: { + density: 420, + height: 1794, + width: 1080, + }, + timezone: 'Asia/Kolkata', + traits: { + address: { + city: 'Kolkata', + country: 'India', + postalcode: '700096', + state: 'West bengal', + street: 'Park Street', + }, + age: '30', + anonymousId: '8d872292709c6fbe', + birthday: '2020-05-26', + createdat: '18th March 2020', + description: 'Premium User for 3 years', + email: 'identify@test.com', + firstname: 'John', + userId: 'sample_user_id', + lastname: 'Sparrow', + name: 'John Sparrow', + id: 'sample_user_id', + phone: '9876543210', + username: 'john_sparrow', + quantity: '5', + price: '56.0', + }, + userAgent: + 'Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)', + }, + event: 'identify', + integrations: { + All: true, + }, + messageId: '1590431830865-3be680d6-7dcd-4b05-8460-f3acc30046d9', + originalTimestamp: '2020-05-25T18:37:10.865Z', + sentAt: '2020-05-25T18:37:10.917Z', + type: 'identify', + userId: 'sample_user_id', + }, + metadata: { jobId: 2, userId: 'u1' }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + headers: [ + { from: '', to: '' }, + { from: 'test2', to: 'value2' }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + }, + { + message: { + anonymousId: '1231241234123', + channel: 'mobile', + context: { + timezone: 'Asia/Kolkata', + traits: { + address: { + city: 'Kolkata', + country: 'India', + postalcode: '700096', + state: 'West bengal', + street: 'Park Street', + }, + age: '30', + anonymousId: '8d872292709c6fbe', + birthday: '2020-05-26', + createdat: '18th March 2020', + description: 'Premium User for 3 years', + email: 'identify2@test.com', + firstname: 'John', + userId: 'sample_user_id', + lastname: 'Sparrow', + name: 'John Sparrow', + id: 'sample_user_id', + phone: '9876543210', + username: 'john_sparrow', + quantity: '5', + price: '56.0', + }, + userAgent: + 'Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)', + }, + event: 'identify', + integrations: { + All: true, + }, + messageId: '23432324-3be680d6-7dcd-4b05-8460-f3acc30046d9', + type: 'identify', + userId: 'sample_user_id', + }, + metadata: { jobId: 3, userId: 'u1' }, + destination: { + Config: { webhookUrl: 'https://6b0e6a60.ngrok.io/n' }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + }, + { + message: { + anonymousId: '345345435', + channel: 'mobile', + event: 'identify', + integrations: { + All: true, + }, + messageId: '23432324-3be680d6-7dcd-4b05-8460-f3acc30046d9', + type: 'identify', + userId: 'sample_user_id', + }, + metadata: { jobId: 4, userId: 'u1' }, + destination: { + Config: { webhookUrl: 'https://6b0e6a60.ngrok.io/n' }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + }, + ], + destType: 'webhook', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: { + body: { + XML: {}, + JSON_ARRAY: {}, + JSON: { + anonymousId: '234234234234234', + channel: 'mobile', + context: { + app: { + build: '1', + name: 'AMTestProject', + namespace: 'com.rudderstack.android.rudderstack.sampleAndroidApp', + version: '1.0', + }, + device: { + id: '8d872292709c6fbe', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'android', + }, + library: { + name: 'com.rudderstack.android.sdk.core', + version: '1.0.2', + }, + locale: 'en-US', + network: { + carrier: 'Android', + bluetooth: false, + cellular: true, + wifi: true, + }, + os: { + name: 'Android', + version: '9', + }, + screen: { + density: 420, + height: 1794, + width: 1080, + }, + timezone: 'Asia/Kolkata', + traits: { + address: { + city: 'Kolkata', + country: 'India', + postalcode: '700096', + state: 'West bengal', + street: 'Park Street', + }, + age: '30', + anonymousId: '8d872292709c6fbe', + birthday: '2020-05-26', + createdat: '18th March 2020', + description: 'Premium User for 3 years', + email: 'identify@test.com', + firstname: 'John', + userId: 'sample_user_id', + lastname: 'Sparrow', + name: 'John Sparrow', + id: 'sample_user_id', + phone: '9876543210', + username: 'john_sparrow', + quantity: '5', + price: '56.0', + }, + userAgent: + 'Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)', + }, + event: 'identify', + integrations: { + All: true, + }, + messageId: '1590431830865-3be680d6-7dcd-4b05-8460-f3acc30046d9', + originalTimestamp: '2020-05-25T18:37:10.865Z', + sentAt: '2020-05-25T18:37:10.917Z', + type: 'identify', + userId: 'sample_user_id', + }, + FORM: {}, + }, + files: {}, + endpoint: 'http://6b0e6a60.ngrok.io', + userId: '234234234234234', + headers: { 'content-type': 'application/json', test2: 'value2' }, + version: '1', + params: {}, + type: 'REST', + method: 'POST', + }, + metadata: [{ jobId: 2, userId: 'u1' }], + batched: false, + statusCode: 200, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + headers: [ + { from: '', to: '' }, + { from: 'test2', to: 'value2' }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + }, + { + batchedRequest: { + body: { + XML: {}, + JSON_ARRAY: {}, + JSON: { + anonymousId: '1231241234123', + channel: 'mobile', + context: { + timezone: 'Asia/Kolkata', + traits: { + address: { + city: 'Kolkata', + country: 'India', + postalcode: '700096', + state: 'West bengal', + street: 'Park Street', + }, + age: '30', + anonymousId: '8d872292709c6fbe', + birthday: '2020-05-26', + createdat: '18th March 2020', + description: 'Premium User for 3 years', + email: 'identify2@test.com', + firstname: 'John', + userId: 'sample_user_id', + lastname: 'Sparrow', + name: 'John Sparrow', + id: 'sample_user_id', + phone: '9876543210', + username: 'john_sparrow', + quantity: '5', + price: '56.0', + }, + userAgent: + 'Dalvik/2.1.0 (Linux; U; Android 9; AOSP on IA Emulator Build/PSR1.180720.117)', + }, + event: 'identify', + integrations: { + All: true, + }, + messageId: '23432324-3be680d6-7dcd-4b05-8460-f3acc30046d9', + type: 'identify', + userId: 'sample_user_id', + }, + FORM: {}, + }, + files: {}, + endpoint: 'https://6b0e6a60.ngrok.io/n', + userId: '1231241234123', + headers: { 'content-type': 'application/json' }, + version: '1', + params: {}, + type: 'REST', + method: 'POST', + }, + metadata: [{ jobId: 3, userId: 'u1' }], + batched: false, + statusCode: 200, + destination: { + Config: { + webhookUrl: 'https://6b0e6a60.ngrok.io/n', + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + }, + { + batchedRequest: { + body: { + XML: {}, + JSON_ARRAY: {}, + JSON: { + anonymousId: '345345435', + channel: 'mobile', + event: 'identify', + integrations: { + All: true, + }, + messageId: '23432324-3be680d6-7dcd-4b05-8460-f3acc30046d9', + type: 'identify', + userId: 'sample_user_id', + }, + FORM: {}, + }, + files: {}, + endpoint: 'https://6b0e6a60.ngrok.io/n', + userId: '345345435', + headers: { 'content-type': 'application/json' }, + version: '1', + params: {}, + type: 'REST', + method: 'POST', + }, + metadata: [{ jobId: 4, userId: 'u1' }], + batched: false, + statusCode: 200, + destination: { + Config: { + webhookUrl: 'https://6b0e6a60.ngrok.io/n', + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + }, + ], + }, + }, + }, + }, ]; diff --git a/test/integrations/destinations/wootric/network.ts b/test/integrations/destinations/wootric/network.ts index 2407efa62bc..1b51cc700c2 100644 --- a/test/integrations/destinations/wootric/network.ts +++ b/test/integrations/destinations/wootric/network.ts @@ -1,183 +1,182 @@ export const networkCallsData = [ - { - httpReq: { - url: 'https://api.wootric.com/v1/end_users/dummyId1?lookup_by_external_id=true', - method: 'GET', - }, - httpRes: { - status: 200, - data: { - "id": 486438462, - "created_at": "2022-08-10 11:39:50 -0700", - "updated_at": "2022-08-10 11:39:50 -0700", - "email": "dummyuser1@gmail.com", - "last_surveyed": "2022-01-20 05:39:21 -0800", - "external_created_at": 1611149961, - "last_seen_at": null, - "properties": { - "city": "Mumbai", - "name": "Dummy User 1", - "title": "SDE", - "gender": "Male", - "company": "Rudderstack" - }, - "phone_number": "+19123456789", - "external_id": "dummyId1", - "last_response": null, - "settings": { - "email_nps": true, - "mobile_nps": true, - "web_nps": true, - "force_mobile_survey": null, - "force_web_survey": null, - "surveys_disabled_by_end_user": null - } - }, - }, + { + httpReq: { + url: 'https://api.wootric.com/v1/end_users/dummyId1?lookup_by_external_id=true', + method: 'GET', }, - { - httpReq: { - url: 'https://api.wootric.com/v1/end_users/exclueFunTestId?lookup_by_external_id=true', - method: 'GET', - }, - httpRes: { - status: 200, - data: { - "id": 486336190, - "created_at": "2022-08-10 07:30:50 -0700", - "updated_at": "2022-08-10 10:12:46 -0700", - "email": "excludeUser@gmail.com", - "last_surveyed": "2022-01-20 05:39:21 -0800", - "external_created_at": 1579755367, - "last_seen_at": null, - "properties": { - "city": "Mumbai", - "name": "exclude test user", - "email": "excludeUser@gmail.com", - "title": "AD", - "gender": "Male", - "company": "Rockstar" - }, - "phone_number": "+18324671283", - "external_id": "exclueFunTestId", - "last_response": null, - "settings": { - "email_nps": true, - "mobile_nps": true, - "web_nps": true, - "force_mobile_survey": null, - "force_web_survey": null, - "surveys_disabled_by_end_user": null - } - }, - }, + httpRes: { + status: 200, + data: { + id: 486438462, + created_at: '2022-08-10 11:39:50 -0700', + updated_at: '2022-08-10 11:39:50 -0700', + email: 'dummyuser1@gmail.com', + last_surveyed: '2022-01-20 05:39:21 -0800', + external_created_at: 1611149961, + last_seen_at: null, + properties: { + city: 'Mumbai', + name: 'Dummy User 1', + title: 'SDE', + gender: 'Male', + company: 'Rudderstack', + }, + phone_number: '+19123456789', + external_id: 'dummyId1', + last_response: null, + settings: { + email_nps: true, + mobile_nps: true, + web_nps: true, + force_mobile_survey: null, + force_web_survey: null, + surveys_disabled_by_end_user: null, + }, + }, }, - { - httpReq: { - url: 'https://api.wootric.com/v1/end_users/my-external-id-1234?lookup_by_external_id=true', - method: 'POST', - - }, - httpRes: { - status: 200, - data: { - "type": "error_list", - "errors": [ - { - "status": "record_not_found", - "message": "The record could not be found", - "field": null - } - ] - } - }, + }, + { + httpReq: { + url: 'https://api.wootric.com/v1/end_users/exclueFunTestId?lookup_by_external_id=true', + method: 'GET', }, - { - httpReq: { - url: 'https://api.wootric.com/v1/end_users/490635419', - method: 'GET' - }, - httpRes: { - data: { - "id": 490635419, - "created_at": "2022-08-20 00:55:26 -0700", - "updated_at": "2022-08-22 11:17:05 -0700", - "email": "firstuser@gmail.com", - "last_surveyed": "2022-08-01 00:11:44 -0700", - "external_created_at": 1661002761, - "last_seen_at": null, - "properties": { - "Department": "Marketing", - "product_plan": "Web", - "revenue amount": "5000" - }, - "phone_number": "+8859133456781", - "external_id": "firstUserId123", - "last_response": { - "id": 101013218, - "score": 9, - "text": "Good !!!", - "survey": { - "channel": "web" - } - }, - "settings": { - "email_nps": true, - "mobile_nps": true, - "web_nps": true, - "force_mobile_survey": null, - "force_web_survey": null, - "surveys_disabled_by_end_user": null - } - }, - status: 200, - }, + httpRes: { + status: 200, + data: { + id: 486336190, + created_at: '2022-08-10 07:30:50 -0700', + updated_at: '2022-08-10 10:12:46 -0700', + email: 'excludeUser@gmail.com', + last_surveyed: '2022-01-20 05:39:21 -0800', + external_created_at: 1579755367, + last_seen_at: null, + properties: { + city: 'Mumbai', + name: 'exclude test user', + email: 'excludeUser@gmail.com', + title: 'AD', + gender: 'Male', + company: 'Rockstar', + }, + phone_number: '+18324671283', + external_id: 'exclueFunTestId', + last_response: null, + settings: { + email_nps: true, + mobile_nps: true, + web_nps: true, + force_mobile_survey: null, + force_web_survey: null, + surveys_disabled_by_end_user: null, + }, + }, }, - { - httpReq: { - url: 'https://api.wootric.com/oauth/token?account_token=NPS-dummyToken', - method: 'POST' - }, - httpRes: { - data: { - "access_token": "2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c", - "token_type": "Bearer", - "expires_in": 7200, - "refresh_token": "f4033a61742e84405a5ef8b2e09b82395dc041f0259fd5fb715fc196a1b9cd52", - "scope": "delete_account admin respond export read survey invalidate_response", - "created_at": 1660292389 - }, - status: 200, - }, + }, + { + httpReq: { + url: 'https://api.wootric.com/v1/end_users/my-external-id-1234?lookup_by_external_id=true', + method: 'POST', }, - { - httpReq: { - url: 'https://api.wootric.com/v1/end_users/dummyId2?lookup_by_external_id=true', - method: 'GET' - }, - httpRes: { - status: 200, - }, + httpRes: { + status: 200, + data: { + type: 'error_list', + errors: [ + { + status: 'record_not_found', + message: 'The record could not be found', + field: null, + }, + ], + }, }, - { - httpReq: { - url: 'https://api.wootric.com/v1/end_users/12345', - method: 'GET' - }, - httpRes: { - status: 200, - }, + }, + { + httpReq: { + url: 'https://api.wootric.com/v1/end_users/490635419', + method: 'GET', }, - { - httpReq: { - url: 'https://api.wootric.com/oauth/token?account_token=NPS-dummyToken12', - method: 'POST' - }, - httpRes: { - data: { - error: "Not found", - status: 404 - } - }, - } + httpRes: { + data: { + id: 490635419, + created_at: '2022-08-20 00:55:26 -0700', + updated_at: '2022-08-22 11:17:05 -0700', + email: 'firstuser@gmail.com', + last_surveyed: '2022-08-01 00:11:44 -0700', + external_created_at: 1661002761, + last_seen_at: null, + properties: { + Department: 'Marketing', + product_plan: 'Web', + 'revenue amount': '5000', + }, + phone_number: '+8859133456781', + external_id: 'firstUserId123', + last_response: { + id: 101013218, + score: 9, + text: 'Good !!!', + survey: { + channel: 'web', + }, + }, + settings: { + email_nps: true, + mobile_nps: true, + web_nps: true, + force_mobile_survey: null, + force_web_survey: null, + surveys_disabled_by_end_user: null, + }, + }, + status: 200, + }, + }, + { + httpReq: { + url: 'https://api.wootric.com/oauth/token?account_token=NPS-dummyToken', + method: 'POST', + }, + httpRes: { + data: { + access_token: '2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c', + token_type: 'Bearer', + expires_in: 7200, + refresh_token: 'f4033a61742e84405a5ef8b2e09b82395dc041f0259fd5fb715fc196a1b9cd52', + scope: 'delete_account admin respond export read survey invalidate_response', + created_at: 1660292389, + }, + status: 200, + }, + }, + { + httpReq: { + url: 'https://api.wootric.com/v1/end_users/dummyId2?lookup_by_external_id=true', + method: 'GET', + }, + httpRes: { + status: 200, + }, + }, + { + httpReq: { + url: 'https://api.wootric.com/v1/end_users/12345', + method: 'GET', + }, + httpRes: { + status: 200, + }, + }, + { + httpReq: { + url: 'https://api.wootric.com/oauth/token?account_token=NPS-dummyToken12', + method: 'POST', + }, + httpRes: { + data: { + error: 'Not found', + status: 404, + }, + }, + }, ]; diff --git a/test/integrations/destinations/wootric/processor/data.ts b/test/integrations/destinations/wootric/processor/data.ts index d94901fe805..ae747e982d5 100644 --- a/test/integrations/destinations/wootric/processor/data.ts +++ b/test/integrations/destinations/wootric/processor/data.ts @@ -1,1825 +1,1852 @@ export const data = [ - { - "name": "wootric", - "description": "Wrong Account Token Passed", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken12" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "identify", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId2", - "channel": "web", - "context": {}, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "{\"message\":\"Access token could not be generated due to {\\\"error\\\":\\\"Not found\\\",\\\"status\\\":404}\",\"destinationResponse\":{\"response\":{\"error\":\"Not found\",\"status\":404},\"status\":500}}", - "statTags": { - "destType": "WOOTRIC", - "errorCategory": "network", - "errorType": "retryable", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 500 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Identify call for creating user", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "identify", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId2", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "traits": { - "city": "Bangalore", - "name": "Dummy User 2", - "email": "dummyUser2@gmail.com", - "phone": "+19123456777", - "title": "SDE", - "gender": "Male", - "company": "Rudderstack", - "createdAt": "2021-01-20T13:39:21.032Z" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.wootric.com/v1/end_users", - "headers": { - "Content-Type": "application/x-www-form-urlencoded", - "Authorization": "Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": { - "email": "dummyUser2@gmail.com", - "phone_number": "+19123456777", - "last_surveyed": "1642685961", - "external_created_at": "1611149961", - "external_id": "dummyId2", - "properties[city]": "Bangalore", - "properties[name]": "Dummy User 2", - "properties[title]": "SDE", - "properties[gender]": "Male", - "properties[company]": "Rudderstack" - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Identify call for creating user without-sending email and sending phone number", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "identify", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId2", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "traits": { - "city": "Bangalore", - "name": "Dummy User 2", - "phone": "+19123456777", - "title": "SDE", - "gender": "Male", - "company": "Rudderstack", - "createdAt": "2021-01-20T13:39:21.032Z" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.wootric.com/v1/end_users", - "headers": { - "Content-Type": "application/x-www-form-urlencoded", - "Authorization": "Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": { - "phone_number": "+19123456777", - "last_surveyed": "1642685961", - "external_created_at": "1611149961", - "external_id": "dummyId2", - "properties[city]": "Bangalore", - "properties[name]": "Dummy User 2", - "properties[title]": "SDE", - "properties[gender]": "Male", - "properties[company]": "Rudderstack" - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Identify call for creating user without-sending phone number and sending email", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "identify", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId2", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "traits": { - "email": "dummyUser2@gmail.com", - "city": "Bangalore", - "name": "Dummy User 2", - "title": "SDE", - "gender": "Male", - "company": "Rudderstack", - "createdAt": "2021-01-20T13:39:21.032Z" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.wootric.com/v1/end_users", - "headers": { - "Content-Type": "application/x-www-form-urlencoded", - "Authorization": "Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": { - "email": "dummyUser2@gmail.com", - "last_surveyed": "1642685961", - "external_created_at": "1611149961", - "external_id": "dummyId2", - "properties[city]": "Bangalore", - "properties[name]": "Dummy User 2", - "properties[title]": "SDE", - "properties[gender]": "Male", - "properties[company]": "Rudderstack" - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Identify call for creating user without sending traits", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "identify", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId2", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "email/phone number are missing. At least one parameter must be provided", - "statTags": { - "destType": "WOOTRIC", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Identify call for creating user without-sending (email and phone number)", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "identify", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId2", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "traits": { - "city": "Mumbai", - "name": "Dummy User 1", - "title": "SDE", - "gender": "Male", - "company": "Rudderstack", - "createdAt": "2021-01-20T13:39:21.032Z" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "email/phone number are missing. At least one parameter must be provided", - "statTags": { - "destType": "WOOTRIC", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Identify call for updating existing user with wootric end user id", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "identify", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId1", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "traits": { - "title": "VP", - "gender": "Male" - }, - "externalId": [ - { - "type": "wootricEndUserId", - "id": "490635419" - } - ], - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "PUT", - "endpoint": "https://api.wootric.com/v1/end_users/490635419", - "headers": { - "Content-Type": "application/x-www-form-urlencoded", - "Authorization": "Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": { - "last_surveyed": "1642685961", - "properties[Department]": "Marketing", - "properties[product_plan]": "Web", - "properties[revenue amount]": "5000", - "properties[title]": "VP", - "properties[gender]": "Male" - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Identify call for updating existing user with (wootric externalId/ rudderstack userId)", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "identify", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId1", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "traits": { - "title": "VP", - "gender": "Male" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "PUT", - "endpoint": "https://api.wootric.com/v1/end_users/486438462", - "headers": { - "Content-Type": "application/x-www-form-urlencoded", - "Authorization": "Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": { - "last_surveyed": "1642685961", - "properties[title]": "VP", - "properties[gender]": "Male", - "properties[city]": "Mumbai", - "properties[name]": "Dummy User 1", - "properties[company]": "Rudderstack" - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Identify call for updating user traits/properties", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "identify", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId1", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "traits": { - "city": "Udaipur", - "name": "Dummy User 1 New", - "title": "SDE-2", - "gender": "Male", - "company": "Rudderstack" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "PUT", - "endpoint": "https://api.wootric.com/v1/end_users/486438462", - "headers": { - "Content-Type": "application/x-www-form-urlencoded", - "Authorization": "Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": { - "last_surveyed": "1642685961", - "properties[city]": "Udaipur", - "properties[name]": "Dummy User 1 New", - "properties[title]": "SDE-2", - "properties[gender]": "Male", - "properties[company]": "Rudderstack" - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Track call with existing userId and event type as create response", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "track", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId1", - "channel": "web", - "properties": { - "feedbackScore": 7, - "feedbackText": "Simple, Easy to use, Reliable, Affordable Product" - }, - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "ip": "0.0.0.0", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "traits": { - "city": "Mumbai", - "name": "Dummy User 1", - "email": "dummyUser1@gmail.com", - "title": "SDE", - "gender": "Male", - "company": "Rudderstack", - "createdAt": "2021-01-20T13:39:21.032Z" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true, - "Wootric": { - "eventType": "create response" - } - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.wootric.com/v1/end_users/486438462/responses", - "headers": { - "Content-Type": "application/x-www-form-urlencoded", - "Authorization": "Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": { - "score": 7, - "ip_address": "0.0.0.0", - "origin_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "text": "Simple, Easy to use, Reliable, Affordable Product", - "created_at": "1611149961", - "end_user[properties][city]": "Mumbai", - "end_user[properties][name]": "Dummy User 1", - "end_user[properties][title]": "SDE", - "end_user[properties][gender]": "Male", - "end_user[properties][company]": "Rudderstack" - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Track call with non-existing userId", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "track", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId2", - "channel": "web", - "properties": { - "feedbackScore": 7, - "feedbackText": "Simple, Easy to use, Reliable, Affordable Product" - }, - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "ip": "0.0.0.0", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true, - "Wootric": { - "eventType": "create response" - } - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "No user found with userId : dummyId2", - "statTags": { - "destType": "WOOTRIC", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Track call with non-existing wootricEndUserId", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "track", - "sentAt": "2022-01-20T13:39:21.033Z", - "channel": "web", - "properties": { - "feedbackScore": 7, - "feedbackText": "Simple, Easy to use, Reliable, Affordable Product" - }, - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "ip": "0.0.0.0", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "externalId": [ - { - "type": "wootricEndUserId", - "id": "12345" - } - ], - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true, - "Wootric": { - "eventType": "create response" - } - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "No user found with wootric end user Id : 12345", - "statTags": { - "destType": "WOOTRIC", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Track call with existing userId and event type as create response and score out of bound", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "track", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId1", - "channel": "web", - "properties": { - "feedbackScore": 12, - "feedbackText": "Simple, Easy to use, Reliable, Affordable Product" - }, - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "ip": "0.0.0.0", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true, - "Wootric": { - "eventType": "create response" - } - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Invalid Score", - "statTags": { - "destType": "WOOTRIC", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Track call with existing userId and event type as create decline", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "track", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId1", - "channel": "web", - "properties": { - "feedbackScore": 9, - "feedbackText": "Simple, Easy to use, Reliable, Affordable Product" - }, - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true, - "Wootric": { - "eventType": "create decline" - } - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://api.wootric.com/v1/end_users/486438462/declines", - "headers": { - "Content-Type": "application/x-www-form-urlencoded", - "Authorization": "Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": { - "origin_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html" - } - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Track call with non-existing userId and event type as create decline", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "track", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId2", - "channel": "web", - "properties": { - "feedbackScore": 9, - "feedbackText": "Simple, Easy to use, Reliable, Affordable Product" - }, - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true, - "Wootric": { - "eventType": "create decline" - } - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "No user found with userId : dummyId2", - "statTags": { - "destType": "WOOTRIC", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Track call with event type other than create response or decline", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "track", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId1", - "channel": "web", - "properties": { - "feedbackScore": 7, - "feedbackText": "Simple, Easy to use, Reliable, Affordable Product" - }, - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "ip": "0.0.0.0", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "traits": { - "city": "Mumbai", - "name": "Dummy User 1", - "email": "dummyUser1@gmail.com", - "phone": "+19123456789", - "title": "SDE", - "gender": "Male", - "company": "Rudderstack", - "createdAt": "2021-01-20T13:39:21.032Z" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true, - "Wootric": { - "eventType": "random" - } - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Event Type not supported", - "statTags": { - "destType": "WOOTRIC", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - }, - { - "name": "wootric", - "description": "Track call with missing event type in integration object", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "destination": { - "Config": { - "username": "wootricfakeuser@example.com", - "password": "password@123", - "accountToken": "NPS-dummyToken" - }, - "ID": "wootric-1234" - }, - "message": { - "type": "track", - "sentAt": "2022-01-20T13:39:21.033Z", - "userId": "dummyId1", - "channel": "web", - "properties": { - "feedbackScore": 3, - "feedbackText": "Too Slow!!!" - }, - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.2.20", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "path": "/Testing/App_for_LaunchDarkly/ourSdk.html", - "title": "Document", - "search": "", - "tab_url": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html", - "referrer": "http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/", - "initial_referrer": "$direct", - "referring_domain": "127.0.0.1:7307", - "initial_referring_domain": "" - }, - "locale": "en-US", - "ip": "0.0.0.0", - "screen": { - "width": 1440, - "height": 900, - "density": 2, - "innerWidth": 536, - "innerHeight": 689 - }, - "traits": { - "city": "Mumbai", - "name": "Dummy User 1", - "email": "dummyUser1@gmail.com", - "phone": "+19123456789", - "title": "SDE", - "gender": "Male", - "company": "Rudderstack", - "createdAt": "2021-01-20T13:39:21.032Z" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.2.20" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36" - }, - "rudderId": "553b5522-c575-40a7-8072-9741c5f9a647", - "messageId": "831f1fa5-de84-4f22-880a-4c3f23fc3f04", - "anonymousId": "bf412108-0357-4330-b119-7305e767823c", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-01-20T13:39:21.032Z" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "error": "Event Type is missing from Integration object", - "statTags": { - "destType": "WOOTRIC", - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "feature": "processor", - "implementation": "native", - "module": "destination" - }, - "statusCode": 400 - } - ] - } - } - } -] + { + name: 'wootric', + description: 'Wrong Account Token Passed', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken12', + }, + ID: 'wootric-1234', + }, + message: { + type: 'identify', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId2', + channel: 'web', + context: {}, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + '{"message":"Access token could not be generated due to {\\"error\\":\\"Not found\\",\\"status\\":404}","destinationResponse":{"response":{"error":"Not found","status":404},"status":500}}', + statTags: { + destType: 'WOOTRIC', + errorCategory: 'network', + errorType: 'retryable', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 500, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Identify call for creating user', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'identify', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId2', + channel: 'web', + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + traits: { + city: 'Bangalore', + name: 'Dummy User 2', + email: 'dummyUser2@gmail.com', + phone: '+19123456777', + title: 'SDE', + gender: 'Male', + company: 'Rudderstack', + createdAt: '2021-01-20T13:39:21.032Z', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.wootric.com/v1/end_users', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: + 'Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: { + email: 'dummyUser2@gmail.com', + phone_number: '+19123456777', + last_surveyed: '1642685961', + external_created_at: '1611149961', + external_id: 'dummyId2', + 'properties[city]': 'Bangalore', + 'properties[name]': 'Dummy User 2', + 'properties[title]': 'SDE', + 'properties[gender]': 'Male', + 'properties[company]': 'Rudderstack', + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Identify call for creating user without-sending email and sending phone number', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'identify', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId2', + channel: 'web', + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + traits: { + city: 'Bangalore', + name: 'Dummy User 2', + phone: '+19123456777', + title: 'SDE', + gender: 'Male', + company: 'Rudderstack', + createdAt: '2021-01-20T13:39:21.032Z', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.wootric.com/v1/end_users', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: + 'Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: { + phone_number: '+19123456777', + last_surveyed: '1642685961', + external_created_at: '1611149961', + external_id: 'dummyId2', + 'properties[city]': 'Bangalore', + 'properties[name]': 'Dummy User 2', + 'properties[title]': 'SDE', + 'properties[gender]': 'Male', + 'properties[company]': 'Rudderstack', + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Identify call for creating user without-sending phone number and sending email', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'identify', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId2', + channel: 'web', + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + traits: { + email: 'dummyUser2@gmail.com', + city: 'Bangalore', + name: 'Dummy User 2', + title: 'SDE', + gender: 'Male', + company: 'Rudderstack', + createdAt: '2021-01-20T13:39:21.032Z', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.wootric.com/v1/end_users', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: + 'Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: { + email: 'dummyUser2@gmail.com', + last_surveyed: '1642685961', + external_created_at: '1611149961', + external_id: 'dummyId2', + 'properties[city]': 'Bangalore', + 'properties[name]': 'Dummy User 2', + 'properties[title]': 'SDE', + 'properties[gender]': 'Male', + 'properties[company]': 'Rudderstack', + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Identify call for creating user without sending traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'identify', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId2', + channel: 'web', + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'email/phone number are missing. At least one parameter must be provided', + statTags: { + destType: 'WOOTRIC', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Identify call for creating user without-sending (email and phone number)', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'identify', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId2', + channel: 'web', + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + traits: { + city: 'Mumbai', + name: 'Dummy User 1', + title: 'SDE', + gender: 'Male', + company: 'Rudderstack', + createdAt: '2021-01-20T13:39:21.032Z', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'email/phone number are missing. At least one parameter must be provided', + statTags: { + destType: 'WOOTRIC', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Identify call for updating existing user with wootric end user id', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'identify', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId1', + channel: 'web', + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + traits: { + title: 'VP', + gender: 'Male', + }, + externalId: [ + { + type: 'wootricEndUserId', + id: '490635419', + }, + ], + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'PUT', + endpoint: 'https://api.wootric.com/v1/end_users/490635419', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: + 'Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: { + last_surveyed: '1642685961', + 'properties[Department]': 'Marketing', + 'properties[product_plan]': 'Web', + 'properties[revenue amount]': '5000', + 'properties[title]': 'VP', + 'properties[gender]': 'Male', + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: + 'Identify call for updating existing user with (wootric externalId/ rudderstack userId)', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'identify', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId1', + channel: 'web', + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + traits: { + title: 'VP', + gender: 'Male', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'PUT', + endpoint: 'https://api.wootric.com/v1/end_users/486438462', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: + 'Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: { + last_surveyed: '1642685961', + 'properties[title]': 'VP', + 'properties[gender]': 'Male', + 'properties[city]': 'Mumbai', + 'properties[name]': 'Dummy User 1', + 'properties[company]': 'Rudderstack', + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Identify call for updating user traits/properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'identify', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId1', + channel: 'web', + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + traits: { + city: 'Udaipur', + name: 'Dummy User 1 New', + title: 'SDE-2', + gender: 'Male', + company: 'Rudderstack', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'PUT', + endpoint: 'https://api.wootric.com/v1/end_users/486438462', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: + 'Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: { + last_surveyed: '1642685961', + 'properties[city]': 'Udaipur', + 'properties[name]': 'Dummy User 1 New', + 'properties[title]': 'SDE-2', + 'properties[gender]': 'Male', + 'properties[company]': 'Rudderstack', + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Track call with existing userId and event type as create response', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'track', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId1', + channel: 'web', + properties: { + feedbackScore: 7, + feedbackText: 'Simple, Easy to use, Reliable, Affordable Product', + }, + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + ip: '0.0.0.0', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + traits: { + city: 'Mumbai', + name: 'Dummy User 1', + email: 'dummyUser1@gmail.com', + title: 'SDE', + gender: 'Male', + company: 'Rudderstack', + createdAt: '2021-01-20T13:39:21.032Z', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + Wootric: { + eventType: 'create response', + }, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.wootric.com/v1/end_users/486438462/responses', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: + 'Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: { + score: 7, + ip_address: '0.0.0.0', + origin_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + text: 'Simple, Easy to use, Reliable, Affordable Product', + created_at: '1611149961', + 'end_user[properties][city]': 'Mumbai', + 'end_user[properties][name]': 'Dummy User 1', + 'end_user[properties][title]': 'SDE', + 'end_user[properties][gender]': 'Male', + 'end_user[properties][company]': 'Rudderstack', + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Track call with non-existing userId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'track', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId2', + channel: 'web', + properties: { + feedbackScore: 7, + feedbackText: 'Simple, Easy to use, Reliable, Affordable Product', + }, + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + ip: '0.0.0.0', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + Wootric: { + eventType: 'create response', + }, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'No user found with userId : dummyId2', + statTags: { + destType: 'WOOTRIC', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Track call with non-existing wootricEndUserId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'track', + sentAt: '2022-01-20T13:39:21.033Z', + channel: 'web', + properties: { + feedbackScore: 7, + feedbackText: 'Simple, Easy to use, Reliable, Affordable Product', + }, + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + ip: '0.0.0.0', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + externalId: [ + { + type: 'wootricEndUserId', + id: '12345', + }, + ], + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + Wootric: { + eventType: 'create response', + }, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'No user found with wootric end user Id : 12345', + statTags: { + destType: 'WOOTRIC', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: + 'Track call with existing userId and event type as create response and score out of bound', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'track', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId1', + channel: 'web', + properties: { + feedbackScore: 12, + feedbackText: 'Simple, Easy to use, Reliable, Affordable Product', + }, + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + ip: '0.0.0.0', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + Wootric: { + eventType: 'create response', + }, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Invalid Score', + statTags: { + destType: 'WOOTRIC', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Track call with existing userId and event type as create decline', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'track', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId1', + channel: 'web', + properties: { + feedbackScore: 9, + feedbackText: 'Simple, Easy to use, Reliable, Affordable Product', + }, + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + Wootric: { + eventType: 'create decline', + }, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.wootric.com/v1/end_users/486438462/declines', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: + 'Bearer 2fe581c1c72851e73d60f4191f720be93e5d3e8a6147e37c4e8e852b1a8f506c', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: { + origin_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Track call with non-existing userId and event type as create decline', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'track', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId2', + channel: 'web', + properties: { + feedbackScore: 9, + feedbackText: 'Simple, Easy to use, Reliable, Affordable Product', + }, + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + Wootric: { + eventType: 'create decline', + }, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'No user found with userId : dummyId2', + statTags: { + destType: 'WOOTRIC', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Track call with event type other than create response or decline', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'track', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId1', + channel: 'web', + properties: { + feedbackScore: 7, + feedbackText: 'Simple, Easy to use, Reliable, Affordable Product', + }, + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + ip: '0.0.0.0', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + traits: { + city: 'Mumbai', + name: 'Dummy User 1', + email: 'dummyUser1@gmail.com', + phone: '+19123456789', + title: 'SDE', + gender: 'Male', + company: 'Rudderstack', + createdAt: '2021-01-20T13:39:21.032Z', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + Wootric: { + eventType: 'random', + }, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Event Type not supported', + statTags: { + destType: 'WOOTRIC', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'wootric', + description: 'Track call with missing event type in integration object', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + username: 'wootricfakeuser@example.com', + password: 'password@123', + accountToken: 'NPS-dummyToken', + }, + ID: 'wootric-1234', + }, + message: { + type: 'track', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'dummyId1', + channel: 'web', + properties: { + feedbackScore: 3, + feedbackText: 'Too Slow!!!', + }, + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + ip: '0.0.0.0', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + traits: { + city: 'Mumbai', + name: 'Dummy User 1', + email: 'dummyUser1@gmail.com', + phone: '+19123456789', + title: 'SDE', + gender: 'Male', + company: 'Rudderstack', + createdAt: '2021-01-20T13:39:21.032Z', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Event Type is missing from Integration object', + statTags: { + destType: 'WOOTRIC', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/testTypes.ts b/test/integrations/testTypes.ts index 51667e8044b..1c5a989f44f 100644 --- a/test/integrations/testTypes.ts +++ b/test/integrations/testTypes.ts @@ -1,5 +1,13 @@ import { AxiosResponse } from 'axios'; import MockAdapter from 'axios-mock-adapter'; +import { + DeliveryV1Response, + ProcessorTransformationRequest, + ProcessorTransformationResponse, + ProxyV1Request, + RouterTransformationRequest, + RouterTransformationResponse, +} from '../../src/types'; export interface requestType { method: string; @@ -29,8 +37,12 @@ export interface mockType { } export interface TestCaseData { + id?: string; name: string; description: string; + scenario?: string; + successCriteria?: string; + comment?: string; feature: string; module: string; version?: string; @@ -44,3 +56,76 @@ export type MockHttpCallsData = { httpReq: Record; httpRes: Partial; }; + +export type ProcessorTestData = { + id: string; + name: string; + description: string; + scenario: string; + successCriteria: string; + comment?: string; + feature: string; + module: string; + version: string; + input: { + request: { + body: ProcessorTransformationRequest[]; + }; + }; + output: { + response: { + status: number; + body: ProcessorTransformationResponse[]; + }; + }; +}; +export type RouterTestData = { + id: string; + name: string; + description: string; + comment?: string; + scenario: string; + successCriteria: string; + feature: string; + module: string; + version: string; + input: { + request: { + body: RouterTransformationRequest; + }; + }; + output: { + response: { + status: number; + body: { + output: RouterTransformationResponse[]; + }; + }; + }; +}; + +export type ProxyV1TestData = { + id: string; + name: string; + description: string; + comment?: string; + scenario: string; + successCriteria: string; + feature: string; + module: string; + version: string; + input: { + request: { + body: ProxyV1Request; + method: string; + }; + }; + output: { + response: { + status: number; + body: { + output: DeliveryV1Response; + }; + }; + }; +}; diff --git a/test/integrations/testUtils.ts b/test/integrations/testUtils.ts index 09f3a82d40b..13a76702f90 100644 --- a/test/integrations/testUtils.ts +++ b/test/integrations/testUtils.ts @@ -5,6 +5,19 @@ import MockAdapter from 'axios-mock-adapter'; import isMatch from 'lodash/isMatch'; import { OptionValues } from 'commander'; import { removeUndefinedAndNullValues } from '@rudderstack/integrations-lib'; +import tags from '../../src/v0/util/tags'; +import { existsSync, mkdirSync, writeFileSync } from 'fs'; +import { Destination, ProxyMetdata, ProxyV0Request, ProxyV1Request } from '../../src/types'; +import { + DeliveryV0ResponseSchema, + DeliveryV0ResponseSchemaForOauth, + DeliveryV1ResponseSchema, + DeliveryV1ResponseSchemaForOauth, + ProcessorTransformationResponseListSchema, + ProxyV0RequestSchema, + ProxyV1RequestSchema, + RouterTransformationResponseListSchema, +} from '../../src/types/zodTypes'; const generateAlphanumericId = (size = 36) => [...Array(size)].map(() => ((Math.random() * size) | 0).toString(size)).join(''); @@ -32,13 +45,17 @@ export const getAllTestMockDataFilePaths = (dirPath: string, destination: string const globPattern = join(dirPath, '**', 'network.ts'); let testFilePaths = globSync(globPattern); if (destination) { + const commonTestFilePaths = testFilePaths.filter((testFile) => + testFile.includes('test/integrations/common'), + ); testFilePaths = testFilePaths.filter((testFile) => testFile.includes(destination)); + testFilePaths = [...commonTestFilePaths, ...testFilePaths]; } return testFilePaths; }; export const addMock = (mock: MockAdapter, axiosMock: MockHttpCallsData) => { - const { url, method, data: reqData, ...opts } = axiosMock.httpReq; + const { url, method, data: reqData, params, ...opts } = axiosMock.httpReq; const { data, headers, status } = axiosMock.httpRes; const headersAsymMatch = { @@ -49,8 +66,10 @@ export const addMock = (mock: MockAdapter, axiosMock: MockHttpCallsData) => { switch (method.toLowerCase()) { case 'get': + // We are accepting parameters exclusively for mocking purposes and do not require a request body, + // particularly for GET requests where it is typically unnecessary // @ts-ignore - mock.onGet(url, reqData, headersAsymMatch).reply(status, data, headers); + mock.onGet(url, { params }, headersAsymMatch).reply(status, data, headers); break; case 'delete': // @ts-ignore @@ -72,13 +91,56 @@ export const addMock = (mock: MockAdapter, axiosMock: MockHttpCallsData) => { break; } }; -export const overrideDestination = (destination, overrideConfigValues) => { +export const overrideDestination = (destination: Destination, overrideConfigValues) => { return Object.assign({}, destination, { Config: { ...destination.Config, ...overrideConfigValues }, }); }; -export const generateIndentifyPayload = (parametersOverride: any) => { +export const produceTestData = (testData: TestCaseData[], filterKeys = []) => { + const result: any = []; + testData.forEach((tcData) => { + let events; + try { + switch (tcData.feature) { + case tags.FEATURES.PROCESSOR: + events = tcData.input.request.body; + break; + case tags.FEATURES.BATCH: + events = tcData.input.request.body.input; + break; + case tags.FEATURES.ROUTER: + events = tcData.input.request.body.input; + break; + } + } catch (e) { + throw new Error( + `Error in producing test data for destination:${tcData.name}, id:${tcData.id}: ${e}`, + ); + } + + events.forEach((event) => { + const { message } = event; + // remove unwanted keys + filterKeys.forEach((key) => { + delete message[key]; + }); + result.push(message); + }); + }); + + // write the data to a file + + // create directory if not exists + const dir = join(__dirname, '../../temp'); + if (!existsSync(dir)) { + mkdirSync(dir); + } + writeFileSync(join(__dirname, '../../temp/test_data.json'), JSON.stringify(result, null, 2)); + console.log('Data generated successfully at temp/test_data.json'); +}; + +export const generateIndentifyPayload: any = (parametersOverride: any) => { const payload = { type: 'identify', sentAt: parametersOverride.sentAt || '2021-01-03T17:02:53.195Z', @@ -113,7 +175,7 @@ export const generateIndentifyPayload = (parametersOverride: any) => { return removeUndefinedAndNullValues(payload); }; -export const generateSimplifiedIdentifyPayload = (parametersOverride: any) => { +export const generateSimplifiedIdentifyPayload: any = (parametersOverride: any) => { return removeUndefinedAndNullValues({ type: 'identify', sentAt: parametersOverride.sentAt || '2021-01-03T17:02:53.195Z', @@ -123,7 +185,7 @@ export const generateSimplifiedIdentifyPayload = (parametersOverride: any) => { rudderId: parametersOverride.rudderId || generateAlphanumericId(36), messageId: parametersOverride.messageId || generateAlphanumericId(36), context: { - externalId: parametersOverride.externalId, + externalId: parametersOverride.context.externalId, traits: parametersOverride.context.traits, }, anonymousId: parametersOverride.anonymousId || 'default-anonymousId', @@ -131,7 +193,7 @@ export const generateSimplifiedIdentifyPayload = (parametersOverride: any) => { }); }; -export const generateTrackPayload = (parametersOverride: any) => { +export const generateTrackPayload: any = (parametersOverride: any) => { const payload = { type: 'track', sentAt: parametersOverride.sentAt || '2021-01-03T17:02:53.195Z', @@ -154,6 +216,7 @@ export const generateTrackPayload = (parametersOverride: any) => { campaign: {}, userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0', + dataProcessingOptions: parametersOverride.context.dataProcessingOptions, }), rudderId: parametersOverride.rudderId || generateAlphanumericId(36), messageId: parametersOverride.messageId || generateAlphanumericId(36), @@ -167,7 +230,7 @@ export const generateTrackPayload = (parametersOverride: any) => { return removeUndefinedAndNullValues(payload); }; -export const generateSimplifiedTrackPayload = (parametersOverride: any) => { +export const generateSimplifiedTrackPayload: any = (parametersOverride: any) => { return removeUndefinedAndNullValues({ type: 'track', sentAt: parametersOverride.sentAt || '2021-01-03T17:02:53.195Z', @@ -178,7 +241,7 @@ export const generateSimplifiedTrackPayload = (parametersOverride: any) => { rudderId: parametersOverride.rudderId || generateAlphanumericId(36), messageId: parametersOverride.messageId || generateAlphanumericId(36), context: removeUndefinedAndNullValues({ - externalId: parametersOverride.externalId, + externalId: parametersOverride.context.externalId, traits: parametersOverride.context.traits, }), anonymousId: parametersOverride.anonymousId || 'default-anonymousId', @@ -186,7 +249,7 @@ export const generateSimplifiedTrackPayload = (parametersOverride: any) => { }); }; -export const generatePageOrScreenPayload = (parametersOverride: any, eventType: string) => { +export const generatePageOrScreenPayload: any = (parametersOverride: any, eventType: string) => { const payload = { channel: 'web', userId: parametersOverride.userId || 'default-userId', @@ -239,7 +302,7 @@ export const generatePageOrScreenPayload = (parametersOverride: any, eventType: return removeUndefinedAndNullValues(payload); }; -export const generateSimplifiedPageOrScreenPayload = ( +export const generateSimplifiedPageOrScreenPayload: any = ( parametersOverride: any, eventType: string, ) => { @@ -248,6 +311,7 @@ export const generateSimplifiedPageOrScreenPayload = ( userId: parametersOverride.userId || 'default-userId', type: eventType || 'page', event: parametersOverride.event, + name: parametersOverride.name, properties: parametersOverride.properties, integrations: parametersOverride.integrations, rudderId: parametersOverride.rudderId || generateAlphanumericId(36), @@ -261,7 +325,7 @@ export const generateSimplifiedPageOrScreenPayload = ( }); }; -export const generateGroupPayload = (parametersOverride: any) => { +export const generateGroupPayload: any = (parametersOverride: any) => { const payload = { channel: 'web', context: removeUndefinedAndNullValues({ @@ -304,7 +368,7 @@ export const generateGroupPayload = (parametersOverride: any) => { return removeUndefinedAndNullValues(payload); }; -export const generateSimplifiedGroupPayload = (parametersOverride: any) => { +export const generateSimplifiedGroupPayload: any = (parametersOverride: any) => { return removeUndefinedAndNullValues({ channel: 'web', userId: parametersOverride.userId || 'default-userId', @@ -322,7 +386,7 @@ export const generateSimplifiedGroupPayload = (parametersOverride: any) => { }); }; -export const transformResultBuilder = (matchData) => { +export const transformResultBuilder: any = (matchData) => { return removeUndefinedAndNullValues({ version: '1', type: 'REST', @@ -364,3 +428,146 @@ export const compareObjects = (obj1, obj2, logPrefix = '', differences: string[] return differences; }; + +export const generateProxyV0Payload = ( + payloadParameters: any, + metadataInput?: ProxyMetdata, + destinationConfig?: any, +): ProxyV0Request => { + let metadata: ProxyMetdata = { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: false, + }; + if (metadataInput) { + metadata = metadataInput; + } + const payload = { + version: 'v0', + type: 'REST', + userId: payloadParameters.userId || 'default-userId', + method: payloadParameters.method || 'POST', + endpoint: payloadParameters.endpoint || '', + headers: payloadParameters.headers || {}, + params: payloadParameters.params || {}, + body: { + JSON: payloadParameters.JSON || {}, + JSON_ARRAY: payloadParameters.JSON_ARRAY || {}, + XML: payloadParameters.XML || {}, + FORM: payloadParameters.FORM || {}, + }, + files: payloadParameters.files || {}, + metadata, + destinationConfig: destinationConfig || {}, + }; + return removeUndefinedAndNullValues(payload) as ProxyV0Request; +}; + +export const generateProxyV1Payload = ( + payloadParameters: any, + metadataInput?: ProxyMetdata[], + destinationConfig?: any, +): ProxyV1Request => { + let metadata: ProxyMetdata[] = [ + { + jobId: 1, + attemptNum: 1, + userId: 'default-userId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + sourceId: 'default-sourceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: false, + }, + ]; + if (metadataInput) { + metadata = metadataInput; + } + const payload = { + version: 'v1', + type: 'REST', + userId: payloadParameters.userId || 'default-userId', + method: payloadParameters.method || 'POST', + endpoint: payloadParameters.endpoint || '', + headers: payloadParameters.headers || {}, + params: payloadParameters.params || {}, + body: { + JSON: payloadParameters.JSON || {}, + JSON_ARRAY: payloadParameters.JSON_ARRAY || {}, + XML: payloadParameters.XML || {}, + FORM: payloadParameters.FORM || {}, + }, + files: payloadParameters.files || {}, + metadata, + destinationConfig: destinationConfig || {}, + }; + return removeUndefinedAndNullValues(payload) as ProxyV1Request; +}; + +// ----------------------------- +// Zod validations + +export const validateTestWithZOD = (testPayload: TestCaseData, response: any) => { + // Validate the resquest payload + switch (testPayload.feature) { + case 'router': + RouterTransformationResponseListSchema.parse(response.body.output); + break; + case 'batch': + RouterTransformationResponseListSchema.parse(response.body); + break; + // case 'user_deletion': + // DeletionSchema.parse(responseBody); + // break; + case 'processor': + ProcessorTransformationResponseListSchema.parse(response.body); + break; + case 'dataDelivery': + if (testPayload.version === 'v0') { + ProxyV0RequestSchema.parse(testPayload.input.request.body); + if (testPayload.scenario === 'Oauth') { + DeliveryV0ResponseSchemaForOauth.parse(response.body.output); + } else { + DeliveryV0ResponseSchema.parse(response.body.output); + } + } else if (testPayload.version === 'v1') { + ProxyV1RequestSchema.parse(testPayload.input.request.body); + if (testPayload.scenario === 'Oauth') { + DeliveryV1ResponseSchemaForOauth.parse(response.body.output); + } else { + DeliveryV1ResponseSchema.parse(response.body.output); + } + } + break; + default: + break; + } + return true; +}; + +// ----------------------------- +// Helper functions + +export const generateMetadata = (jobId: number): any => { + return { + jobId, + attemptNum: 1, + userId: 'default-userId', + sourceId: 'default-sourceId', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', + secret: { + accessToken: 'default-accessToken', + }, + dontBatch: false, + }; +}; diff --git a/test/scripts/testDataGenerator.ts b/test/scripts/testDataGenerator.ts new file mode 100644 index 00000000000..a00e9fce324 --- /dev/null +++ b/test/scripts/testDataGenerator.ts @@ -0,0 +1,88 @@ +import path from 'path'; +import { TestCaseData } from '../integrations/testTypes'; +import { getTestData, getTestDataFilePaths, produceTestData } from '../integrations/testUtils'; +import { Command } from 'commander'; +import axios from 'axios'; +import * as fs from 'fs'; + +// Produces test data for a given destination +// Example usage +// npx ts-node test/scripts/testDataGenerator.ts --destination=klaviyo --feature=processor + +const command = new Command(); +command + .allowUnknownOption() + .option('-d, --destination ', 'Enter Destination Name') + .option('-f, --feature ', 'Enter Feature Name(processor, router)') + .option('-i, --index ', 'Enter Test index') + .option('-id, --id ', 'Enter unique "Id" of the test case you want to run') + .option('-dp, --dataPlane ', 'Enter Data Plane URL') + .option('-wk, --writeKey ', 'Enter Write Key') + .option( + '-fk, --filterKeys ', + 'Enter Keys to filter from the test data(originalTimestamp, timestamp, messageId etc)', + ) + .parse(); + +const opts = command.opts(); + +if (opts.destination === undefined) { + throw new Error('Destination is not provided'); +} + +const filterKeys = opts.filterKeys ? opts.filterKeys.split(',') : []; + +const rootDir = __dirname; +const resolvedpath = path.resolve(rootDir, '../integrations'); +const destinationTestDataPaths = getTestDataFilePaths(resolvedpath, opts); + +destinationTestDataPaths.forEach((testDataPath) => { + let testData: TestCaseData[] = getTestData(testDataPath); + if (opts.index !== undefined) { + testData = [testData[parseInt(opts.index)]]; + } + if (opts.id) { + testData = testData.filter((data) => { + if (data['id'] === opts.id) { + return true; + } + return false; + }); + } + console.log('Writing test data to ../../temp/test_data.json'); + produceTestData(testData, filterKeys); + + if (opts.dataPlane && opts.writeKey) { + // read file ../../temp/test_data.json + console.log('Sending data to data plane URL: ', opts.dataPlane); + + const resolvedpathForData = path.resolve(rootDir, '../../temp/test_data.json'); + + fs.readFile(resolvedpathForData, 'utf8', function (err, data) { + if (err) { + console.log(err); + } else { + const parsedData = JSON.parse(data); + axios + .post( + `${opts.dataPlane}/v1/batch`, + { + batch: parsedData, + }, + { + headers: { + 'Content-Type': 'application/json', + Authorization: `Basic ${Buffer.from(opts.writeKey + ':').toString('base64')}`, + }, + }, + ) + .then((response) => { + console.log(response); + }) + .catch((error) => { + console.log(error); + }); + } + }); + } +}); diff --git a/test/test_reporter/reporter.ts b/test/test_reporter/reporter.ts index 135f9803984..5741b1cdf01 100644 --- a/test/test_reporter/reporter.ts +++ b/test/test_reporter/reporter.ts @@ -125,9 +125,9 @@ export const generateTestReport = (testData, output, result) => { export const initaliseReport = () => { const htmlTemplate = generateHTMLTemplate(); - if (!fs.existsSync('test_reports')){ + if (!fs.existsSync('test_reports')) { fs.mkdirSync('test_reports'); -} + } fs.writeFileSync('test_reports/test-report.html', htmlTemplate); console.log('Report initialised'); }; diff --git a/tsconfig.json b/tsconfig.json index 9db40dd0e10..926831b6123 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,7 @@ /* Language and Environment */ "target": "ES2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, "lib": [ - "es2019" + "es2019", ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ @@ -100,8 +100,8 @@ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */, }, "exclude": ["./src/**/*.test.js", "./src/**/*.test.ts", "./test"], - "include": ["./src", "./src/**/*.json"] + "include": ["./src", "./src/**/*.json"], }