diff --git a/.circleci/config.yml b/.circleci/config.yml index 7e32aaa..4033da4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,93 +12,150 @@ version: 2.1 orbs: - android: circleci/android@2.1.2 + android: circleci/android@2.4.0 + codecov: codecov/codecov@4.0.1 # Workflows orchestrate a set of jobs to be run; workflows: version: 2 build-test-deploy: jobs: - - build-and-unit-test - - functional-test + - validate-code + - build-and-unit-test: + requires: + - validate-code + - functional-test: + requires: + - validate-code + - build-test-app: + requires: + - validate-code + filters: + branches: + only: + - main + - staging jobs: - build-and-unit-test: - working_directory: ~/code + validate-code: executor: - name: android/android-machine - resource-class: large - tag: 2021.10.1 + name: android/android-docker + resource-class: medium + tag: 2024.01.1 + steps: - checkout + + - android/restore-gradle-cache + + - android/restore-build-cache + - run: - name: Checkstyle - command: make checkstyle + name: Check Format + command: make checkformat - run: - name: Javadoc - command: make ci-javadoc + name: Check Style + command: make checkstyle + + - android/save-gradle-cache + + - android/save-build-cache + - store_artifacts: - path: ci/javadoc/build/reports + path: code/target/build/reports + build-and-unit-test: + executor: + name: android/android-docker + resource-class: medium + tag: 2024.01.1 + + steps: + - checkout - - run: - name: Build - command: make ci-build + - android/restore-gradle-cache + + - android/restore-build-cache - run: - name: UnitTests - command: make ci-unit-test + name: Javadoc + command: make javadoc + + - store_artifacts: + path: code/target/build/docs/javadoc - # code coverage - run: - name: Upload Code Coverage Report - command: | - curl -s https://codecov.io/bash > codecov; - VERSION=$(grep 'VERSION=\"[0-9\.]*\"' codecov | cut -d'"' -f2); - for i in 1 256 512 - do - shasum -a $i -c --ignore-missing <(curl -s "https://raw.githubusercontent.com/codecov/codecov-bash/${VERSION}/SHA${i}SUM") || - shasum -a $i -c <(curl -s "https://raw.githubusercontent.com/codecov/codecov-bash/${VERSION}/SHA${i}SUM" | grep -w "codecov") - done - bash ./codecov -v -X s3 -c -D "./ci/unit-test/build/reports" -F unit-tests + name: Assemble Phone + command: make assemble-phone + + - android/run-tests: + test-command: make unit-test-coverage - store_artifacts: - path: ci/unit-test/build/reports + path: code/target/build/reports/tests - store_test_results: - path: ci/unit-test/build/test-results + path: code/target/build/test-results/testPhoneDebugUnitTest + - android/save-gradle-cache + + - android/save-build-cache + + - codecov/upload: + file: code/target/build/reports/coverage/test/phone/debug/report.xml + flags: unit-tests functional-test: - executor: + executor: name: android/android-machine - resource-class: large - tag: 2021.10.1 + resource-class: medium + tag: 2024.01.1 + steps: - checkout + + - android/restore-build-cache + + - run: + name: List available emulator images + command: sdkmanager --list + - android/start-emulator-and-run-tests: # It should match the name seen in the "sdkmanager --list" output system-image: system-images;android-29;default;x86 # The command to be run, while waiting for emulator startup - post-emulator-launch-assemble-command: make ci-build + post-emulator-launch-assemble-command: make assemble-phone # The test command - test-command: make ci-functional-test - - # code coverage - - run: - name: Upload Code Coverage Report - command: | - curl -s https://codecov.io/bash > codecov; - VERSION=$(grep 'VERSION=\"[0-9\.]*\"' codecov | cut -d'"' -f2); - for i in 1 256 512 - do - shasum -a $i -c --ignore-missing <(curl -s "https://raw.githubusercontent.com/codecov/codecov-bash/${VERSION}/SHA${i}SUM") || - shasum -a $i -c <(curl -s "https://raw.githubusercontent.com/codecov/codecov-bash/${VERSION}/SHA${i}SUM" | grep -w "codecov") - done - bash ./codecov -v -X s3 -c -D "./ci/functional-test/build/reports" -F functional-tests + test-command: make functional-test-coverage + + - android/save-build-cache + - codecov/upload: + file: code/target/build/reports/coverage/androidTest/phone/debug/connected/report.xml + flags: functional-tests + - store_artifacts: - path: ci/functional-test/build/reports + path: code/target/build/reports/androidTests - store_test_results: - path: ci/functional-test/build/outputs/androidTest-results + path: code/target/build/outputs/androidTest-results + + build-test-app: + executor: + name: android/android-docker + resource-class: medium + tag: 2024.01.1 + + steps: + - checkout + + - android/restore-gradle-cache + + - android/restore-build-cache + + - run: + name: Assemble App + command: make assemble-app + + - android/save-gradle-cache + - android/save-build-cache \ No newline at end of file diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..e4a96e0 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,5 @@ +#!/bin/bash + +make format +git diff --cached --name-only --diff-filter=d | while read filename; do git add "$filename"; done + diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..79682fd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,82 @@ +# +# Copyright 2024 Adobe. All rights reserved. +# This file is licensed to you under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +# OF ANY KIND, either express or implied. See the License for the specific language +# governing permissions and limitations under the License. +# + +name: Bug report +description: Create a bug report to help us improve. Use this template if you encountered an issue while integrating with or implementing the APIs of this SDK. +labels: [bug, triage-required] + +body: +- type: checkboxes + attributes: + label: Prerequisites + description: Please check the following items before logging a new bug report. + options: + - label: This is not a Security Disclosure, otherwise please follow the guidelines in [Security Policy](https://github.com/adobe/aepsdk-target-android/security/policy). + required: true + - label: I have searched in this repository's issues to see if it has already been reported. + required: true + - label: I have updated to the latest released version of the SDK and the issue still persists. + required: true + +- type: textarea + attributes: + label: Bug summary + description: Please provide a summary of the bug you are reporting. + validations: + required: true + +- type: textarea + attributes: + label: Environment + description: | + Please provide the OS version, SDK version(s) used, IDE version, and any other specific settings that could help us narrow down the problem. + Example: + - **OS**: Android 13 + - **SDK(s)**: target 2.0.0, core 2.0.0 + - **IDE**: Android Studio 2021.3.1 Patch 1 + validations: + required: true + +- type: textarea + attributes: + label: Steps to reproduce + description: Steps to reproduce the behavior consistently. + placeholder: | + 1. ... + 2. ... + 3. ... + validations: + required: false + +- type: textarea + attributes: + label: Current behavior + description: A concise description of what you are experiencing. + validations: + required: false + +- type: textarea + attributes: + label: Expected behavior + description: A concise description of what you expected to happen. + validations: + required: false + +- type: textarea + attributes: + label: Anything else? + description: | + Here you can include sample code that illustrates the problem, logs taken while reproducing the problem, or anything that can give us more context about the issue you are encountering. + + Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..43717ea --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,55 @@ +# +# Copyright 2024 Adobe. All rights reserved. +# This file is licensed to you under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +# OF ANY KIND, either express or implied. See the License for the specific language +# governing permissions and limitations under the License. +# + +name: Feature request +description: Suggest an idea for this project. +labels: [feature-request, triage-required] + +body: +- type: checkboxes + attributes: + label: Prerequisites + description: Please check the following items before logging a new feature request. + options: + - label: This is not a Security Disclosure, otherwise please follow the guidelines in [Security Policy](https://github.com/adobe/aepsdk-target-android/security/policy). + required: true + - label: I have searched in this repository's issues to see if it has already been reported. + required: true + +- type: textarea + id: description + attributes: + label: Feature request summary + description: Please provide a summary of the feature. + validations: + required: true + +- type: textarea + attributes: + label: Current behavior + description: A concise description of what you are experiencing. + validations: + required: false + +- type: textarea + attributes: + label: Expected behavior + description: A concise description of what you expected to happen. + validations: + required: false + +- type: textarea + attributes: + label: Additional implementation details or code snippets + description: Provide additional information about this request, implementation details or code snippets. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/project_epic.yml b/.github/ISSUE_TEMPLATE/project_epic.yml new file mode 100644 index 0000000..7be5395 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/project_epic.yml @@ -0,0 +1,36 @@ +# +# Copyright 2024 Adobe. All rights reserved. +# This file is licensed to you under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +# OF ANY KIND, either express or implied. See the License for the specific language +# governing permissions and limitations under the License. +# + +name: Project epic +description: Create an internal epic that represents the top level parent of multiple tasks. +labels: [epic] + +body: +- type: textarea + id: description + attributes: + label: Epic description + description: Please provide a detailed description for this epic. + validations: + required: true + +- type: textarea + id: tasks + attributes: + label: Tasks + description: | + Provide a high-level definition of done for this epic as a list of tasks that need to be completed. + Tip: List out the task links if they already exist or list them out as text with a descriptive title so they can be easily converted to task items. + placeholder: | + - [ ] your task link here + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/project_task.yml b/.github/ISSUE_TEMPLATE/project_task.yml new file mode 100644 index 0000000..7dbe1cb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/project_task.yml @@ -0,0 +1,29 @@ +# +# Copyright 2024 Adobe. All rights reserved. +# This file is licensed to you under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +# OF ANY KIND, either express or implied. See the License for the specific language +# governing permissions and limitations under the License. +# + +name: Project task +description: Create an internal task that can be completed as a standalone code change or is part of an epic. +labels: [task] +body: +- type: textarea + attributes: + label: Task description + description: Please provide a summary or the "what" of the task logged. + validations: + required: true + +- type: textarea + attributes: + label: Additional implementation details or code snippet(s) + description: Provide additional information about this task, implementation details or code snippets. + validations: + required: false diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000..bf12cfc --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,16 @@ +# +# Copyright 2022 Adobe. All rights reserved. +# This file is licensed to you under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +# OF ANY KIND, either express or implied. See the License for the specific language +# governing permissions and limitations under the License. +# + +template: | + ## What’s Changed + + $CHANGES \ No newline at end of file diff --git a/.github/workflows/maven-release.yml b/.github/workflows/maven-release.yml index 2ef47e4..f3f4cd3 100644 --- a/.github/workflows/maven-release.yml +++ b/.github/workflows/maven-release.yml @@ -10,27 +10,55 @@ # governing permissions and limitations under the License. # -name: Publish package to the Maven Central Repository -on: - push: - branches: - - main +name: Publish Release +on: + workflow_dispatch: + inputs: + tag: + description: 'tag/version' + required: true + action_tag: + description: 'Create tag? ("no" to skip)' + required: true + default: 'yes' jobs: publish: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + - name: Set up Java - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: - java-version: 11 + distribution: 'zulu' + java-version: 17 + - name: Cache Gradle packages uses: actions/cache@v2 with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} restore-keys: ${{ runner.os }}-gradle + + - name: Verify version + run: | + set -eo pipefail + echo Release version: ${{ github.event.inputs.tag }} + (./scripts/version.sh -v ${{ github.event.inputs.tag }}) + + - name: Create GH Release + id: create_release + uses: release-drafter/release-drafter@v5 + if: ${{ github.event.inputs.action_tag == 'yes' }} + with: + name: v${{ github.event.inputs.tag }} + tag: v${{ github.event.inputs.tag }} + version: v${{ github.event.inputs.tag }} + publish: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Import GPG key env: GPG_SECRET_KEYS: ${{ secrets.GPG_SECRET_KEYS }} @@ -38,11 +66,11 @@ jobs: run: | echo $GPG_SECRET_KEYS | base64 --decode | gpg --import --no-tty --batch --yes echo $GPG_OWNERTRUST | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes - - name: Publish to maven central staging repository - run: make ci-publish-main + + - name: Publish to Maven Central Repository + run: make ci-publish env: SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} - + GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} \ No newline at end of file diff --git a/.github/workflows/maven-snapshot.yml b/.github/workflows/maven-snapshot.yml index 9b90e27..f1d68b9 100644 --- a/.github/workflows/maven-snapshot.yml +++ b/.github/workflows/maven-snapshot.yml @@ -10,21 +10,19 @@ # governing permissions and limitations under the License. # -name: Publish package to the Maven Central Repository +name: Publish Snapshot on: - push: - branches: - - staging - + workflow_dispatch: jobs: publish: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Java - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: - java-version: 11 + distribution: 'zulu' + java-version: 17 - name: Cache Gradle packages uses: actions/cache@v2 with: @@ -38,10 +36,10 @@ jobs: run: | echo $GPG_SECRET_KEYS | base64 --decode | gpg --import --no-tty --batch --yes echo $GPG_OWNERTRUST | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes - - name: Publish to maven central staging repository + - name: Publish to Maven Snapshot Repository run: make ci-publish-staging env: SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} + GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} \ No newline at end of file diff --git a/.github/workflows/update-version.yml b/.github/workflows/update-version.yml new file mode 100644 index 0000000..7403cea --- /dev/null +++ b/.github/workflows/update-version.yml @@ -0,0 +1,45 @@ +# +# Copyright 2024 Adobe. All rights reserved. +# This file is licensed to you under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +# OF ANY KIND, either express or implied. See the License for the specific language +# governing permissions and limitations under the License. +# + +name: Update Version +on: + workflow_dispatch: + inputs: + version: + description: 'New version to use for the Target extension. Example: 3.0.0' + required: true + + core-dependency: + description: '[Optional] Update Core dependency in pom.xml. Example: 3.0.0' + required: false + +jobs: + update-version: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Update Target Version + run: (./scripts/version.sh -u -v ${{ github.event.inputs.version }} -d "Core ${{ github.event.inputs.core-dependency }}") + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ github.token }} + commit-message: Updating version to ${{ github.event.inputs.version }}. + branch: version-${{ github.event.inputs.version }}-update + delete-branch: true + title: Updating version to ${{ github.event.inputs.version }} + body: Updating version to ${{ github.event.inputs.version }} + diff --git a/Documentation/api-reference.md b/Documentation/api-reference.md index ac8168e..883840a 100644 --- a/Documentation/api-reference.md +++ b/Documentation/api-reference.md @@ -13,7 +13,6 @@ Refer to the [Getting Started Guide](getting-started.md). - [getSessionId](#getSessionId) - [getThirdPartyId](#getThirdPartyId) - [prefetchContent](#prefetchContent) -- [registerExtension](#registerExtension) - [resetExperience](#resetExperience) - [retrieveLocationContent](#retrieveLocationContent) - [setPreviewRestartDeepLink](#setPreviewRestartDeepLink) @@ -279,25 +278,6 @@ TargetParamters targetParameters = null; Target.prefetchContent(prefetchMboxesList, targetParameters, prefetchStatusCallback); ``` -### registerExtension - -> **Warning** -> This API is deprecated from version 2.0.0. Please use Mobile Core's [registerExtensions](https://github.com/adobe/aepsdk-core-android/blob/main/Documentation/MobileCore/api-reference.md) API instead. - -Registers the Target extension with the Mobile Core. - -**Syntax** - -```java -public static void registerExtension() -``` - -**Example** - -```java -Target.registerExtension(); -``` - ### resetExperience This API resets the user's experience by removing the visitor identifiers and resetting the Target session. Invoking this API also removes previously set Target user ID and custom visitor IDs, Target Edge Host, and the session information from persistent storage. diff --git a/Documentation/getting-started.md b/Documentation/getting-started.md index 9b53419..2aaa078 100644 --- a/Documentation/getting-started.md +++ b/Documentation/getting-started.md @@ -27,12 +27,23 @@ To get started with Target, follow these steps: ## Add Target to your app -Add the Mobile Core and Target extensions to your project using the app's Gradle file. +Installation via [Maven](https://maven.apache.org/) & [Gradle](https://gradle.org/) is the easiest and recommended way to get the Mobile SDK. Add the Mobile Core and Target extensions to your project using the app's Gradle file. - ```java - implementation 'com.adobe.marketing.mobile:core:2.+' - implementation 'com.adobe.marketing.mobile:target:2.+' - ``` +#### Kotlin + +```kotlin + implementation(platform("com.adobe.marketing.mobile:sdk-bom:3.+")) + implementation("com.adobe.marketing.mobile:core") + implementation("com.adobe.marketing.mobile:target") +``` + +#### Groovy + +```groovy + implementation platform('com.adobe.marketing.mobile:sdk-bom:3.+') + implementation 'com.adobe.marketing.mobile:core' + implementation 'com.adobe.marketing.mobile:target' +``` > **Warning** > Using dynamic dependency versions is not recommended for production apps. Refer to this [page](https://github.com/adobe/aepsdk-core-android/blob/main/Documentation/MobileCore/gradle-dependencies.md) for managing gradle dependencies. diff --git a/Makefile b/Makefile index 3ca4641..bb4ed4f 100644 --- a/Makefile +++ b/Makefile @@ -1,63 +1,58 @@ EXTENSION-LIBRARY-FOLDER-NAME = target +TEST-APP-FOLDER-NAME = testapp -BUILD-ASSEMBLE-LOCATION = ./ci/assemble -ROOT_DIR=$(shell git rev-parse --show-toplevel) - -PROJECT_NAME = $(shell cat $(ROOT_DIR)/code/gradle.properties | grep "moduleProjectName" | cut -d'=' -f2) -AAR_NAME = $(shell cat $(ROOT_DIR)/code/gradle.properties | grep "moduleAARName" | cut -d'=' -f2) -MODULE_NAME = $(shell cat $(ROOT_DIR)/code/gradle.properties | grep "moduleName" | cut -d'=' -f2) -LIB_VERSION = $(shell cat $(ROOT_DIR)/code/gradle.properties | grep "moduleVersion" | cut -d'=' -f2) -SOURCE_FILE_DIR = $(ROOT_DIR)/code/$(PROJECT_NAME) -AAR_FILE_DIR = $(ROOT_DIR)/code/$(PROJECT_NAME)/build/outputs/aar - -create-ci: clean - (mkdir -p ci) +init: + git config core.hooksPath .githooks clean: - (rm -rf ci) - (rm -rf $(AAR_FILE_DIR)) (./code/gradlew -p code clean) -checkstyle: - (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) checkstyle) - +format: + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) spotlessApply) + format-license: - (./code/gradlew -p code licenseFormat) + (./code/gradlew -p code licenseFormat) -ci-build: create-ci - (mkdir -p ci/assemble) +checkformat: + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) spotlessCheck) - (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) assemblePhone) - (mv $(AAR_FILE_DIR)/$(EXTENSION-LIBRARY-FOLDER-NAME)-phone-release.aar $(AAR_FILE_DIR)/$(MODULE_NAME)-release-$(LIB_VERSION).aar) - (cp -r ./code/$(EXTENSION-LIBRARY-FOLDER-NAME)/build $(BUILD-ASSEMBLE-LOCATION)) +checkstyle: + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) checkstyle) -ci-unit-test: create-ci - (mkdir -p ci/unit-test) - (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) platformUnitTestJacocoReport) - (cp -r ./code/$(EXTENSION-LIBRARY-FOLDER-NAME)/build ./ci/unit-test/) +unit-test: + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) testPhoneDebugUnitTest) -ci-functional-test: create-ci - (mkdir -p ci/functional-test) +unit-test-coverage: + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) createPhoneDebugUnitTestCoverageReport) + +functional-test: (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) uninstallPhoneDebugAndroidTest) - (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) connectedPhoneDebugAndroidTest platformFunctionalTestJacocoReport) - (cp -r ./code/$(EXTENSION-LIBRARY-FOLDER-NAME)/build ./ci/functional-test) + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) connectedPhoneDebugAndroidTest) -ci-javadoc: create-ci - (mkdir -p ci/javadoc) - (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) javadocPublic > ci/javadocPublic.log 2>&1) - (cp -r ./code/$(EXTENSION-LIBRARY-FOLDER-NAME)/build ./ci/javadoc) +functional-test-coverage: + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) uninstallPhoneDebugAndroidTest) + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) createPhoneDebugAndroidTestCoverageReport) + +javadoc: + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) javadocJar) + +assemble-phone: + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) assemblePhone) -ci-generate-library-debug: - (./code/gradlew -p code/${EXTENSION-LIBRARY-FOLDER-NAME} assemblePhoneDebug) +assemble-phone-debug: + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) assemblePhoneDebug) + +assemble-phone-release: + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) assemblePhoneRelease) -ci-generate-library-release: - (./code/gradlew -p code/${EXTENSION-LIBRARY-FOLDER-NAME} assemblePhoneRelease) +assemble-app: + (./code/gradlew -p code/$(TEST-APP-FOLDER-NAME) assemble) -build-release: - (./code/gradlew -p code/${EXTENSION-LIBRARY-FOLDER-NAME} clean lint assemblePhoneRelease) +ci-publish-maven-local-jitpack: assemble-phone-release + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) publishReleasePublicationToMavenLocal -Pjitpack -x signReleasePublication) -ci-publish-staging: clean build-release - (./code/gradlew -p code/${EXTENSION-LIBRARY-FOLDER-NAME} publishReleasePublicationToSonatypeRepository) +ci-publish-staging: assemble-phone-release + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) publishReleasePublicationToSonatypeRepository) -ci-publish-main: clean build-release - (./code/gradlew -p code/${EXTENSION-LIBRARY-FOLDER-NAME} publishReleasePublicationToSonatypeRepository -Prelease) +ci-publish: assemble-phone-release + (./code/gradlew -p code/$(EXTENSION-LIBRARY-FOLDER-NAME) publishReleasePublicationToSonatypeRepository -Prelease) diff --git a/README.md b/README.md index 91493ea..98f82a0 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Refer to the [getting started](./Documentation/getting-started.md) guide for set **Open the project** -To open and run the project, open the `code/build.gradle` file in Android Studio +To open and run the project, open the `code/build.gradle.kts` file in Android Studio **Run demo application** Once you open the project in Android Studio (see above), select the `testapp` runnable and your favorite emulator and run the program. diff --git a/code/build.gradle b/code/build.gradle deleted file mode 100644 index 0efd986..0000000 --- a/code/build.gradle +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright 2022 Adobe. All rights reserved. - * This file is licensed to you under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - * OF ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - */ -// Top-level build file where you can add configuration options common to all sub-projects/modules. -import com.hierynomus.gradle.license.tasks.LicenseFormat - -buildscript { - ext { - kotlin_version = '1.4.0' - } - repositories { - google() - mavenCentral() - maven { url "https://plugins.gradle.org/m2/" } - maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } - } - dependencies { - classpath 'com.android.tools.build:gradle:7.3.1' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.20" - } -} - - -plugins { - id 'com.github.hierynomus.license' version '0.16.1' apply true -} - -allprojects { - repositories { - google() - mavenCentral() - maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } - maven { url "https://plugins.gradle.org/m2/" } - } - - apply plugin: 'maven-publish' - if (project.hasProperty("sonatypeUser") && project.hasProperty("sonatypePass")) { - ext["ossrhUsername"] = "$sonatypeUser" - ext["ossrhPassword"] = "$sonatypePass" - } else { - ext["ossrhUsername"] = "" - ext["ossrhPassword"] = "" - } -} - -license { - header rootProject.file('../config/formatter/header.txt') - ext.year = Calendar.getInstance().get(Calendar.YEAR) - skipExistingHeaders = true -} - -// Add and maintain licence header to all project files of type XML, YAML, Properties, and Gradle -task licenseFormatProject(type: LicenseFormat) { - source = fileTree(dir: "../") - .exclude(["**/.idea/*", "**/build/*", "**/*.java", "**/*.kt", "**/.git/*", "**/.gradle/*", "**/gradle/wrapper/*", "config/*", "**/local.properties"]) - .include(["**/*.xml", "**/*.yml", "**/*.properties", "**/*.gradle"]) -} -licenseFormat.dependsOn licenseFormatProject - -task clean(type: Delete) { - delete rootProject.buildDir -} - -ext { - // android config - minSdkVersion = 19 - targetSdkVersion = 33 - compileSdkVersion = 33 - versionCode = 2 - - // java config - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - - // dependencies - junitVersion = "1.1.3" - mockitoCoreVersion = "4.5.1" - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - jacocoVersion = "0.8.7" -} \ No newline at end of file diff --git a/code/settings.gradle b/code/build.gradle.kts similarity index 67% rename from code/settings.gradle rename to code/build.gradle.kts index 3170c83..719171c 100644 --- a/code/settings.gradle +++ b/code/build.gradle.kts @@ -1,4 +1,4 @@ -/** +/* * Copyright 2022 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy @@ -9,6 +9,16 @@ * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ -include ':testapp' -include ':target' -rootProject.name = 'aepsdk-target-android' +apply(plugin = "aep-license") +buildscript { + repositories { + gradlePluginPortal() + google() + mavenCentral() + maven { url = uri("https://jitpack.io") } + mavenLocal() + } + dependencies { + classpath("com.github.adobe:aepsdk-commons:gp-3.0.0") + } +} \ No newline at end of file diff --git a/code/checkstyle.gradle b/code/checkstyle.gradle deleted file mode 100644 index 04f7d44..0000000 --- a/code/checkstyle.gradle +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright 2022 Adobe. All rights reserved. - * This file is licensed to you under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - * OF ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - */ -apply plugin: "checkstyle" - -checkstyle { - configFile rootProject.file('checkstyle.xml') - ignoreFailures false - showViolations true - toolVersion = "8.15" -} - -/** Checkstyle task for new files (not in exclude list). Fail build if a check fails **/ -task checkstyle(type: Checkstyle) { - configFile rootProject.file('checkstyle.xml') - - //fail early - ignoreFailures false - showViolations true - - source 'src' - include '**/*.java' - exclude '**/gen/**' - exclude '**/test/**' - exclude '**/legacy/**' - exclude '**/androidTest/**' - exclude '**/R.java' - exclude '**/BuildConfig.java' -// exclude rootProject.file('checkstyle/checkstyle-exclude-list.txt') as String[] - classpath = files() -} \ No newline at end of file diff --git a/code/checkstyle.xml b/code/checkstyle.xml deleted file mode 100644 index dec75f2..0000000 --- a/code/checkstyle.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/code/gradle.properties b/code/gradle.properties index de85860..651bc0f 100644 --- a/code/gradle.properties +++ b/code/gradle.properties @@ -10,27 +10,19 @@ # governing permissions and limitations under the License. # -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. org.gradle.jvmargs=-Xmx2048m +org.gradle.caching=true -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app"s APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true -moduleProjectName=target moduleName=target -moduleAARName=target-phone-release.aar -moduleVersion=2.0.3 +moduleVersion=3.0.0 +#Maven artifact mavenRepoName=AdobeMobileTargetSdk mavenRepoDescription=Adobe Experience Platform Target extension for the Adobe Experience Platform Mobile SDK mavenUploadDryRunFlag=false -mavenCoreVersion=2.0.1 + +# production versions for production build +mavenCoreVersion=3.0.0 +functionalTestIdentityVersion=3.0.0 \ No newline at end of file diff --git a/code/gradle/wrapper/gradle-wrapper.properties b/code/gradle/wrapper/gradle-wrapper.properties index a6da2ae..08fe573 100644 --- a/code/gradle/wrapper/gradle-wrapper.properties +++ b/code/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Wed Oct 11 21:18:19 PDT 2023 distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/code/settings.gradle.kts b/code/settings.gradle.kts new file mode 100755 index 0000000..57cae11 --- /dev/null +++ b/code/settings.gradle.kts @@ -0,0 +1,36 @@ +/* + * Copyright 2024 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +pluginManagement { + repositories { + gradlePluginPortal() + google() + mavenCentral() + mavenLocal() + } +} + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + mavenLocal() + maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/") } + maven { url = uri("https://jitpack.io") } + } +} + +rootProject.name = "aepsdk-target-android" +include ( + ":testapp", + ":target" +) \ No newline at end of file diff --git a/code/target/build.gradle b/code/target/build.gradle deleted file mode 100644 index 6671d89..0000000 --- a/code/target/build.gradle +++ /dev/null @@ -1,245 +0,0 @@ -/** - * Copyright 2022 Adobe. All rights reserved. - * This file is licensed to you under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - * OF ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - */ -apply plugin: 'com.android.library' -apply plugin: 'jacoco' -apply plugin: 'maven-publish' -apply plugin: 'signing' -apply plugin: 'kotlin-android' - -ext { - srcFolders = file("./").listFiles().findAll { - !it.isFile() && !it.name.startsWith("gradle") && !it.name.startsWith("test") - }.collect { "./" + it.name + "/src/main/java" } -} - -jacoco { - toolVersion = rootProject.ext.jacocoVersion -} - -android { - compileSdkVersion rootProject.ext.compileSdkVersion - - defaultConfig { - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - versionCode rootProject.ext.versionCode - versionName rootProject.moduleVersion - - testInstrumentationRunner rootProject.ext.testInstrumentationRunner - consumerProguardFiles 'consumer-rules.pro' - } - - flavorDimensions "target" - productFlavors { - phone { - dimension "target" - } - } - - buildTypes { - debug { - testCoverageEnabled true - debuggable true - } - - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - - kotlinOptions { - jvmTarget = '1.8' - } - - testOptions { - unitTests.returnDefaultValues = true - } - - compileOptions { - sourceCompatibility rootProject.ext.sourceCompatibility - targetCompatibility rootProject.ext.targetCompatibility - } -} - -afterEvaluate { - tasks.withType(Javadoc) { - source = [android.sourceSets.main.java.sourceFiles, android.sourceSets.phone.java.sourceFiles] - classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) - classpath += files(android.libraryVariants.collect { variant -> - variant.javaCompileProvider.get().classpath.files - }) - options { - source = "8" - links "https://developer.android.com/reference" - } - } -} - -task javadocInternal(type: Javadoc) { - destinationDir = reporting.file("javadocInternal") - options.memberLevel = JavadocMemberLevel.PRIVATE -} - -task javadocPublic(type: Javadoc) { - destinationDir = reporting.file("javadocPublic") - options.memberLevel = JavadocMemberLevel.PUBLIC -} - -task javadocPublish(type: Jar) { - from javadocPublic - archiveClassifier.set('javadoc') -} - -def isReleaseBuild() { - return hasProperty('release') -} - -version = isReleaseBuild() ? rootProject.moduleVersion : rootProject.moduleVersion+"-SNAPSHOT" - -publish.dependsOn('assemblePhone') - -publishing { - publications { - release(MavenPublication) { - groupId = 'com.adobe.marketing.mobile' - artifactId = rootProject.moduleName - version = version - artifact("$buildDir/outputs/aar/${rootProject.moduleAARName}") - artifact javadocPublish - - pom { - name = mavenRepoName - description = mavenRepoDescription - url = 'https://developer.adobe.com/client-sdks' - licenses { - license { - name = 'The Apache License, Version 2.0' - url = 'https://www.apache.org/licenses/LICENSE-2.0.txt' - distribution = 'repo' - } - } - developers { - developer { - id = 'adobe' - name = 'adobe' - email = 'adobe-mobile-testing@adobe.com' - } - } - scm { - connection = 'scm:git:github.com//adobe/aepsdk-target-android.git' - developerConnection = 'scm:git:ssh://github.com/adobe/aepsdk-target-android.git' - url = 'https://github.com/adobe/aepsdk-target-android' - } - withXml { - def dependenciesNode = asNode().appendNode('dependencies') - - def coreDependencyNode = dependenciesNode.appendNode('dependency') - coreDependencyNode.appendNode('groupId', 'com.adobe.marketing.mobile') - coreDependencyNode.appendNode('artifactId', 'core') - coreDependencyNode.appendNode('version', mavenCoreVersion) - } - } - } - } - repositories { - maven { - name = "sonatype" - url = version.endsWith('SNAPSHOT') ? "https://oss.sonatype.org/content/repositories/snapshots/" : "https://oss.sonatype.org/service/local/staging/deploy/maven2/" - credentials { - username = System.getenv("SONATYPE_USERNAME") - password = System.getenv("SONATYPE_PASSWORD") - } - } - } -} - -ext."signing.gnupg.executable"="gpg" -ext."signing.gnupg.keyName"=System.getenv("GPG_KEY_ID") -ext."signing.gnupg.passphrase"=System.getenv("GPG_PASSPHRASE") - -signing { - useGpgCmd() - required { - tasks.withType(PublishToMavenRepository).find { - gradle.taskGraph.hasTask it - } - } - sign publishing.publications -} - -task platformUnitTestJacocoReport(type: JacocoReport, dependsOn: "testPhoneDebugUnitTest") { - def excludeRegex = ['**/ADB*.class', '**/BuildConfig.class'] - def javaClasses = fileTree(dir: "${project.buildDir}/intermediates/javac/phoneDebug/classes", excludes: excludeRegex) - def kotlinClasses = fileTree(dir: "${project.buildDir}/tmp/kotlin-classes/phoneDebug", excludes: excludeRegex) - classDirectories.setFrom(files([javaClasses, kotlinClasses])) - - def mainSrc = "${project.projectDir}/src/main/java" - def phoneSrc = "${project.projectDir}/src/phone/java" - sourceDirectories.setFrom files([mainSrc, phoneSrc]) - - executionData.setFrom fileTree(dir: "$buildDir", includes: [ - "outputs/unit_test_code_coverage/phoneDebugUnitTest/testPhoneDebugUnitTest.exec", - ]) - - reports { - xml.enabled true - csv.enabled false - html.enabled true - } -} - -task platformFunctionalTestJacocoReport(type: JacocoReport, dependsOn: "createPhoneDebugCoverageReport") { - def excludeRegex = ['**/ADB*.class', '**/BuildConfig.class'] - def javaClasses = fileTree(dir: "${project.buildDir}/intermediates/javac/phoneDebug/classes", excludes: excludeRegex) - def kotlinClasses = fileTree(dir: "${project.buildDir}/tmp/kotlin-classes/phoneDebug", excludes: excludeRegex) - classDirectories.setFrom(files([javaClasses, kotlinClasses])) - - def mainSrc = "${project.projectDir}/src/main/java" - def phoneSrc = "${project.projectDir}/src/phone/java" - sourceDirectories.setFrom files([mainSrc, phoneSrc]) - - executionData.setFrom fileTree(dir: "$buildDir", includes: [ - "outputs/code_coverage/phoneDebugAndroidTest/connected/*coverage.ec" - ]) - reports { - xml.enabled true - csv.enabled false - html.enabled false - } -} - -apply from: '../checkstyle.gradle' - -dependencies { - implementation "androidx.annotation:annotation:1.0.0" - - // Adobe Mobile SDK Core - implementation 'com.adobe.marketing.mobile:core:2.0.1' - - testImplementation "androidx.test.ext:junit:${rootProject.ext.junitVersion}" - testImplementation "org.mockito:mockito-core:${rootProject.ext.mockitoCoreVersion}" - testImplementation "org.mockito:mockito-inline:${rootProject.ext.mockitoCoreVersion}" - testImplementation 'com.fasterxml.jackson.core:jackson-databind:2.9.9' - testImplementation 'org.json:json:20180813' - - androidTestImplementation 'com.adobe.marketing.mobile:identity:2.0.0' - androidTestImplementation "androidx.test.ext:junit:${rootProject.ext.junitVersion}" - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' - androidTestImplementation 'com.fasterxml.jackson.core:jackson-databind:2.9.9' -} - -tasks.withType(Test) { - testLogging { - showStandardStreams = true - } -} diff --git a/code/target/build.gradle.kts b/code/target/build.gradle.kts new file mode 100644 index 0000000..82334ff --- /dev/null +++ b/code/target/build.gradle.kts @@ -0,0 +1,41 @@ +/* + * Copyright 2024 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +plugins { + id("aep-library") +} + +val mavenCoreVersion: String by project +val functionalTestIdentityVersion: String by project + +aepLibrary { + namespace = "com.adobe.marketing.mobile.target" + enableSpotless = true + enableCheckStyle = true + + publishing { + gitRepoName = "aepsdk-target-android" + addCoreDependency(mavenCoreVersion) + } +} + +dependencies { + implementation("com.adobe.marketing.mobile:core:$mavenCoreVersion") + + // testImplementation dependencies provided by aep-library: + // MOCKITO_CORE, MOCKITO_INLINE, JSON + testImplementation("com.fasterxml.jackson.core:jackson-databind:2.12.7") + + // androidTestImplementation dependencies provided by aep-library: + // ANDROIDX_TEST_EXT_JUNIT, ESPRESSO_CORE + androidTestImplementation("com.adobe.marketing.mobile:identity:$functionalTestIdentityVersion") + androidTestImplementation("com.fasterxml.jackson.core:jackson-databind:2.12.7") +} diff --git a/code/target/consumer-rules.pro b/code/target/consumer-rules.pro deleted file mode 100644 index e69de29..0000000 diff --git a/code/target/proguard-rules.pro b/code/target/proguard-rules.pro deleted file mode 100644 index 481bb43..0000000 --- a/code/target/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/code/target/src/androidTest/java/com/adobe/marketing/mobile/SDKHelper.java b/code/target/src/androidTest/java/com/adobe/marketing/mobile/SDKHelper.java index ebe2c2f..b6327be 100644 --- a/code/target/src/androidTest/java/com/adobe/marketing/mobile/SDKHelper.java +++ b/code/target/src/androidTest/java/com/adobe/marketing/mobile/SDKHelper.java @@ -1,5 +1,5 @@ /* - Copyright 2022 Adobe. All rights reserved. + Copyright 2023 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -7,7 +7,8 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ +*/ + package com.adobe.marketing.mobile; public class SDKHelper { diff --git a/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/ADBCountDownLatch.java b/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/ADBCountDownLatch.java index e11e9a6..019e6e0 100644 --- a/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/ADBCountDownLatch.java +++ b/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/ADBCountDownLatch.java @@ -1,14 +1,13 @@ /* - Copyright 2021 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; @@ -54,6 +53,7 @@ public int getCurrentCount() { @Override public String toString() { - return String.format("%s, initial: %d, current: %d", latch.toString(), initialCount, currentCount.get()); + return String.format( + "%s, initial: %d, current: %d", latch.toString(), initialCount, currentCount.get()); } } diff --git a/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/MonitorExtension.kt b/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/MonitorExtension.kt index 10ab960..14637f2 100644 --- a/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/MonitorExtension.kt +++ b/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/MonitorExtension.kt @@ -1,5 +1,5 @@ /* - Copyright 2022 Adobe. All rights reserved. + Copyright 2023 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -7,13 +7,14 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ +*/ + package com.adobe.marketing.mobile.target -import com.adobe.marketing.mobile.ExtensionApi -import com.adobe.marketing.mobile.Extension import com.adobe.marketing.mobile.EventSource import com.adobe.marketing.mobile.EventType +import com.adobe.marketing.mobile.Extension +import com.adobe.marketing.mobile.ExtensionApi import com.adobe.marketing.mobile.SharedStateResolution internal typealias ConfigurationMonitor = (firstValidConfiguration: Map) -> Unit @@ -44,4 +45,4 @@ internal class MonitorExtension(extensionApi: ExtensionApi) : Extension(extensio } } } -} \ No newline at end of file +} diff --git a/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/TargetFunctionalTests.kt b/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/TargetFunctionalTests.kt index e1b96fb..4915cdb 100644 --- a/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/TargetFunctionalTests.kt +++ b/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/TargetFunctionalTests.kt @@ -1,5 +1,5 @@ /* - Copyright 2022 Adobe. All rights reserved. + Copyright 2023 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -7,20 +7,37 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ +*/ package com.adobe.marketing.mobile.target import android.net.Uri import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.adobe.marketing.mobile.* +import com.adobe.marketing.mobile.AdobeCallback +import com.adobe.marketing.mobile.Identity +import com.adobe.marketing.mobile.LoggingMode +import com.adobe.marketing.mobile.MobileCore +import com.adobe.marketing.mobile.SDKHelper import com.adobe.marketing.mobile.Target -import com.adobe.marketing.mobile.services.* +import com.adobe.marketing.mobile.VisitorID +import com.adobe.marketing.mobile.services.HttpConnecting +import com.adobe.marketing.mobile.services.NamedCollection +import com.adobe.marketing.mobile.services.NetworkRequest +import com.adobe.marketing.mobile.services.Networking +import com.adobe.marketing.mobile.services.ServiceProvider import org.json.JSONArray import org.json.JSONObject -import org.junit.* -import org.junit.Assert.* +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNotEquals +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Rule +import org.junit.Test import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runner.RunWith @@ -49,7 +66,7 @@ class Retry(private val numberOfTestAttempts: Int) : TestRule { caughtThrowable = t System.err.println( description.displayName + ": run " + currentTestRun + " failed, " + - (numberOfTestAttempts - currentTestRun) + " retries remain." + (numberOfTestAttempts - currentTestRun) + " retries remain." ) System.err.println("test failure caused by: " + caughtThrowable.getLocalizedMessage()) } @@ -61,7 +78,6 @@ class Retry(private val numberOfTestAttempts: Int) : TestRule { } } - private typealias NetworkMonitor = (request: NetworkRequest) -> Unit private const val TARGET_DATA_STORE = "ADOBEMOBILE_TARGET" @@ -71,7 +87,8 @@ private var dataStore: NamedCollection? = null @RunWith(AndroidJUnit4::class) class TargetFunctionalTests { - @get:Rule val totalTestCount = Retry(2) + @get:Rule + val totalTestCount = Retry(2) companion object { // Tests will be run at most 2 times @@ -242,10 +259,10 @@ class TargetFunctionalTests { SDKHelper.resetTargetListener() } - //1 + // 1 @Test fun testExtensionVersion() { - assertEquals(TargetTestConstants.EXTENSION_VERSION, Target.extensionVersion()) + assertEquals(Target.EXTENSION_VERSION, Target.extensionVersion()) } // ---------------------------------------------------// @@ -260,7 +277,7 @@ class TargetFunctionalTests { .parameters(mboxParameters) .profileParameters(profileParameters) .build() - val targetRequest = TargetRequest(mboxName, targetParameters , defaultContent) { data -> + val targetRequest = TargetRequest(mboxName, targetParameters, defaultContent) { data -> retrievedLocationResponse = data waitForCallback?.countDown() } @@ -281,7 +298,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 2 @@ -299,7 +316,7 @@ class TargetFunctionalTests { val targetParameters = TargetParameters.Builder() .order(TargetOrder.fromEventData(orderParameters)) .build() - val targetRequest = TargetRequest(mboxName, targetParameters , defaultContent) { data -> + val targetRequest = TargetRequest(mboxName, targetParameters, defaultContent) { data -> retrievedLocationResponse = data waitForCallback?.countDown() } @@ -323,7 +340,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 3 @@ -334,7 +351,7 @@ class TargetFunctionalTests { val targetParameters = TargetParameters.Builder() .product(TargetProduct.fromEventData(productParameters)) .build() - val targetRequest = TargetRequest(mboxName, targetParameters , defaultContent) { data -> + val targetRequest = TargetRequest(mboxName, targetParameters, defaultContent) { data -> retrievedLocationResponse = data waitForCallback?.countDown() } @@ -355,7 +372,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 4 @@ -373,7 +390,7 @@ class TargetFunctionalTests { .order(TargetOrder.fromEventData(orderParameters)) .product(TargetProduct.fromEventData(productParameters)) .build() - val targetRequest = TargetRequest(mboxName, targetParameters , defaultContent) { data -> + val targetRequest = TargetRequest(mboxName, targetParameters, defaultContent) { data -> retrievedLocationResponse = data waitForCallback?.countDown() } @@ -401,7 +418,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 5 @@ -416,7 +433,7 @@ class TargetFunctionalTests { } val thirdPartyID = "testID" Target.setThirdPartyId(thirdPartyID) - val targetRequest = TargetRequest(mboxName, targetParameters , defaultContent) { data -> + val targetRequest = TargetRequest(mboxName, targetParameters, defaultContent) { data -> retrievedLocationResponse = data waitForCallback?.countDown() } @@ -438,7 +455,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 6 @@ -455,7 +472,7 @@ class TargetFunctionalTests { val thirdPartyID = "testID" Target.setThirdPartyId(thirdPartyID) Target.resetExperience() - val targetRequest = TargetRequest(mboxName, targetParameters , defaultContent) { data -> + val targetRequest = TargetRequest(mboxName, targetParameters, defaultContent) { data -> retrievedLocationResponse = data waitForCallback?.countDown() } @@ -477,7 +494,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 7 @@ -492,10 +509,11 @@ class TargetFunctionalTests { networkRequestHeaders = request.headers waitForNetworkCall?.countDown() } - mockedNetworkResponse = TargetTestHelper.getResponseForTarget(null, mboxNames, + mockedNetworkResponse = TargetTestHelper.getResponseForTarget( + null, mboxNames, targetClientCode, "prefetchedContent", null, null, null, - null, true, true) - + null, true, true + ) val prefetchRequest1 = TargetPrefetch(mboxNames[0], targetParameters) val prefetchRequest2 = TargetPrefetch(mboxNames[1], targetParameters) @@ -528,7 +546,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 8 @@ -550,7 +568,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 9 @@ -567,7 +585,6 @@ class TargetFunctionalTests { // test Target.getThirdPartyId { data -> - Log.error("Peaks Debug", data, data) retrievedThirdPartyID = data localLatch.countDown() } @@ -608,10 +625,12 @@ class TargetFunctionalTests { waitForNetworkCall?.countDown() } - updateConfiguration(mapOf( - "experienceCloud.org" to "972C898555E9F7BC7F000101@AdobeOrg", - "experienceCloud.server" to "identity.com" - )) + updateConfiguration( + mapOf( + "experienceCloud.org" to "972C898555E9F7BC7F000101@AdobeOrg", + "experienceCloud.server" to "identity.com" + ) + ) Identity.syncIdentifier( "type", "value", @@ -629,7 +648,6 @@ class TargetFunctionalTests { ) waitForNetworkCall?.await(5, TimeUnit.SECONDS) - // reset network capturer waitForNetworkCall = CountDownLatch(1) networkMonitor = { request -> @@ -639,9 +657,12 @@ class TargetFunctionalTests { } // test - val targetRequestList = listOf(TargetRequest(mboxName, null, defaultContent) { data -> - retrievedLocationResponse = data - waitForCallback?.countDown() }) + val targetRequestList = listOf( + TargetRequest(mboxName, null, defaultContent) { data -> + retrievedLocationResponse = data + waitForCallback?.countDown() + } + ) Target.retrieveLocationContent(targetRequestList, null) waitForCallback?.await(5, TimeUnit.SECONDS) waitForNetworkCall?.await(5, TimeUnit.SECONDS) @@ -675,7 +696,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 13 @@ -696,7 +717,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 14 @@ -720,12 +741,11 @@ class TargetFunctionalTests { assertEquals("mbox1", mbox.getString("name")) assertEquals("mbox_parameter_value", mbox.getJSONObject("parameters").getString("mbox_parameter_key")) - // test retrieveLocationContent("mbox1") // verify - assertNull(networkRequestBody); + assertNull(networkRequestBody) assertNull(networkRequestHeaders) assertEquals("prefetchedContent", retrievedLocationResponse) @@ -744,7 +764,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 18 @@ -760,9 +780,11 @@ class TargetFunctionalTests { .profileParameters(profileParameters) .build() val targetPrefetchList = listOf(TargetPrefetch(mboxName, targetParameters)) - mockedNetworkResponse = TargetTestHelper.getResponseForTarget(null, mboxNames, + mockedNetworkResponse = TargetTestHelper.getResponseForTarget( + null, mboxNames, targetClientCode, "prefetchedContent", null, null, null, - null, true, true) + null, true, true + ) val networkCountDownLatch = CountDownLatch(1) networkMonitor = { request -> @@ -806,7 +828,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 19 @@ -822,9 +844,11 @@ class TargetFunctionalTests { .profileParameters(profileParameters) .build() val targetPrefetchList = listOf(TargetPrefetch("mbox1", targetParameters)) - mockedNetworkResponse = TargetTestHelper.getResponseForTarget(null, mboxNames, + mockedNetworkResponse = TargetTestHelper.getResponseForTarget( + null, mboxNames, targetClientCode, "prefetchedContent", null, null, null, - null, true, true) + null, true, true + ) var callbackErrorStatus: String? = null val networkCountDownLatch = CountDownLatch(1) @@ -865,13 +889,15 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) // setup val retrieveLocationCountdownLatch = CountDownLatch(1) - val targetRequestList = listOf(TargetRequest(mboxName, null, defaultContent) { _ -> - retrieveLocationCountdownLatch.countDown() - }) + val targetRequestList = listOf( + TargetRequest(mboxName, null, defaultContent) { _ -> + retrieveLocationCountdownLatch.countDown() + } + ) val locationContentTargetParameters: TargetParameters = TargetParameters.Builder() .product(TargetProduct.fromEventData(productParameters2)) .order(TargetOrder.fromEventData(orderParameters2)) @@ -916,7 +942,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 24 @@ -968,7 +994,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 25 @@ -977,9 +1003,11 @@ class TargetFunctionalTests { fun test_Functional_Happy_Target_targetRetrieveLocationContent_VerifyWithoutTargetParameters() { // setup val retrieveLocationCountdownLatch = CountDownLatch(1) - val targetRequestList = listOf(TargetRequest(mboxName, null, defaultContent) { _ -> - retrieveLocationCountdownLatch.countDown() - }) + val targetRequestList = listOf( + TargetRequest(mboxName, null, defaultContent) { _ -> + retrieveLocationCountdownLatch.countDown() + } + ) val networkCountDownLatch = CountDownLatch(1) networkMonitor = { request -> networkRequestBody = String(request.body, Charsets.UTF_8) @@ -1005,12 +1033,12 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } - //********************************************************************************************** + // ********************************************************************************************** // Location Clicked Tests - //********************************************************************************************** + // ********************************************************************************************** // Test Case No : 26 @Test @Throws(Exception::class) @@ -1028,7 +1056,7 @@ class TargetFunctionalTests { assertNull(prefetchErrorStatus) assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) // test resetNetworkMonitor() @@ -1064,7 +1092,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 29 @@ -1100,20 +1128,19 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } - - //********************************************************************************************** + // ********************************************************************************************** // Location Displayed Tests - //********************************************************************************************** + // ********************************************************************************************** // Test Case No : 32 @Test @Throws(Exception::class) fun test_Functional_Happy_Target_targetDisplayedLocations() { prefetchContent("mbox1") - val prefetchJson= JSONObject(networkRequestBody) + val prefetchJson = JSONObject(networkRequestBody) assertNotNull(prefetchJson) val prefetch = prefetchJson.getJSONObject("prefetch").getJSONArray("mboxes") assertEquals(1, prefetch.length().toLong()) @@ -1136,7 +1163,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) // reset resetNetworkMonitor() @@ -1174,7 +1201,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } // Test Case No : 38 @@ -1183,7 +1210,7 @@ class TargetFunctionalTests { fun test_Functional_Target_targetPrefetchContentWith_targetDisplayedLocations_For_Different_MBox() { // setup prefetchContent("mbox1") - val prefetchJson= JSONObject(networkRequestBody) + val prefetchJson = JSONObject(networkRequestBody) assertNotNull(prefetchJson) // reset @@ -1218,10 +1245,9 @@ class TargetFunctionalTests { assertNull(networkRequestHeaders) } - - //********************************************************************************************** + // ********************************************************************************************** // Setters And Getters test - //********************************************************************************************** + // ********************************************************************************************** @Test @Throws(Exception::class) fun test_Functional_Happy_Target_targetSetAndGetSessionId() { @@ -1240,7 +1266,6 @@ class TargetFunctionalTests { assertNotNull(retrievedSessionId) assertNotEquals("", retrievedSessionId) - // Set a new session Id Target.setSessionId(sessionId) @@ -1258,13 +1283,12 @@ class TargetFunctionalTests { assertNotEquals(oldSessionId, retrievedSessionId) } - @Test @Throws(Exception::class) fun test_Functional_Happy_Target_targetSetAndGetTntId() { // setup - var retrievedTntId : String? = null - val newTntId= "66E5C681-4F70-41A2-86AE-F1E151443B10.35_0" + var retrievedTntId: String? = null + val newTntId = "66E5C681-4F70-41A2-86AE-F1E151443B10.35_0" // test Target.getTntId() { tntId -> @@ -1298,8 +1322,8 @@ class TargetFunctionalTests { @Throws(Exception::class) fun test_Functional_Happy_Target_targetSetAndGetThirdPartyId() { // setup - var retrievedThirdPartyId : String? = null - val newThirdPartyId= "shiningNewId" + var retrievedThirdPartyId: String? = null + val newThirdPartyId = "shiningNewId" // test Target.getThirdPartyId() { thirdPartyId -> @@ -1333,13 +1357,15 @@ class TargetFunctionalTests { @Throws(Exception::class) fun test_Functional_Session_Target_VerifySetSessionIdAndTntIdAndEdgeHostUsedWhenSendingTargetRequest() { // setup - var retrievedTntId : String? = null - var retrievedSessionId : String? = null - mockedNetworkResponse = TargetTestHelper.getResponseForTarget(null, arrayOf(mboxName), + var retrievedTntId: String? = null + var retrievedSessionId: String? = null + mockedNetworkResponse = TargetTestHelper.getResponseForTarget( + null, arrayOf(mboxName), targetClientCode, "prefetchedContent", "f741a5d5-09c0-4931-bf53-b9e568c5f782.35_0", "mboxedge35.tt.omtrdc.net", null, - null, false, true) + null, false, true + ) retrieveLocationContent(mboxName) // verify @@ -1348,7 +1374,6 @@ class TargetFunctionalTests { val sessionId1 = uri.getQueryParameter("sessionId") assertNotNull(sessionId1) - // Get and verify tntId waitForCallback = CountDownLatch(1) Target.getTntId() { tntId -> @@ -1358,7 +1383,6 @@ class TargetFunctionalTests { waitForCallback?.await(5, TimeUnit.SECONDS) assertEquals("f741a5d5-09c0-4931-bf53-b9e568c5f782.35_0", retrievedTntId) - // Get and verify sessionId waitForCallback = CountDownLatch(1) Target.getSessionId() { sessionId -> @@ -1376,7 +1400,7 @@ class TargetFunctionalTests { resetNetworkMonitor() retrieveLocationContent("mbox2") - //verify if the network request contains the latest ids + // verify if the network request contains the latest ids assertNotNull(networkRequestUrl) val uri2 = Uri.parse(networkRequestUrl) val sessionId2 = uri2.getQueryParameter("sessionId") @@ -1388,12 +1412,12 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } - //********************************************************************************************** + // ********************************************************************************************** // Target Raw Request Tests - //********************************************************************************************** + // ********************************************************************************************** @Test @Throws(Exception::class) fun test_Functional_Happy_Target_targetExecuteRawRequest_batch() { @@ -1404,16 +1428,18 @@ class TargetFunctionalTests { val executeMbox1 = mapOf( "index" to 0, "name" to "mbox1", - "parameters" to mboxParameters, + "parameters" to mboxParameters, "profileParameters" to profileParameters, "order" to orderParameters, - "product" to productParameters) + "product" to productParameters + ) val executeMboxes: MutableList> = ArrayList() executeMboxes.add(executeMbox1) val request = mapOf( "execute" to mapOf( "mboxes" to executeMboxes - )) + ) + ) val a4tPayload = "{\"payload\":{\"pe\":\"tnt\",\"tnta\":\"333911:0:0:0|2|4445.12\"}}" val a4tPayloadObject = JSONObject(a4tPayload) @@ -1428,8 +1454,8 @@ class TargetFunctionalTests { waitForNetworkCall?.countDown() } - - mockedNetworkResponse = TargetTestHelper.getResponseForTarget(null, mboxNames, + mockedNetworkResponse = TargetTestHelper.getResponseForTarget( + null, mboxNames, targetClientCode, "targetContent", "f741a5d5-09c0-4931-bf53-b9e568c5f782.35_0", @@ -1437,7 +1463,8 @@ class TargetFunctionalTests { arrayOf(a4tPayloadObject), arrayOf(mboxClickMetricPayload), false, - true) + true + ) // test Target.executeRawRequest( @@ -1486,7 +1513,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) // Verify server response assertEquals(1, responseDataList.size.toLong()) @@ -1550,7 +1577,8 @@ class TargetFunctionalTests { waitForNetworkCall?.countDown() } - mockedNetworkResponse = TargetTestHelper.getResponseForTarget(null, mboxNames, + mockedNetworkResponse = TargetTestHelper.getResponseForTarget( + null, mboxNames, targetClientCode, "targetContent", "f741a5d5-09c0-4931-bf53-b9e568c5f782.35_0", @@ -1558,7 +1586,8 @@ class TargetFunctionalTests { null, null, false, - true) + true + ) // test Target.executeRawRequest( @@ -1590,19 +1619,22 @@ class TargetFunctionalTests { val executeMbox1 = mapOf( "index" to 0, "name" to "mbox1", - "parameters" to mboxParameters, + "parameters" to mboxParameters, "profileParameters" to profileParameters, "order" to orderParameters, - "product" to productParameters) + "product" to productParameters + ) val executeMboxes: MutableList> = ArrayList() executeMboxes.add(executeMbox1) val request = mapOf( "execute" to mapOf( "mboxes" to executeMboxes - )) + ) + ) // setup network response - mockedNetworkResponse = TargetTestHelper.getResponseForTarget(null, + mockedNetworkResponse = TargetTestHelper.getResponseForTarget( + null, mboxNames, targetClientCode, "targetContent", @@ -1611,7 +1643,8 @@ class TargetFunctionalTests { null, null, false, - true) + true + ) networkMonitor = { request -> networkRequestUrl = request.url networkRequestBody = String(request.body, Charsets.UTF_8) @@ -1644,18 +1677,21 @@ class TargetFunctionalTests { val prefetchMbox1 = mapOf( "index" to 0, "name" to "mbox1", - "parameters" to mboxParameters, - "profileParameters" to profileParameters) + "parameters" to mboxParameters, + "profileParameters" to profileParameters + ) val prefetchMboxes: MutableList> = ArrayList() prefetchMboxes.add(prefetchMbox1) val request = mapOf( "prefetch" to mapOf( "mboxes" to prefetchMboxes - )) + ) + ) // setup network response resetNetworkMonitor() - mockedNetworkResponse = TargetTestHelper.getResponseForTarget(null, + mockedNetworkResponse = TargetTestHelper.getResponseForTarget( + null, mboxNames, targetClientCode, "targetContent", @@ -1664,7 +1700,8 @@ class TargetFunctionalTests { null, null, true, - true) + true + ) // test Target.executeRawRequest( @@ -1701,7 +1738,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) // Verify server response assertEquals(1, responseDataList.size.toLong()) @@ -1734,7 +1771,7 @@ class TargetFunctionalTests { "name" to "mbox1" ), "tokens" to listOf(displayToken), - "parameters" to mboxParameters2, + "parameters" to mboxParameters2, "profileParameters" to profileParameters2, "order" to orderParameters2, "product" to productParameters2 @@ -1783,7 +1820,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } @Test @@ -1796,19 +1833,22 @@ class TargetFunctionalTests { val executeMbox1 = mapOf( "index" to 0, "name" to "mbox1", - "parameters" to mboxParameters, + "parameters" to mboxParameters, "profileParameters" to profileParameters, "order" to orderParameters, - "product" to productParameters) + "product" to productParameters + ) val executeMboxes: MutableList> = ArrayList() executeMboxes.add(executeMbox1) val requestMap = mapOf( "execute" to mapOf( "mboxes" to executeMboxes - )) + ) + ) // setup network response - mockedNetworkResponse = TargetTestHelper.getResponseForTarget(null, + mockedNetworkResponse = TargetTestHelper.getResponseForTarget( + null, mboxNames, targetClientCode, "targetContent", @@ -1817,7 +1857,8 @@ class TargetFunctionalTests { null, null, false, - true) + true + ) networkMonitor = { request -> networkRequestUrl = request.url networkRequestBody = String(request.body, Charsets.UTF_8) @@ -1827,7 +1868,7 @@ class TargetFunctionalTests { // test Target.executeRawRequest( - requestMap + requestMap ) { responseData -> responseDataList.add(responseData) localLatch.countDown() @@ -1860,7 +1901,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) // Verify server response assertEquals(1, responseDataList.size.toLong()) @@ -1892,7 +1933,7 @@ class TargetFunctionalTests { "name" to "mbox1" ), "tokens" to listOf(clickToken), - "parameters" to mboxParameters2, + "parameters" to mboxParameters2, "profileParameters" to profileParameters2, "order" to orderParameters2, "product" to productParameters2 @@ -1941,16 +1982,18 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } @Test @Throws(Exception::class) fun test_Functional_Target_targetSendRawNotifications_noClientCodeConfigured() { // setup - updateConfiguration(mapOf( - "target.clientCode" to "" - )) + updateConfiguration( + mapOf( + "target.clientCode" to "" + ) + ) val notification = mapOf( "id" to "0", @@ -1960,7 +2003,7 @@ class TargetFunctionalTests { "name" to "mbox1" ), "tokens" to listOf("RandomClickTrackEventToken"), - "parameters" to mboxParameters2, + "parameters" to mboxParameters2, "profileParameters" to profileParameters2, "order" to orderParameters2, "product" to productParameters2 @@ -2001,7 +2044,7 @@ class TargetFunctionalTests { "name" to "mbox1" ), "tokens" to listOf("RandomClickTrackEventToken"), - "parameters" to mboxParameters2, + "parameters" to mboxParameters2, "profileParameters" to profileParameters2, "order" to orderParameters2, "product" to productParameters2 @@ -2011,7 +2054,8 @@ class TargetFunctionalTests { "notifications" to listOf(notification), "property" to mapOf( "token" to "requestPropertyToken" - )) + ) + ) // test Target.sendRawNotifications(notificationRequest) @@ -2038,7 +2082,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) } @Test @@ -2046,9 +2090,11 @@ class TargetFunctionalTests { fun test_Functional_Target_targetSendRawNotifications_withPropertyTokenInRequestAndInConfiguration() { // setup resetNetworkMonitor() - updateConfiguration(mapOf( - "target.propertyToken" to "configPropertyToken" - )) + updateConfiguration( + mapOf( + "target.propertyToken" to "configPropertyToken" + ) + ) val notification = mapOf( "id" to "0", "timestamp" to System.currentTimeMillis(), @@ -2057,7 +2103,7 @@ class TargetFunctionalTests { "name" to "mbox1" ), "tokens" to listOf("RandomClickTrackEventToken"), - "parameters" to mboxParameters2, + "parameters" to mboxParameters2, "profileParameters" to profileParameters2, "order" to orderParameters2, "product" to productParameters2 @@ -2067,7 +2113,8 @@ class TargetFunctionalTests { "notifications" to listOf(notification), "property" to mapOf( "token" to "requestPropertyToken" - )) + ) + ) Thread.sleep(1000) // test @@ -2083,30 +2130,35 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) // reset the updated configuration // so that it doesn't get carry forwarded to other tests - updateConfiguration(mapOf( - "target.propertyToken" to null - )) + updateConfiguration( + mapOf( + "target.propertyToken" to null + ) + ) } - //********************************************************************************************** + // ********************************************************************************************** // Attach Data Tests - //********************************************************************************************** + // ********************************************************************************************** @Test @Throws(Exception::class) fun test_Functional_Happy_Target_VerifyDataAttachedToRetrieveLocationContentRequest() { // setup - updateConfiguration(mapOf( - "rules.url" to "https://assets.adobedtm.com/94f571f308d5/36109c91f05a/launch-025ab77d2925-development-rules.zip" - )) + updateConfiguration( + mapOf( + "rules.url" to "https://assets.adobedtm.com/94f571f308d5/36109c91f05a/launch-025ab77d2925-development-rules.zip" + ) + ) Thread.sleep(1000) // test resetNetworkMonitor() - mockedNetworkResponse = TargetTestHelper.getResponseForTarget(null, arrayOf(mboxName), + mockedNetworkResponse = TargetTestHelper.getResponseForTarget( + null, arrayOf(mboxName), targetClientCode, "targetContent", null, @@ -2114,11 +2166,12 @@ class TargetFunctionalTests { null, null, false, - true) + true + ) retrieveLocationContent(mboxName) // verify - val json= JSONObject(networkRequestBody) + val json = JSONObject(networkRequestBody) val mboxes = json.getJSONObject("execute").getJSONArray("mboxes") val mbox = mboxes.getJSONObject(0) val profileParams = mbox.getJSONObject("profileParameters") @@ -2127,7 +2180,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) // clear the rules resetRules() @@ -2137,14 +2190,17 @@ class TargetFunctionalTests { @Throws(Exception::class) fun test_Functional_Target_VerifyDataNotAttachedIfKeyAlreadyExists() { // setup - updateConfiguration(mapOf( - "rules.url" to "https://assets.adobedtm.com/94f571f308d5/36109c91f05a/launch-025ab77d2925-development-rules.zip" - )) + updateConfiguration( + mapOf( + "rules.url" to "https://assets.adobedtm.com/94f571f308d5/36109c91f05a/launch-025ab77d2925-development-rules.zip" + ) + ) Thread.sleep(1000) // test resetNetworkMonitor() - mockedNetworkResponse = TargetTestHelper.getResponseForTarget(null, arrayOf(mboxName), + mockedNetworkResponse = TargetTestHelper.getResponseForTarget( + null, arrayOf(mboxName), targetClientCode, "targetContent", null, @@ -2152,14 +2208,15 @@ class TargetFunctionalTests { null, null, false, - true) + true + ) val targetParameters = TargetParameters.Builder() .profileParameters(mapOf("gender" to "female")) .build() retrieveLocationContent(mboxName, targetParameters) // verify - val json= JSONObject(networkRequestBody) + val json = JSONObject(networkRequestBody) val mboxes = json.getJSONObject("execute").getJSONArray("mboxes") val mbox = mboxes.getJSONObject(0) val profileParams = mbox.getJSONObject("profileParameters") @@ -2168,7 +2225,7 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) // clear the rules resetRules() @@ -2178,14 +2235,17 @@ class TargetFunctionalTests { @Throws(Exception::class) fun test_Functional_Happy_Target_VerifyDataAttachedToPrefetchRequest() { // setup - updateConfiguration(mapOf( - "rules.url" to "https://assets.adobedtm.com/94f571f308d5/36109c91f05a/launch-025ab77d2925-development-rules.zip" - )) + updateConfiguration( + mapOf( + "rules.url" to "https://assets.adobedtm.com/94f571f308d5/36109c91f05a/launch-025ab77d2925-development-rules.zip" + ) + ) Thread.sleep(1000) // test resetNetworkMonitor() - mockedNetworkResponse = TargetTestHelper.getResponseForTarget(null, arrayOf(mboxName), + mockedNetworkResponse = TargetTestHelper.getResponseForTarget( + null, arrayOf(mboxName), targetClientCode, "targetContent", null, @@ -2193,11 +2253,12 @@ class TargetFunctionalTests { null, null, true, - true) + true + ) prefetchContent(mboxName) // verify - val json= JSONObject(networkRequestBody) + val json = JSONObject(networkRequestBody) val mboxes = json.getJSONObject("prefetch").getJSONArray("mboxes") val mbox = mboxes.getJSONObject(0) val profileParams = mbox.getJSONObject("profileParameters") @@ -2206,16 +2267,16 @@ class TargetFunctionalTests { // verify request headers assertEquals("AdobeTargetMobile-Android", networkRequestHeaders?.get("X-EXC-SDK")) - assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), TargetTestConstants.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) + assertEquals(String.format("%s+%s", MobileCore.extensionVersion(), Target.EXTENSION_VERSION), networkRequestHeaders?.get("X-EXC-SDK-Version")) // clear the rules resetRules() } - //********************************************************************************************** + // ********************************************************************************************** // Private methods - //********************************************************************************************** - private fun updateConfiguration(config: Map) { + // ********************************************************************************************** + private fun updateConfiguration(config: Map) { val configurationLatch = CountDownLatch(1) configurationAwareness { configurationLatch.countDown() } MobileCore.updateConfiguration(config) @@ -2223,9 +2284,11 @@ class TargetFunctionalTests { } private fun resetRules() { - updateConfiguration(mapOf( - "rules.url" to "" - )) + updateConfiguration( + mapOf( + "rules.url" to "" + ) + ) } private fun retrieveLocationContent(mboxName: String, targetParams: TargetParameters = targetParameters) { @@ -2234,7 +2297,7 @@ class TargetFunctionalTests { resetNetworkMonitor() - val targetRequest = TargetRequest(mboxName, targetParams , defaultContent) { data -> + val targetRequest = TargetRequest(mboxName, targetParams, defaultContent) { data -> retrievedLocationResponse = data waitForCallback?.countDown() } @@ -2249,9 +2312,11 @@ class TargetFunctionalTests { waitForCallback = CountDownLatch(1) prefetchErrorStatus = null resetNetworkMonitor() - mockedNetworkResponse = TargetTestHelper.getResponseForTarget(null, arrayOf(mboxName), + mockedNetworkResponse = TargetTestHelper.getResponseForTarget( + null, arrayOf(mboxName), targetClientCode, "prefetchedContent", null, null, null, - null, true, true) + null, true, true + ) val targetPrefetchList = listOf(TargetPrefetch(mboxName, targetParameters)) Target.prefetchContent(targetPrefetchList, targetParameters) { status -> @@ -2325,4 +2390,4 @@ class TargetFunctionalTests { responseStream?.close() } } -} \ No newline at end of file +} diff --git a/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/TargetTestConstants.java b/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/TargetTestConstants.java deleted file mode 100644 index c71fdc0..0000000 --- a/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/TargetTestConstants.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ - -package com.adobe.marketing.mobile.target; - -public class TargetTestConstants { - - static final String EXTENSION_VERSION = "2.0.3"; - - public final static class EventType { - public static final String TARGET = "com.adobe.eventType.target"; - } - - public final static class EventSource { - public static final String REQUEST_CONTENT = "com.adobe.eventSource.requestContent"; - } - - public final static class EventDataKeys { - public static final String STATE_OWNER = "stateowner"; - } -} diff --git a/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/TargetTestHelper.kt b/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/TargetTestHelper.kt index 55d8726..7b3c998 100644 --- a/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/TargetTestHelper.kt +++ b/code/target/src/androidTest/java/com/adobe/marketing/mobile/target/TargetTestHelper.kt @@ -1,5 +1,5 @@ /* - Copyright 2022 Adobe. All rights reserved. + Copyright 2023 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -7,11 +7,11 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ +*/ + package com.adobe.marketing.mobile.target import com.adobe.marketing.mobile.services.DeviceInforming -import com.adobe.marketing.mobile.services.Log import com.adobe.marketing.mobile.services.ServiceProvider import com.adobe.marketing.mobile.util.StringUtils import org.json.JSONArray @@ -67,9 +67,9 @@ internal object TargetTestHelper { private const val TARGET_ERROR_MESSAGE = "message" private const val TARGET_REQUEST_ID_VALUE = "95ba3643-ea07-4ed8-a422-c5d1a0c4b145" - //====================================================================================================================================== + // ====================================================================================================================================== // target helper methods - //====================================================================================================================================== + // ====================================================================================================================================== @JvmStatic fun getResponseForTarget( errorMessage: String?, @@ -82,14 +82,14 @@ internal object TargetTestHelper { clickMetricAnalyticPayloads: Array?, isPrefetch: Boolean, isClickMetricAdded: Boolean - ) : InputStream? { + ): InputStream? { // val targetRequestMatcher = E2ERequestMatcher(".tt.omtrdc.net/rest/v1/delivery/") val responseString: String? var prefetchResponses: JSONArray? = JSONArray() var mboxResponses: JSONArray? = JSONArray() val mBoxResponseMap = getMBoxesResponseMap(content) - //create mbox responses for each mbox loaded/prefetched. two paths are needed due to a4t payload. + // create mbox responses for each mbox loaded/prefetched. two paths are needed due to a4t payload. if (a4tPayloads != null) { for (i in mboxNames.indices) { val a4tToInsert = a4tPayloads[i] @@ -172,7 +172,7 @@ internal object TargetTestHelper { } } - //prevent creation of an empty prefetch or mbox node in the response string. + // prevent creation of an empty prefetch or mbox node in the response string. if (prefetchResponses!!.length() == 0) { prefetchResponses = null } @@ -180,7 +180,7 @@ internal object TargetTestHelper { mboxResponses = null } - //create the response string and set the response in the testable network service + // create the response string and set the response in the testable network service responseString = createTargetResponseString( errorMessage, clientCode, prefetchResponses, mboxResponses, edgeHost, tntId, null, null @@ -266,10 +266,14 @@ internal object TargetTestHelper { } private fun createTargetResponseString( - errorMessage: String?, clientCode: String?, + errorMessage: String?, + clientCode: String?, prefetchArray: JSONArray?, mboxArray: JSONArray?, - edgeHost: String?, tntId: String?, thirdPartyId: String?, marketingCloudID: String? + edgeHost: String?, + tntId: String?, + thirdPartyId: String?, + marketingCloudID: String? ): String? { return try { val response = JSONObject() @@ -337,8 +341,8 @@ internal object TargetTestHelper { val mboxNode = mboxJSONArray.optJSONObject(i) if (mboxNode == null || StringUtils.isNullOrEmpty( mboxNode.optString( - TARGET_API_JSON_MBOX, "" - ) + TARGET_API_JSON_MBOX, "" + ) ) ) { continue @@ -383,8 +387,8 @@ internal object TargetTestHelper { @JvmStatic fun readInputStreamFromFile( fileName: String, - ) : InputStream? { - return this::class.java.classLoader?.getResource("${fileName}.zip") - ?.openStream()!! + ): InputStream? { + return this::class.java.classLoader?.getResource("$fileName.zip") + ?.openStream()!! } } diff --git a/code/target/src/main/AndroidManifest.xml b/code/target/src/main/AndroidManifest.xml index 1d5c72f..d5bd4a5 100644 --- a/code/target/src/main/AndroidManifest.xml +++ b/code/target/src/main/AndroidManifest.xml @@ -12,6 +12,4 @@ governing permissions and limitations under the License. --> - - \ No newline at end of file + \ No newline at end of file diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/AdobeTargetDetailedCallback.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/AdobeTargetDetailedCallback.java index 3584091..6322a38 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/AdobeTargetDetailedCallback.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/AdobeTargetDetailedCallback.java @@ -1,39 +1,35 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; import com.adobe.marketing.mobile.AdobeError; - import java.util.Map; -/** - * Callback Interface to pass the mbox content and other payload info of mbox. - */ +/** Callback Interface to pass the mbox content and other payload info of mbox. */ public interface AdobeTargetDetailedCallback { - /** - * Callback function to pass the mbox content and other mbox payload values. - * - * @param content {@code String} mbox content - * @param data A {@code Map} of mbox payload values. - * {@code data} will be null if neither response tokens nor analytics payload is available. - */ - void call(final String content, final Map data); + /** + * Callback function to pass the mbox content and other mbox payload values. + * + * @param content {@code String} mbox content + * @param data A {@code Map} of mbox payload values. {@code data} will be null + * if neither response tokens nor analytics payload is available. + */ + void call(final String content, final Map data); - /** - * Callback function for notifying about the internal error in getting mbox details. - * - * @param error {@link AdobeError} represents the internal error which occurred. - */ - void fail(final AdobeError error); + /** + * Callback function for notifying about the internal error in getting mbox details. + * + * @param error {@link AdobeError} represents the internal error which occurred. + */ + void fail(final AdobeError error); } diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetConstants.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetConstants.java index 77119f2..edcadbd 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetConstants.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetConstants.java @@ -1,14 +1,13 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; @@ -19,10 +18,11 @@ final class TargetConstants { static final String EXTENSION_NAME = "com.adobe.module.target"; static final String FRIENDLY_NAME = "Target"; - static final String API_URL_HOST_BASE = "%s.tt.omtrdc.net"; + static final String API_URL_HOST_BASE = "%s.tt.omtrdc.net"; static final String EDGE_HOST_BASE = "mboxedge%s"; - static final String DELIVERY_API_URL_BASE = "https://%s/rest/v1/delivery/?client=%s&sessionId=%s"; - static final String MBOX_AT_PROPERTY_KEY = "at_property"; + static final String DELIVERY_API_URL_BASE = + "https://%s/rest/v1/delivery/?client=%s&sessionId=%s"; + static final String MBOX_AT_PROPERTY_KEY = "at_property"; static final String A4T_ACTION_NAME = "AnalyticsForTarget"; static final int DEFAULT_NETWORK_TIMEOUT = 2; @@ -36,9 +36,12 @@ final class TargetConstants { static final String DEFAULT_WRAPPER_FRIENDLY_NAME = "None"; + static final String PREVIEW_FLOATING_BUTTON_ASSET_FILE = "encoded_button_image.txt"; + private TargetConstants() {} static final HashMap MAP_TO_CONTEXT_DATA_KEYS = createMap(); + static HashMap createMap() { final HashMap map = new HashMap<>(); map.put(Identity.ADVERTISING_IDENTIFIER, ContextDataKeys.ADVERTISING_IDENTIFIER); @@ -70,30 +73,30 @@ static HashMap createMap() { } static final class ContextDataKeys { - static final String INSTALL_EVENT_KEY = "a.InstallEvent"; - static final String LAUNCH_EVENT_KEY = "a.LaunchEvent"; - static final String CRASH_EVENT_KEY = "a.CrashEvent"; - static final String UPGRADE_EVENT_KEY = "a.UpgradeEvent"; - static final String DAILY_ENGAGED_EVENT_KEY = "a.DailyEngUserEvent"; + static final String INSTALL_EVENT_KEY = "a.InstallEvent"; + static final String LAUNCH_EVENT_KEY = "a.LaunchEvent"; + static final String CRASH_EVENT_KEY = "a.CrashEvent"; + static final String UPGRADE_EVENT_KEY = "a.UpgradeEvent"; + static final String DAILY_ENGAGED_EVENT_KEY = "a.DailyEngUserEvent"; static final String MONTHLY_ENGAGED_EVENT_KEY = "a.MonthlyEngUserEvent"; - static final String INSTALL_DATE = "a.InstallDate"; - static final String LAUNCHES = "a.Launches"; - static final String PREVIOUS_SESSION_LENGTH = "a.PrevSessionLength"; - static final String DAYS_SINCE_FIRST_LAUNCH = "a.DaysSinceFirstUse"; - static final String DAYS_SINCE_LAST_LAUNCH = "a.DaysSinceLastUse"; - static final String HOUR_OF_DAY = "a.HourOfDay"; - static final String DAY_OF_WEEK = "a.DayOfWeek"; - static final String OPERATING_SYSTEM = "a.OSVersion"; - static final String APPLICATION_IDENTIFIER = "a.AppID"; - static final String DAYS_SINCE_LAST_UPGRADE = "a.DaysSinceLastUpgrade"; - static final String LAUNCHES_SINCE_UPGRADE = "a.LaunchesSinceUpgrade"; - static final String ADVERTISING_IDENTIFIER = "a.adid"; - static final String DEVICE_NAME = "a.DeviceName"; - static final String DEVICE_RESOLUTION = "a.Resolution"; - static final String CARRIER_NAME = "a.CarrierName"; - static final String LOCALE = "a.locale"; - static final String RUN_MODE = "a.RunMode"; - static final String IGNORED_SESSION_LENGTH = "a.ignoredSessionLength"; + static final String INSTALL_DATE = "a.InstallDate"; + static final String LAUNCHES = "a.Launches"; + static final String PREVIOUS_SESSION_LENGTH = "a.PrevSessionLength"; + static final String DAYS_SINCE_FIRST_LAUNCH = "a.DaysSinceFirstUse"; + static final String DAYS_SINCE_LAST_LAUNCH = "a.DaysSinceLastUse"; + static final String HOUR_OF_DAY = "a.HourOfDay"; + static final String DAY_OF_WEEK = "a.DayOfWeek"; + static final String OPERATING_SYSTEM = "a.OSVersion"; + static final String APPLICATION_IDENTIFIER = "a.AppID"; + static final String DAYS_SINCE_LAST_UPGRADE = "a.DaysSinceLastUpgrade"; + static final String LAUNCHES_SINCE_UPGRADE = "a.LaunchesSinceUpgrade"; + static final String ADVERTISING_IDENTIFIER = "a.adid"; + static final String DEVICE_NAME = "a.DeviceName"; + static final String DEVICE_RESOLUTION = "a.Resolution"; + static final String CARRIER_NAME = "a.CarrierName"; + static final String LOCALE = "a.locale"; + static final String RUN_MODE = "a.RunMode"; + static final String IGNORED_SESSION_LENGTH = "a.ignoredSessionLength"; private ContextDataKeys() {} } @@ -106,12 +109,11 @@ static class TargetResponse { private TargetResponse() {} } - static final String DATA_STORE_KEY = "ADOBEMOBILE_TARGET"; static class DataStoreKeys { - static final String TNT_ID = "TNT_ID"; - static final String THIRD_PARTY_ID = "THIRD_PARTY_ID"; + static final String TNT_ID = "TNT_ID"; + static final String THIRD_PARTY_ID = "THIRD_PARTY_ID"; static final String SESSION_ID = "SESSION_ID"; static final String SESSION_TIMESTAMP = "SESSION_TIMESTAMP"; static final String EDGE_HOST = "EDGE_HOST"; @@ -148,7 +150,7 @@ static final class EventDataKeys { static final String IS_LOCATION_DISPLAYED = "islocationdisplayed"; static final String IS_LOCATION_CLICKED = "islocationclicked"; static final String THIRD_PARTY_ID = "thirdpartyid"; - static final String TNT_ID = "tntid"; + static final String TNT_ID = "tntid"; static final String SESSION_ID = "sessionid"; static final String RESET_EXPERIENCE = "resetexperience"; static final String CLEAR_PREFETCH_CACHE = "clearcache"; @@ -167,9 +169,9 @@ static final class EventDataKeys { static final String EXPERIENCE_CLOUD = "experienceCloud"; static final String PROPERTY = "property"; static final String ENVIRONMENT_ID = "environmentId"; - static final String TRACK_INTERNAL = "trackinternal"; - static final String TRACK_ACTION = "action"; - static final String CONTEXT_DATA = "contextdata"; + static final String TRACK_INTERNAL = "trackinternal"; + static final String TRACK_ACTION = "action"; + static final String CONTEXT_DATA = "contextdata"; static final class Order { static final String ID = "id"; @@ -190,8 +192,8 @@ private EventDataKeys() {} } static final class Configuration { - static final String EXTENSION_NAME = "com.adobe.module.configuration"; - static final String GLOBAL_CONFIG_PRIVACY = "global.privacy"; + static final String EXTENSION_NAME = "com.adobe.module.configuration"; + static final String GLOBAL_CONFIG_PRIVACY = "global.privacy"; static final String TARGET_CLIENT_CODE = "target.clientCode"; static final String TARGET_PREVIEW_ENABLED = "target.previewEnabled"; static final String TARGET_NETWORK_TIMEOUT = "target.timeout"; @@ -220,30 +222,30 @@ private Identity() {} static final class Lifecycle { static final String EXTENSION_NAME = "com.adobe.module.lifecycle"; - static final String APP_ID = "appid"; - static final String CARRIER_NAME = "carriername"; - static final String CRASH_EVENT = "crashevent"; - static final String DAILY_ENGAGED_EVENT = "dailyenguserevent"; - static final String DAY_OF_WEEK = "dayofweek"; + static final String APP_ID = "appid"; + static final String CARRIER_NAME = "carriername"; + static final String CRASH_EVENT = "crashevent"; + static final String DAILY_ENGAGED_EVENT = "dailyenguserevent"; + static final String DAY_OF_WEEK = "dayofweek"; static final String DAYS_SINCE_FIRST_LAUNCH = "dayssincefirstuse"; - static final String DAYS_SINCE_LAST_LAUNCH = "dayssincelastuse"; + static final String DAYS_SINCE_LAST_LAUNCH = "dayssincelastuse"; static final String DAYS_SINCE_LAST_UPGRADE = "dayssincelastupgrade"; - static final String DEVICE_NAME = "devicename"; - static final String DEVICE_RESOLUTION = "resolution"; - static final String HOUR_OF_DAY = "hourofday"; - static final String IGNORED_SESSION_LENGTH = "ignoredsessionlength"; - static final String INSTALL_DATE = "installdate"; - static final String INSTALL_EVENT = "installevent"; - static final String LAUNCH_EVENT = "launchevent"; - static final String LAUNCHES = "launches"; - static final String LAUNCHES_SINCE_UPGRADE = "launchessinceupgrade"; - static final String LIFECYCLE_CONTEXT_DATA = "lifecyclecontextdata"; - static final String LOCALE = "locale"; - static final String MONTHLY_ENGAGED_EVENT = "monthlyenguserevent"; - static final String OPERATING_SYSTEM = "osversion"; + static final String DEVICE_NAME = "devicename"; + static final String DEVICE_RESOLUTION = "resolution"; + static final String HOUR_OF_DAY = "hourofday"; + static final String IGNORED_SESSION_LENGTH = "ignoredsessionlength"; + static final String INSTALL_DATE = "installdate"; + static final String INSTALL_EVENT = "installevent"; + static final String LAUNCH_EVENT = "launchevent"; + static final String LAUNCHES = "launches"; + static final String LAUNCHES_SINCE_UPGRADE = "launchessinceupgrade"; + static final String LIFECYCLE_CONTEXT_DATA = "lifecyclecontextdata"; + static final String LOCALE = "locale"; + static final String MONTHLY_ENGAGED_EVENT = "monthlyenguserevent"; + static final String OPERATING_SYSTEM = "osversion"; static final String PREVIOUS_SESSION_LENGTH = "prevsessionlength"; - static final String RUN_MODE = "runmode"; - static final String UPGRADE_EVENT = "upgradeevent"; + static final String RUN_MODE = "runmode"; + static final String UPGRADE_EVENT = "upgradeevent"; private Lifecycle() {} } @@ -260,14 +262,15 @@ private EventHub() {} static class PreviewKeys { // Target preview Constants - static final String PREVIEW_PARAMETERS = "at_preview_params"; - static final String PREVIEW_TOKEN = "at_preview_token"; - static final String PREVIEW_ENDPOINT = "at_preview_endpoint"; - static final String DEFAULT_TARGET_PREVIEW_ENDPOINT = "hal.testandtarget.omniture.com"; - static final String DEEPLINK = "deeplink"; + static final String PREVIEW_PARAMETERS = "at_preview_params"; + static final String PREVIEW_TOKEN = "at_preview_token"; + static final String PREVIEW_ENDPOINT = "at_preview_endpoint"; + static final String DEFAULT_TARGET_PREVIEW_ENDPOINT = "hal.testandtarget.omniture.com"; + static final String DEEPLINK = "deeplink"; static final String DEEPLINK_SCHEME = "adbinapp"; static final String DEEPLINK_SCHEME_PATH_CANCEL = "cancel"; static final String DEEPLINK_SCHEME_PATH_CONFIRM = "confirm"; + private PreviewKeys() {} } -} \ No newline at end of file +} diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetErrors.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetErrors.java index f7dfd04..dd0063d 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetErrors.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetErrors.java @@ -1,56 +1,67 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; final class TargetErrors { - static final String NO_CLIENT_CODE = "Missing client code"; - static final String NOT_OPTED_IN = "Privacy status is not opted in"; - static final String NO_PREFETCH_REQUESTS = "Empty or null prefetch requests list"; - static final String NO_CONNECTION = "Unable to open connection"; - static final String NULL_RESPONSE_JSON = "Null response Json"; - static final String ERROR_RESPONSE = "Errors returned in Target response: "; - static final String NOTIFICATION_ERROR_TAG = "Notification"; - static final String NO_PREFETCH_MBOXES = "No prefetch mbox content in Target response"; - static final String MBOX_NAME_NULL_OR_EMPTY = "MboxName is either null or empty"; - static final String MBOX_NAMES_NULL_OR_EMPTY = "MboxNames List is either null or empty"; - static final String NO_TARGET_REQUESTS = "No valid Target Request found."; - static final String PARAMS_SERIALIZATION_FAILED = "TargetParameters serialization failed"; - static final String NETWORK_SERVICE_UNAVAILABLE = "Unable to send target request, Network service is not available"; - static final String REQUEST_BUILDER_INIT_FAILED = "Couldn't initialize the target request builder for this request"; - static final String REQUEST_BUILDER_INIT_FAILED_NOTIFICATIONS = - "Couldn't initialize the target request builder to extract the notifications"; - static final String REQUEST_GENERATION_FAILED = "Failed to generate the Target request payload"; - static final String UNEXPECTED_VISITORIDS_LIST = "The serialized visitorIdsList received as parameter is not a list %s"; - static final String NO_CACHED_MBOX_FOUND = "No cached mbox found for %s"; - static final String TOKEN_LIST_EMPTY_OR_NULL = "Tokens list is null or empty in the view notification object"; - static final String DISPLAY_NOTIFICATION_SEND_FAILED = "Unable to send display notification: %s"; - static final String DISPLAY_NOTIFICATION_CREATE_FAILED = "Failed to create display notification Json(%s)"; - static final String DISPLAY_NOTIFICATION_TOKEN_EMPTY = - "Unable to create display notification as token is null or empty"; - static final String DISPLAY_NOTIFICATION_NOT_SENT = "No display notifications are available to send"; - static final String DISPLAY_NOTIFICATION_NULL_FOR_MBOX = "No display notifications are available to send for mbox %s"; - static final String CLICK_NOTIFICATION_SEND_FAILED = "Unable to send click notification: "; - static final String CLICK_NOTIFICATION_NOT_SENT = "No click notifications are available to send"; - static final String NO_CLICK_METRICS = "No click metrics set on mbox: %s"; - static final String NO_CLICK_METRIC_FOUND = "No click metric found on mbox: %s"; - static final String CLICK_NOTIFICATION_CREATE_FAILED = "Failed to create click notification Json(%s)"; - static final String NO_PREFETCH_IN_PREVIEW = "Target prefetch can't be used while in preview mode"; - static final String TARGET_NOT_ENABLED_FOR_PREVIEW = "Target is not enabled, cannot enter in preview mode: %s"; - static final String TARGET_PREVIEW_DISABLED = - "Target Preview is disabled, please change the configuration and try again"; - static final String TARGET_THIRD_PARTY_ID_NOT_PERSISTED = "Failed to persist thirdPartyId, %s"; - static final String TARGET_TNT_ID_NOT_PERSISTED = "Failed to persist tntID, %s"; - static final String TARGET_SESSION_ID_NOT_PERSISTED = "Failed to persist session id, %s"; + static final String NO_CLIENT_CODE = "Missing client code"; + static final String NOT_OPTED_IN = "Privacy status is not opted in"; + static final String NO_PREFETCH_REQUESTS = "Empty or null prefetch requests list"; + static final String NO_CONNECTION = "Unable to open connection"; + static final String NULL_RESPONSE_JSON = "Null response Json"; + static final String ERROR_RESPONSE = "Errors returned in Target response: "; + static final String NOTIFICATION_ERROR_TAG = "Notification"; + static final String NO_PREFETCH_MBOXES = "No prefetch mbox content in Target response"; + static final String MBOX_NAME_NULL_OR_EMPTY = "MboxName is either null or empty"; + static final String MBOX_NAMES_NULL_OR_EMPTY = "MboxNames List is either null or empty"; + static final String NO_TARGET_REQUESTS = "No valid Target Request found."; + static final String PARAMS_SERIALIZATION_FAILED = "TargetParameters serialization failed"; + static final String NETWORK_SERVICE_UNAVAILABLE = + "Unable to send target request, Network service is not available"; + static final String REQUEST_BUILDER_INIT_FAILED = + "Couldn't initialize the target request builder for this request"; + static final String REQUEST_BUILDER_INIT_FAILED_NOTIFICATIONS = + "Couldn't initialize the target request builder to extract the notifications"; + static final String REQUEST_GENERATION_FAILED = "Failed to generate the Target request payload"; + static final String UNEXPECTED_VISITORIDS_LIST = + "The serialized visitorIdsList received as parameter is not a list %s"; + static final String NO_CACHED_MBOX_FOUND = "No cached mbox found for %s"; + static final String TOKEN_LIST_EMPTY_OR_NULL = + "Tokens list is null or empty in the view notification object"; + static final String DISPLAY_NOTIFICATION_SEND_FAILED = + "Unable to send display notification: %s"; + static final String DISPLAY_NOTIFICATION_CREATE_FAILED = + "Failed to create display notification Json(%s)"; + static final String DISPLAY_NOTIFICATION_TOKEN_EMPTY = + "Unable to create display notification as token is null or empty"; + static final String DISPLAY_NOTIFICATION_NOT_SENT = + "No display notifications are available to send"; + static final String DISPLAY_NOTIFICATION_NULL_FOR_MBOX = + "No display notifications are available to send for mbox %s"; + static final String CLICK_NOTIFICATION_SEND_FAILED = "Unable to send click notification: "; + static final String CLICK_NOTIFICATION_NOT_SENT = + "No click notifications are available to send"; + static final String NO_CLICK_METRICS = "No click metrics set on mbox: %s"; + static final String NO_CLICK_METRIC_FOUND = "No click metric found on mbox: %s"; + static final String CLICK_NOTIFICATION_CREATE_FAILED = + "Failed to create click notification Json(%s)"; + static final String NO_PREFETCH_IN_PREVIEW = + "Target prefetch can't be used while in preview mode"; + static final String TARGET_NOT_ENABLED_FOR_PREVIEW = + "Target is not enabled, cannot enter in preview mode: %s"; + static final String TARGET_PREVIEW_DISABLED = + "Target Preview is disabled, please change the configuration and try again"; + static final String TARGET_THIRD_PARTY_ID_NOT_PERSISTED = "Failed to persist thirdPartyId, %s"; + static final String TARGET_TNT_ID_NOT_PERSISTED = "Failed to persist tntID, %s"; + static final String TARGET_SESSION_ID_NOT_PERSISTED = "Failed to persist session id, %s"; - private TargetErrors() {} + private TargetErrors() {} } diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetExtension.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetExtension.java index 1108f61..190433b 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetExtension.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetExtension.java @@ -1,20 +1,19 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; +import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; - import com.adobe.marketing.mobile.Event; import com.adobe.marketing.mobile.EventSource; import com.adobe.marketing.mobile.EventType; @@ -35,14 +34,11 @@ import com.adobe.marketing.mobile.services.Networking; import com.adobe.marketing.mobile.services.ServiceProvider; import com.adobe.marketing.mobile.services.ui.UIService; +import com.adobe.marketing.mobile.services.uri.UriOpening; import com.adobe.marketing.mobile.util.DataReader; import com.adobe.marketing.mobile.util.DataReaderException; import com.adobe.marketing.mobile.util.JSONUtils; import com.adobe.marketing.mobile.util.StringUtils; - -import org.json.JSONException; -import org.json.JSONObject; - import java.net.HttpURLConnection; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -52,45 +48,54 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.json.JSONException; +import org.json.JSONObject; /** - * Adobe Target is the Adobe Marketing Cloud solution that provides everything you need to tailor and personalize your customers - * experience on mobile application. - *

- * It helps you to deliver targeted content within your mobile Application. - * The extension will provide a way to react to public facing Target APIs to make target request and get responses through asynchronous callbacks. - * Returns an instance of the Target extension. Adds all the Listeners to the provided EventHub. - * The Target extension listens for the following {@link Event}s: + * Adobe Target is the Adobe Marketing Cloud solution that provides everything you need to tailor + * and personalize your customers experience on mobile application. + * + *

It helps you to deliver targeted content within your mobile Application. The extension will + * provide a way to react to public facing Target APIs to make target request and get responses + * through asynchronous callbacks. Returns an instance of the Target extension. Adds all the + * Listeners to the provided EventHub. The Target extension listens for the following {@link + * Event}s: + * *

    - *
  1. {@link EventType#TARGET} - {@link EventSource#REQUEST_CONTENT}
  2. - *
  3. {@code EventType#TARGET} - {@link EventSource#REQUEST_RESET}
  4. - *
  5. {@code EventType#TARGET} - {@link EventSource#REQUEST_IDENTITY}
  6. - *
  7. {@code EventType#GENERIC_DATA} - {@link EventSource#OS}
  8. - *
  9. {@link EventType#CONFIGURATION} - {@link EventSource#RESPONSE_CONTENT}
  10. + *
  11. {@link EventType#TARGET} - {@link EventSource#REQUEST_CONTENT} + *
  12. {@code EventType#TARGET} - {@link EventSource#REQUEST_RESET} + *
  13. {@code EventType#TARGET} - {@link EventSource#REQUEST_IDENTITY} + *
  14. {@code EventType#GENERIC_DATA} - {@link EventSource#OS} + *
  15. {@link EventType#CONFIGURATION} - {@link EventSource#RESPONSE_CONTENT} *
- *

- * The Target extension dispatches the following {@code Event}s: + * + *

The Target extension dispatches the following {@code Event}s: + * *

    - *
  1. {@code EventType#TARGET} - {@code EventSource#RESPONSE_CONTENT}
  2. - *
  3. {@code EventType#TARGET} - {@code EventSource#RESPONSE_IDENTITY}
  4. - *
  5. {@code EventType#TARGET} - {@code EventSource#RESPONSE_IDENTITY}
  6. + *
  7. {@code EventType#TARGET} - {@code EventSource#RESPONSE_CONTENT} + *
  8. {@code EventType#TARGET} - {@code EventSource#RESPONSE_IDENTITY} + *
  9. {@code EventType#TARGET} - {@code EventSource#RESPONSE_IDENTITY} *
- *

- * The Target extension has dependencies on the following {@link ServiceProvider} services: + * + *

The Target extension has dependencies on the following {@link ServiceProvider} services: + * *

    - *
  1. {@link DataStoring}
  2. - *
  3. {@link Networking}
  4. + *
  5. {@link DataStoring} + *
  6. {@link Networking} *
* * @see ServiceProvider */ public class TargetExtension extends Extension { private static final String CLASS_NAME = "TargetExtension"; - private static final String TARGET_EVENT_DISPATCH_MESSAGE = "Dispatching - Target response content event"; + private static final String TARGET_EVENT_DISPATCH_MESSAGE = + "Dispatching - Target response content event"; private final DeviceInforming deviceInfoService; private final Networking networkService; private final UIService uiService; + private final UriOpening uriService; + private final Context context; private final TargetState targetState; private final TargetResponseParser targetResponseParser; @@ -99,44 +104,49 @@ public class TargetExtension extends Extension { /** * Constructor for {@code TargetExtension}. - *

- * It is invoked during the extension registration to retrieve the extension's details such as name and version. + * + *

It is invoked during the extension registration to retrieve the extension's details such + * as name and version. * * @param extensionApi {@link ExtensionApi} instance. */ protected TargetExtension(final ExtensionApi extensionApi) { - super(extensionApi); - - deviceInfoService = ServiceProvider.getInstance().getDeviceInfoService(); - NamedCollection dataStore = ServiceProvider.getInstance().getDataStoreService().getNamedCollection(TargetConstants.DATA_STORE_KEY); - networkService = ServiceProvider.getInstance().getNetworkService(); - uiService = ServiceProvider.getInstance().getUIService(); - - targetState = new TargetState(dataStore); - targetResponseParser = new TargetResponseParser(); - targetPreviewManager = new TargetPreviewManager(networkService, uiService); - targetRequestBuilder = getRequestBuilder(); + this(extensionApi, null, null, null, null); } /** * Constructor for {@code TargetExtension}. - *

- * Used only for Testing purposes. + * + *

Used only for Testing purposes. * * @param extensionApi {@link ExtensionApi} instance. */ @VisibleForTesting - protected TargetExtension(final ExtensionApi extensionApi, final DeviceInforming deviceInfoService, final Networking networkService, - final UIService uiService, final TargetState targetState, final TargetPreviewManager targetPreviewManager, - final TargetRequestBuilder requestBuilder, final TargetResponseParser responseParser) { + protected TargetExtension( + final ExtensionApi extensionApi, + final TargetState targetState, + final TargetPreviewManager targetPreviewManager, + final TargetRequestBuilder requestBuilder, + final TargetResponseParser responseParser) { super(extensionApi); - this.deviceInfoService = deviceInfoService; - this.networkService = networkService; - this.uiService = uiService; - this.targetState = targetState; - this.targetPreviewManager = targetPreviewManager; - this.targetRequestBuilder = requestBuilder; - this.targetResponseParser = responseParser; + deviceInfoService = ServiceProvider.getInstance().getDeviceInfoService(); + NamedCollection dataStore = + ServiceProvider.getInstance() + .getDataStoreService() + .getNamedCollection(TargetConstants.DATA_STORE_KEY); + networkService = ServiceProvider.getInstance().getNetworkService(); + uiService = ServiceProvider.getInstance().getUIService(); + uriService = ServiceProvider.getInstance().getUriService(); + context = ServiceProvider.getInstance().getAppContextService().getApplicationContext(); + + this.targetState = targetState != null ? targetState : new TargetState(dataStore); + this.targetPreviewManager = + targetPreviewManager != null + ? targetPreviewManager + : new TargetPreviewManager(networkService, uiService, uriService, context); + this.targetRequestBuilder = requestBuilder != null ? requestBuilder : getRequestBuilder(); + this.targetResponseParser = + responseParser != null ? responseParser : new TargetResponseParser(); } /** @@ -144,8 +154,7 @@ protected TargetExtension(final ExtensionApi extensionApi, final DeviceInforming * * @return {@link String} containing the unique name for this extension. */ - @NonNull - @Override + @NonNull @Override protected String getName() { return TargetConstants.EXTENSION_NAME; } @@ -156,7 +165,9 @@ protected String getName() { * @return {@link String} containing the friendly name for this extension. */ @Override - protected String getFriendlyName() { return TargetConstants.FRIENDLY_NAME; } + protected String getFriendlyName() { + return TargetConstants.FRIENDLY_NAME; + } /** * Retrieve the extension version. @@ -176,17 +187,33 @@ public boolean readyForEvent(@NonNull final Event event) { @Override protected void onRegistered() { - getApi().registerEventListener(EventType.TARGET, EventSource.REQUEST_CONTENT, this::handleTargetRequestContentEvent); - getApi().registerEventListener(EventType.TARGET, EventSource.REQUEST_RESET, this::handleTargetRequestResetEvent); - getApi().registerEventListener(EventType.TARGET, EventSource.REQUEST_IDENTITY, this::handleTargetRequestIdentityEvent); - getApi().registerEventListener(EventType.GENERIC_DATA, EventSource.OS, this::handleGenericDataOSEvent); - getApi().registerEventListener(EventType.CONFIGURATION, EventSource.RESPONSE_CONTENT, this::handleConfigurationResponseContentEvent); + getApi().registerEventListener( + EventType.TARGET, + EventSource.REQUEST_CONTENT, + this::handleTargetRequestContentEvent); + getApi().registerEventListener( + EventType.TARGET, + EventSource.REQUEST_RESET, + this::handleTargetRequestResetEvent); + getApi().registerEventListener( + EventType.TARGET, + EventSource.REQUEST_IDENTITY, + this::handleTargetRequestIdentityEvent); + getApi().registerEventListener( + EventType.GENERIC_DATA, EventSource.OS, this::handleGenericDataOSEvent); + getApi().registerEventListener( + EventType.CONFIGURATION, + EventSource.RESPONSE_CONTENT, + this::handleConfigurationResponseContentEvent); } void handleTargetRequestContentEvent(@NonNull final Event event) { if (TargetUtils.isNullOrEmpty(event.getEventData())) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "handleTargetRequestContentEvent - Failed to process Target request content event, event data is null/ empty."); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleTargetRequestContentEvent - Failed to process Target request content" + + " event, event data is null/ empty."); return; } @@ -200,15 +227,25 @@ void handleTargetRequestContentEvent(@NonNull final Event event) { if (eventData.containsKey(TargetConstants.EventDataKeys.PREFETCH)) { final List> flattenedPrefetchRequests; try { - flattenedPrefetchRequests = (List>) eventData.get(TargetConstants.EventDataKeys.PREFETCH); + flattenedPrefetchRequests = + (List>) + eventData.get(TargetConstants.EventDataKeys.PREFETCH); } catch (final ClassCastException e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "handleTargetRequestContentEvent - Failed to get TargetExtension Prefetch list from event data, %s", e); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleTargetRequestContentEvent - Failed to get TargetExtension Prefetch" + + " list from event data, %s", + e); return; } if (TargetUtils.isNullOrEmpty(flattenedPrefetchRequests)) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "handleTargetRequestContentEvent -Failed to retrieve Target Prefetch list (%s)", TargetErrors.NO_PREFETCH_REQUESTS); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleTargetRequestContentEvent -Failed to retrieve Target Prefetch list" + + " (%s)", + TargetErrors.NO_PREFETCH_REQUESTS); dispatchMboxPrefetchResult(TargetErrors.NO_PREFETCH_REQUESTS, event); return; } @@ -226,15 +263,25 @@ void handleTargetRequestContentEvent(@NonNull final Event event) { if (eventData.containsKey(TargetConstants.EventDataKeys.LOAD_REQUEST)) { final List> flattenedLocationRequests; try { - flattenedLocationRequests = (List>) eventData.get(TargetConstants.EventDataKeys.LOAD_REQUEST); + flattenedLocationRequests = + (List>) + eventData.get(TargetConstants.EventDataKeys.LOAD_REQUEST); } catch (final ClassCastException e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "handleTargetRequestContentEvent - Failed to get Target Request list from event data, %s", e); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleTargetRequestContentEvent - Failed to get Target Request list from" + + " event data, %s", + e); return; } if (TargetUtils.isNullOrEmpty(flattenedLocationRequests)) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "handleTargetRequestContentEvent -Failed to retrieve Target location content (%s)", TargetErrors.NO_TARGET_REQUESTS); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleTargetRequestContentEvent -Failed to retrieve Target location" + + " content (%s)", + TargetErrors.NO_TARGET_REQUESTS); return; } final List targetRequests = new ArrayList<>(); @@ -248,17 +295,21 @@ void handleTargetRequestContentEvent(@NonNull final Event event) { return; } - if ( DataReader.optBoolean(eventData, TargetConstants.EventDataKeys.IS_LOCATION_DISPLAYED, false)) { + if (DataReader.optBoolean( + eventData, TargetConstants.EventDataKeys.IS_LOCATION_DISPLAYED, false)) { handleLocationsDisplayed(event); return; } - if (DataReader.optBoolean(eventData, TargetConstants.EventDataKeys.IS_LOCATION_CLICKED, false)) { + if (DataReader.optBoolean( + eventData, TargetConstants.EventDataKeys.IS_LOCATION_CLICKED, false)) { handleLocationClicked(event); return; } - final String restartDeeplink = DataReader.optString(eventData, TargetConstants.EventDataKeys.PREVIEW_RESTART_DEEP_LINK, null); + final String restartDeeplink = + DataReader.optString( + eventData, TargetConstants.EventDataKeys.PREVIEW_RESTART_DEEP_LINK, null); if (!StringUtils.isNullOrEmpty(restartDeeplink)) { setPreviewRestartDeepLink(restartDeeplink); } @@ -266,18 +317,23 @@ void handleTargetRequestContentEvent(@NonNull final Event event) { void handleTargetRequestResetEvent(@NonNull final Event event) { if (TargetUtils.isNullOrEmpty(event.getEventData())) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "handleTargetRequestResetEvent - Failed to process Target request content event, event data is null/ empty."); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleTargetRequestResetEvent - Failed to process Target request content" + + " event, event data is null/ empty."); return; } final Map eventData = event.getEventData(); - if (DataReader.optBoolean(eventData, TargetConstants.EventDataKeys.RESET_EXPERIENCE, false)) { + if (DataReader.optBoolean( + eventData, TargetConstants.EventDataKeys.RESET_EXPERIENCE, false)) { resetIdentity(event); return; } - if (DataReader.optBoolean(eventData, TargetConstants.EventDataKeys.CLEAR_PREFETCH_CACHE, false)) { + if (DataReader.optBoolean( + eventData, TargetConstants.EventDataKeys.CLEAR_PREFETCH_CACHE, false)) { targetState.clearPrefetchedMboxes(); } } @@ -290,26 +346,35 @@ void handleTargetRequestIdentityEvent(@NonNull final Event event) { } if (eventData.containsKey(TargetConstants.EventDataKeys.THIRD_PARTY_ID)) { - final String thirdPartyId = DataReader.optString(eventData, TargetConstants.EventDataKeys.THIRD_PARTY_ID, null); + final String thirdPartyId = + DataReader.optString( + eventData, TargetConstants.EventDataKeys.THIRD_PARTY_ID, null); setThirdPartyIdInternal(thirdPartyId); getApi().createSharedState(targetState.generateSharedState(), event); } else if (eventData.containsKey(TargetConstants.EventDataKeys.TNT_ID)) { - final String tntId = DataReader.optString(eventData, TargetConstants.EventDataKeys.TNT_ID, null); + final String tntId = + DataReader.optString(eventData, TargetConstants.EventDataKeys.TNT_ID, null); setTntIdInternal(tntId); getApi().createSharedState(targetState.generateSharedState(), event); } else if (eventData.containsKey(TargetConstants.EventDataKeys.SESSION_ID)) { - final String sessionId = DataReader.optString(eventData, TargetConstants.EventDataKeys.SESSION_ID, null); + final String sessionId = + DataReader.optString(eventData, TargetConstants.EventDataKeys.SESSION_ID, null); setSessionId(sessionId); } } void handleGenericDataOSEvent(@NonNull final Event event) { if (TargetUtils.isNullOrEmpty(event.getEventData())) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "handleGenericDataOSEvent - Failed to process Generic os event, event data is null/ empty."); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleGenericDataOSEvent - Failed to process Generic os event, event data is" + + " null/ empty."); return; } - final String deepLink = DataReader.optString(event.getEventData(), TargetConstants.PreviewKeys.DEEPLINK, null); + final String deepLink = + DataReader.optString( + event.getEventData(), TargetConstants.PreviewKeys.DEEPLINK, null); if (!StringUtils.isNullOrEmpty(deepLink)) { setupPreviewMode(deepLink); @@ -317,11 +382,19 @@ void handleGenericDataOSEvent(@NonNull final Event event) { } void handleConfigurationResponseContentEvent(@NonNull final Event event) { - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, "handleConfigurationResponse - event %s type: %s source: %s ", event.getName(), - event.getType(), event.getSource()); + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleConfigurationResponse - event %s type: %s source: %s ", + event.getName(), + event.getType(), + event.getSource()); if (targetState.getMobilePrivacyStatus() == MobilePrivacyStatus.OPT_OUT) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "handleConfigurationResponse - Clearing saved identities"); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleConfigurationResponse - Clearing saved identities"); resetIdentity(); // identifiers are cleared now, set shared state @@ -332,7 +405,8 @@ void handleConfigurationResponseContentEvent(@NonNull final Event event) { /** * Sets the preview restart url in the target preview manager. * - * @param deepLink the {@link String} deep link received from the public API - SetPreviewRestartDeeplink + * @param deepLink the {@link String} deep link received from the public API - + * SetPreviewRestartDeeplink */ void setPreviewRestartDeepLink(final String deepLink) { targetPreviewManager.setRestartDeepLink(deepLink); @@ -344,78 +418,115 @@ void setPreviewRestartDeepLink(final String deepLink) { * @param event the incoming {@link Event} object. */ void handleRawRequest(@NonNull final Event event) { - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, "Processing the raw Target request - event %s type: %s source: %s ", - event.getName(), event.getType(), + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Processing the raw Target request - event %s type: %s source: %s ", + event.getName(), + event.getType(), event.getSource()); final Map eventData = event.getEventData(); try { - final Map id = DataReader.getTypedMap(Object.class, eventData, TargetConstants.EventDataKeys.ID); - final Map context = DataReader.getTypedMap(Object.class, eventData, TargetConstants.EventDataKeys.CONTEXT); - final Map experienceCloud = DataReader.getTypedMap(Object.class, eventData, TargetConstants.EventDataKeys.EXPERIENCE_CLOUD); - final Map execute = DataReader.getTypedMap(Object.class, eventData, TargetConstants.EventDataKeys.EXECUTE); - final Map prefetch = DataReader.getTypedMap(Object.class, eventData, TargetConstants.EventDataKeys.PREFETCH); - final List> notifications = DataReader.getTypedListOfMap(Object.class, eventData, TargetConstants.EventDataKeys.NOTIFICATIONS); + final Map id = + DataReader.getTypedMap( + Object.class, eventData, TargetConstants.EventDataKeys.ID); + final Map context = + DataReader.getTypedMap( + Object.class, eventData, TargetConstants.EventDataKeys.CONTEXT); + final Map experienceCloud = + DataReader.getTypedMap( + Object.class, + eventData, + TargetConstants.EventDataKeys.EXPERIENCE_CLOUD); + final Map execute = + DataReader.getTypedMap( + Object.class, eventData, TargetConstants.EventDataKeys.EXECUTE); + final Map prefetch = + DataReader.getTypedMap( + Object.class, eventData, TargetConstants.EventDataKeys.PREFETCH); + final List> notifications = + DataReader.getTypedListOfMap( + Object.class, eventData, TargetConstants.EventDataKeys.NOTIFICATIONS); final boolean isContentRequest = (prefetch != null) || (execute != null); if (networkService == null) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, "handleRawRequest - (%s)", TargetErrors.NETWORK_SERVICE_UNAVAILABLE); + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleRawRequest - (%s)", + TargetErrors.NETWORK_SERVICE_UNAVAILABLE); dispatchTargetRawResponseIfNeeded(isContentRequest, null, event); return; } if (targetRequestBuilder == null) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, "handleRawRequest - (%s)", TargetErrors.REQUEST_BUILDER_INIT_FAILED); + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleRawRequest - (%s)", + TargetErrors.REQUEST_BUILDER_INIT_FAILED); dispatchTargetRawResponseIfNeeded(isContentRequest, null, event); return; } String propertyToken = targetState.getPropertyToken(); if (StringUtils.isNullOrEmpty(propertyToken)) { - final Map property = DataReader.getTypedMap(Object.class, eventData, TargetConstants.EventDataKeys.PROPERTY); + final Map property = + DataReader.getTypedMap( + Object.class, eventData, TargetConstants.EventDataKeys.PROPERTY); if (!TargetUtils.isNullOrEmpty(property)) { - propertyToken = DataReader.optString(property, TargetConstants.EventDataKeys.TOKEN, ""); + propertyToken = + DataReader.optString(property, TargetConstants.EventDataKeys.TOKEN, ""); } } long environmentId = targetState.getEnvironmentId(); if (environmentId == 0) { - environmentId = DataReader.optLong(eventData, TargetConstants.EventDataKeys.ENVIRONMENT_ID, 0L); + environmentId = + DataReader.optLong( + eventData, TargetConstants.EventDataKeys.ENVIRONMENT_ID, 0L); } final String sendRequestError = prepareForTargetRequest(); if (sendRequestError != null) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, "handleRawRequest - ", sendRequestError); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleRawRequest - ", + sendRequestError); dispatchTargetRawResponseIfNeeded(isContentRequest, null, event); return; } - final JSONObject defaultJsonObject = targetRequestBuilder.getDefaultJsonObject( - id, - context, - experienceCloud, - environmentId, - retrieveIdentitySharedState(event)); + final JSONObject defaultJsonObject = + targetRequestBuilder.getDefaultJsonObject( + id, + context, + experienceCloud, + environmentId, + retrieveIdentitySharedState(event)); - final JSONObject payloadJson = targetRequestBuilder.getRequestPayload( - defaultJsonObject, - prefetch, - execute, - notifications, - propertyToken); + final JSONObject payloadJson = + targetRequestBuilder.getRequestPayload( + defaultJsonObject, prefetch, execute, notifications, propertyToken); if (JSONUtils.isNullOrEmpty(payloadJson)) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "handleRawRequest - Cannot send raw Target request, payload json is null or empty."); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleRawRequest - Cannot send raw Target request, payload json is null or" + + " empty."); dispatchTargetRawResponseIfNeeded(isContentRequest, null, event); return; } final Map eventHubData = retrieveEventHubSharedState(event); final Map headers = new HashMap<>(); - headers.put(TargetConstants.HEADER_CONTENT_TYPE, TargetConstants.HEADER_CONTENT_TYPE_JSON); + headers.put( + TargetConstants.HEADER_CONTENT_TYPE, TargetConstants.HEADER_CONTENT_TYPE_JSON); headers.put(TargetConstants.HEADER_X_EXC_SDK, getSdkInfo(eventHubData)); headers.put(TargetConstants.HEADER_X_EXC_SDK_VERSION, getSdkVersion(eventHubData)); @@ -423,30 +534,49 @@ void handleRawRequest(@NonNull final Event event) { final String payloadJsonString = payloadJson.toString(); final byte[] payload = payloadJsonString.getBytes(StandardCharsets.UTF_8); final int timeout = targetState.getNetworkTimeout(); - final NetworkRequest networkRequest = new NetworkRequest(url, HttpMethod.POST, payload, headers, timeout, timeout); - - Log.debug(TargetConstants.LOG_TAG, "handleRawRequest - Target request was sent with url %s, body %s", url, payloadJsonString); - - networkService.connectAsync(networkRequest, connection -> { - processTargetRawResponse(connection, isContentRequest, event); - }); + final NetworkRequest networkRequest = + new NetworkRequest(url, HttpMethod.POST, payload, headers, timeout, timeout); + + Log.debug( + TargetConstants.LOG_TAG, + "handleRawRequest - Target request was sent with url %s, body %s", + url, + payloadJsonString); + + networkService.connectAsync( + networkRequest, + connection -> { + processTargetRawResponse(connection, isContentRequest, event); + }); } catch (final DataReaderException e) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "handleRawRequest - Cannot process the raw Target request, the provided request data is invalid (%s).", e.getMessage()); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleRawRequest - Cannot process the raw Target request, the provided request" + + " data is invalid (%s).", + e.getMessage()); } } /** - * Prefetch multiple Target mboxes in a single network call. - * The content will be cached locally and returned immediately if any prefetched mbox is requested though a loadRequest call. + * Prefetch multiple Target mboxes in a single network call. The content will be cached locally + * and returned immediately if any prefetched mbox is requested though a loadRequest call. * - * @param targetPrefetchRequests an {@code List} representing the desired mboxes to prefetch - * @param event the {@link Event} object + * @param targetPrefetchRequests an {@code List} representing the desired mboxes + * to prefetch + * @param event the {@link Event} object */ - void handleMboxPrefetch(@NonNull final List targetPrefetchRequests, @NonNull final Event event) { - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, - "handleMboxPrefetch - Prefetched mbox event details - event %s type: %s source: %s ", - event.getName(), event.getType(), event.getSource()); + void handleMboxPrefetch( + @NonNull final List targetPrefetchRequests, + @NonNull final Event event) { + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleMboxPrefetch - Prefetched mbox event details - event %s type: %s source: %s" + + " ", + event.getName(), + event.getType(), + event.getSource()); if (inPreviewMode()) { Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.NO_PREFETCH_IN_PREVIEW); @@ -455,31 +585,46 @@ void handleMboxPrefetch(@NonNull final List targetPrefetchReques } final Map eventData = event.getEventData(); - final Map targetParametersMap = DataReader.optTypedMap(Object.class, - eventData, TargetConstants.EventDataKeys.TARGET_PARAMETERS, null); - final TargetParameters targetParameters = TargetParameters.fromEventData(targetParametersMap); + final Map targetParametersMap = + DataReader.optTypedMap( + Object.class, + eventData, + TargetConstants.EventDataKeys.TARGET_PARAMETERS, + null); + final TargetParameters targetParameters = + TargetParameters.fromEventData(targetParametersMap); final Map lifecycleData = retrieveLifecycleSharedState(event); final Map identityData = retrieveIdentitySharedState(event); - prefetchMboxContent(targetPrefetchRequests, targetParameters, lifecycleData, identityData, - event); + prefetchMboxContent( + targetPrefetchRequests, targetParameters, lifecycleData, identityData, event); } /** * Request multiple Target mboxes in a single network call. * - * @param targetRequests an {@code List} representing the desired mboxes to load - * @param event the {@link Event} object + * @param targetRequests an {@code List} representing the desired mboxes to load + * @param event the {@link Event} object */ - void loadRequests(@NonNull final List targetRequests, @NonNull final Event event) { - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, + void loadRequests( + @NonNull final List targetRequests, @NonNull final Event event) { + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, "loadRequests - event %s type: %s source: %s ", - event.getName(), event.getType(), event.getSource()); + event.getName(), + event.getType(), + event.getSource()); final Map eventData = event.getEventData(); - final Map targetParametersMap = DataReader.optTypedMap(Object.class, - eventData, TargetConstants.EventDataKeys.TARGET_PARAMETERS, null); - final TargetParameters targetParameters = TargetParameters.fromEventData(targetParametersMap); + final Map targetParametersMap = + DataReader.optTypedMap( + Object.class, + eventData, + TargetConstants.EventDataKeys.TARGET_PARAMETERS, + null); + final TargetParameters targetParameters = + TargetParameters.fromEventData(targetParametersMap); final Map lifecycleData = retrieveLifecycleSharedState(event); final Map identityData = retrieveIdentitySharedState(event); @@ -488,48 +633,66 @@ void loadRequests(@NonNull final List targetRequests, @NonNull fi /** * Sends display notifications to Target - *

- * Reads the display tokens from the cache either {@link TargetState#getPrefetchedMbox()} or - * {@link TargetState#getLoadedMbox()} to send the display notifications. - * The display notification is not sent if, + * + *

Reads the display tokens from the cache either {@link TargetState#getPrefetchedMbox()} or + * {@link TargetState#getLoadedMbox()} to send the display notifications. The display + * notification is not sent if, + * *

    - *
  1. Target Extension is not configured.
  2. - *
  3. Privacy status is opted-out or opt-unknown.
  4. - *
  5. If the mboxes are either loaded previously or not prefetched.
  6. + *
  7. Target Extension is not configured. + *
  8. Privacy status is opted-out or opt-unknown. + *
  9. If the mboxes are either loaded previously or not prefetched. *
* * @param event the {@link Event} object */ void handleLocationsDisplayed(@NonNull final Event event) { - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, "handleLocationsDisplayed - event %s type: %s source: %s ", - event.getName(), event.getType(), event.getSource()); + event.getName(), + event.getType(), + event.getSource()); final String sendRequestError = prepareForTargetRequest(); if (sendRequestError != null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.DISPLAY_NOTIFICATION_SEND_FAILED, + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + TargetErrors.DISPLAY_NOTIFICATION_SEND_FAILED, sendRequestError); return; } final Map eventData = event.getEventData(); - final List mboxNames = DataReader.optStringList(eventData, TargetConstants.EventDataKeys.MBOX_NAMES, null); + final List mboxNames = + DataReader.optStringList(eventData, TargetConstants.EventDataKeys.MBOX_NAMES, null); if (TargetUtils.isNullOrEmpty(mboxNames)) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "Location displayed unsuccessful (%s) ", TargetErrors.MBOX_NAMES_NULL_OR_EMPTY); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Location displayed unsuccessful (%s) ", + TargetErrors.MBOX_NAMES_NULL_OR_EMPTY); return; } - final Map targetParametersMap = DataReader.optTypedMap(Object.class, - eventData, TargetConstants.EventDataKeys.TARGET_PARAMETERS, null); - final TargetParameters targetParameters = TargetParameters.fromEventData(targetParametersMap); + final Map targetParametersMap = + DataReader.optTypedMap( + Object.class, + eventData, + TargetConstants.EventDataKeys.TARGET_PARAMETERS, + null); + final TargetParameters targetParameters = + TargetParameters.fromEventData(targetParametersMap); final Map lifecycleData = retrieveLifecycleSharedState(event); final Map identityData = retrieveIdentitySharedState(event); for (String mboxName : mboxNames) { // If loadedMbox contains mboxName then do not send analytics request again - if (StringUtils.isNullOrEmpty(mboxName) || targetState.getLoadedMbox().containsKey(mboxName)) { + if (StringUtils.isNullOrEmpty(mboxName) + || targetState.getLoadedMbox().containsKey(mboxName)) { continue; } @@ -537,73 +700,100 @@ void handleLocationsDisplayed(@NonNull final Event event) { if (targetState.getPrefetchedMbox().containsKey(mboxName)) { mboxJson = targetState.getPrefetchedMbox().get(mboxName); } else { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - TargetErrors.DISPLAY_NOTIFICATION_SEND_FAILED + TargetErrors.NO_CACHED_MBOX_FOUND, + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + TargetErrors.DISPLAY_NOTIFICATION_SEND_FAILED + + TargetErrors.NO_CACHED_MBOX_FOUND, mboxName); continue; } - if (!addDisplayNotification(mboxName, mboxJson, targetParameters, lifecycleData, event.getTimestamp())) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, + if (!addDisplayNotification( + mboxName, mboxJson, targetParameters, lifecycleData, event.getTimestamp())) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, "handleLocationsDisplayed - %s mBox not added for display notification.", mboxName); continue; } - dispatchAnalyticsForTargetRequest(targetResponseParser.getAnalyticsForTargetPayload(mboxJson, - targetState.getSessionId())); + dispatchAnalyticsForTargetRequest( + targetResponseParser.getAnalyticsForTargetPayload( + mboxJson, targetState.getSessionId())); } if (targetState.getNotifications().isEmpty()) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME,"handleLocationsDisplayed - " + TargetErrors.DISPLAY_NOTIFICATION_NOT_SENT); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleLocationsDisplayed - " + TargetErrors.DISPLAY_NOTIFICATION_NOT_SENT); return; } - sendTargetRequest(null, null, targetParameters, + sendTargetRequest( + null, + null, + targetParameters, lifecycleData, - identityData, event, connection -> { + identityData, + event, + connection -> { processNotificationResponse(connection, event); }); } /** - * Sends a click notification to Target if click metrics are enabled for the provided location name. - *

- * Reads the clicked token from the cached either {@link TargetState#getPrefetchedMbox()} or - * {@link TargetState#getLoadedMbox()} to send the click notification. - * The clicked notification is not sent if, + * Sends a click notification to Target if click metrics are enabled for the provided location + * name. + * + *

Reads the clicked token from the cached either {@link TargetState#getPrefetchedMbox()} or + * {@link TargetState#getLoadedMbox()} to send the click notification. The clicked notification + * is not sent if, + * *

    - *
  1. Target Extension is not configured.
  2. - *
  3. Privacy status is opted-out or opt-unknown.
  4. - *
  5. If the mbox is either not prefetched or loaded previously.
  6. - *
  7. If the clicked token is empty or null for the loaded mbox.
  8. + *
  9. Target Extension is not configured. + *
  10. Privacy status is opted-out or opt-unknown. + *
  11. If the mbox is either not prefetched or loaded previously. + *
  12. If the clicked token is empty or null for the loaded mbox. *
* - * @param event the {@link Event} object + * @param event the {@link Event} object */ void handleLocationClicked(@NonNull final Event event) { - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, - "handleLocationClicked - event %s type: %s source: %s ", event.getName(), - event.getType(), event.getSource()); + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, + "handleLocationClicked - event %s type: %s source: %s ", + event.getName(), + event.getType(), + event.getSource()); // bail out if the target configuration is not available or if the privacy is opted-out final String sendRequestError = prepareForTargetRequest(); if (sendRequestError != null) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - TargetErrors.CLICK_NOTIFICATION_SEND_FAILED + sendRequestError); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + TargetErrors.CLICK_NOTIFICATION_SEND_FAILED + sendRequestError); return; } - final Map eventData = event.getEventData(); if (TargetUtils.isNullOrEmpty(eventData)) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, "Location clicked unsuccessful, event data is null or empty "); return; } - final String mboxName = DataReader.optString(eventData, TargetConstants.EventDataKeys.MBOX_NAME, null); + final String mboxName = + DataReader.optString(eventData, TargetConstants.EventDataKeys.MBOX_NAME, null); if (StringUtils.isNullOrEmpty(mboxName)) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, "Location clicked unsuccessful " + TargetErrors.MBOX_NAME_NULL_OR_EMPTY); return; } @@ -616,7 +806,9 @@ void handleLocationClicked(@NonNull final Event event) { } else if (targetState.getLoadedMbox().containsKey(mboxName)) { mboxJson = targetState.getLoadedMbox().get(mboxName); } else { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, TargetErrors.CLICK_NOTIFICATION_SEND_FAILED + TargetErrors.NO_CACHED_MBOX_FOUND, mboxName); return; @@ -624,44 +816,60 @@ void handleLocationClicked(@NonNull final Event event) { final JSONObject clickMetric = targetResponseParser.getClickMetric(mboxJson); if (clickMetric == null) { - Log.warning(TargetConstants.LOG_TAG, - TargetErrors.CLICK_NOTIFICATION_SEND_FAILED + TargetErrors.NO_CLICK_METRIC_FOUND, + Log.warning( + TargetConstants.LOG_TAG, + TargetErrors.CLICK_NOTIFICATION_SEND_FAILED + + TargetErrors.NO_CLICK_METRIC_FOUND, mboxName); return; } // gather the other required shared states - final Map targetParametersMap = DataReader.optTypedMap(Object.class, - eventData, TargetConstants.EventDataKeys.TARGET_PARAMETERS, null); - final TargetParameters targetParameters = TargetParameters.fromEventData(targetParametersMap); + final Map targetParametersMap = + DataReader.optTypedMap( + Object.class, + eventData, + TargetConstants.EventDataKeys.TARGET_PARAMETERS, + null); + final TargetParameters targetParameters = + TargetParameters.fromEventData(targetParametersMap); final Map lifecycleData = retrieveLifecycleSharedState(event); final Map identityData = retrieveIdentitySharedState(event); // create and add click notification to the notification list - if (!addClickedNotificationToList(mboxJson, targetParameters, lifecycleData, event.getTimestamp())) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, + if (!addClickedNotificationToList( + mboxJson, targetParameters, lifecycleData, event.getTimestamp())) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, "handleLocationClicked - %s mBox not added for click notification", mboxName); return; } - final Map clickMetricA4TParams = targetResponseParser.getAnalyticsForTargetPayload(clickMetric); + final Map clickMetricA4TParams = + targetResponseParser.getAnalyticsForTargetPayload(clickMetric); if (!TargetUtils.isNullOrEmpty(clickMetricA4TParams)) { - dispatchAnalyticsForTargetRequest(targetResponseParser.preprocessAnalyticsForTargetPayload( - clickMetricA4TParams, targetState.getSessionId())); + dispatchAnalyticsForTargetRequest( + targetResponseParser.preprocessAnalyticsForTargetPayload( + clickMetricA4TParams, targetState.getSessionId())); } // send network request - sendTargetRequest(null, null, targetParameters, + sendTargetRequest( + null, + null, + targetParameters, lifecycleData, - identityData, event, connection -> processNotificationResponse(connection, event)); - + identityData, + event, + connection -> processNotificationResponse(connection, event)); } /** - * Clears all the current identifiers. - * After clearing the identifiers, creates a shared state at version {@code eventNumber} - * and dispatches an {@link EventType#TARGET} {@link EventSource#REQUEST_RESET} event. + * Clears all the current identifiers. After clearing the identifiers, creates a shared state at + * version {@code eventNumber} and dispatches an {@link EventType#TARGET} {@link + * EventSource#REQUEST_RESET} event. * * @param event the {@link Event} which triggered this method */ @@ -677,14 +885,20 @@ void resetIdentity(@NonNull final Event event) { */ private String prepareForTargetRequest() { if (targetState.getClientCode().isEmpty()) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "prepareForTargetRequest - TargetRequest preparation failed because (%s)", TargetErrors.NO_CLIENT_CODE); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "prepareForTargetRequest - TargetRequest preparation failed because (%s)", + TargetErrors.NO_CLIENT_CODE); return TargetErrors.NO_CLIENT_CODE; } if (targetState.getMobilePrivacyStatus() != MobilePrivacyStatus.OPT_IN) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "prepareForTargetRequest - TargetRequest preparation failed because (%s)", TargetErrors.NOT_OPTED_IN); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "prepareForTargetRequest - TargetRequest preparation failed because (%s)", + TargetErrors.NOT_OPTED_IN); return TargetErrors.NOT_OPTED_IN; } @@ -692,43 +906,53 @@ private String prepareForTargetRequest() { } /** - *

- * This method will determine the correct host name to use. - * In order, the priority is: - * 1. Custom value set in "target.server" configuration setting (see customServer param) - * 2. Edge host returned from previous Target server responses - * 3. Default host created with customer's client code - * {@code String} sessionId and {@code String} clientCode are also sent as query parameters in the Target request url. + * This method will determine the correct host name to use. In order, the priority is: 1. Custom + * value set in "target.server" configuration setting (see customServer param) 2. Edge host + * returned from previous Target server responses 3. Default host created with customer's client + * code {@code String} sessionId and {@code String} clientCode are also sent as query parameters + * in the Target request url. * * @return the server url string */ private String getTargetRequestUrl() { // If customServer is not empty return targetRequestUrl with customServer as host if (!targetState.getTargetServer().isEmpty()) { - return String.format(TargetConstants.DELIVERY_API_URL_BASE, targetState.getTargetServer(), - targetState.getClientCode(), targetState.getSessionId()); + return String.format( + TargetConstants.DELIVERY_API_URL_BASE, + targetState.getTargetServer(), + targetState.getClientCode(), + targetState.getSessionId()); } final String edgeHost = targetState.getEdgeHost(); - final String host = StringUtils.isNullOrEmpty(edgeHost) ? - String.format(TargetConstants.API_URL_HOST_BASE, targetState.getClientCode()) - : edgeHost; - return String.format(TargetConstants.DELIVERY_API_URL_BASE, host, targetState.getClientCode(), targetState.getSessionId()); + final String host = + StringUtils.isNullOrEmpty(edgeHost) + ? String.format( + TargetConstants.API_URL_HOST_BASE, targetState.getClientCode()) + : edgeHost; + return String.format( + TargetConstants.DELIVERY_API_URL_BASE, + host, + targetState.getClientCode(), + targetState.getSessionId()); } - /** * Processes the network response after the Target delivery API call for raw request. * - * @param connection a {@link HttpConnecting} instance. - * @param isContentRequest {@code boolean} indicating whether it's a prefetch or execute request. - * @param event the incoming {@link Event} object. + * @param connection a {@link HttpConnecting} instance. + * @param isContentRequest {@code boolean} indicating whether it's a prefetch or execute + * request. + * @param event the incoming {@link Event} object. */ - private void processTargetRawResponse(final HttpConnecting connection, - final boolean isContentRequest, - final Event event) { + private void processTargetRawResponse( + final HttpConnecting connection, final boolean isContentRequest, final Event event) { if (connection == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "processTargetRawResponse - (%s)", TargetErrors.NO_CONNECTION); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "processTargetRawResponse - (%s)", + TargetErrors.NO_CONNECTION); dispatchTargetRawResponseIfNeeded(isContentRequest, null, event); return; } @@ -739,17 +963,26 @@ private void processTargetRawResponse(final HttpConnecting connection, connection.close(); if (responseJson == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "processTargetRawResponse - (%s)" + TargetErrors.NULL_RESPONSE_JSON); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "processTargetRawResponse - (%s)" + TargetErrors.NULL_RESPONSE_JSON); dispatchTargetRawResponseIfNeeded(isContentRequest, null, event); return; } if (responseCode != HttpURLConnection.HTTP_OK) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "processTargetRawResponse - Received Target response with connection code: " + responseCode); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "processTargetRawResponse - Received Target response with connection code: " + + responseCode); final String responseError = targetResponseParser.getErrorMessage(responseJson); if (!StringUtils.isNullOrEmpty(responseError)) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.ERROR_RESPONSE + responseError); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + TargetErrors.ERROR_RESPONSE + responseError); } dispatchTargetRawResponseIfNeeded(isContentRequest, null, event); return; @@ -761,9 +994,13 @@ private void processTargetRawResponse(final HttpConnecting connection, targetState.updateEdgeHost(targetResponseParser.getEdgeHost(responseJson)); getApi().createSharedState(targetState.generateSharedState(), event); - dispatchTargetRawResponseIfNeeded(isContentRequest, JSONUtils.toMap(responseJson), event); + dispatchTargetRawResponseIfNeeded( + isContentRequest, JSONUtils.toMap(responseJson), event); } catch (final JSONException e) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "processTargetRawResponse - (%s)" + TargetErrors.NULL_RESPONSE_JSON); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "processTargetRawResponse - (%s)" + TargetErrors.NULL_RESPONSE_JSON); dispatchTargetRawResponseIfNeeded(isContentRequest, null, event); } } @@ -777,13 +1014,16 @@ private void processTargetRawResponse(final HttpConnecting connection, * @param identityData {@code Map shared state of Identity extension * @param event the {@link Event} which triggered this method call */ - private void prefetchMboxContent(final List targetPrefetchRequests, - final TargetParameters targetParameters, - final Map lifecycleData, - final Map identityData, - final Event event) { + private void prefetchMboxContent( + final List targetPrefetchRequests, + final TargetParameters targetParameters, + final Map lifecycleData, + final Map identityData, + final Event event) { if (TargetUtils.isNullOrEmpty(targetPrefetchRequests)) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, "prefetchMboxContent - Unable to prefetch mbox content, Error %s", TargetErrors.NO_PREFETCH_REQUESTS); dispatchMboxPrefetchResult(TargetErrors.NO_PREFETCH_REQUESTS, event); @@ -792,80 +1032,117 @@ private void prefetchMboxContent(final List targetPrefetchReques final String sendRequestError = prepareForTargetRequest(); if (sendRequestError != null) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, "prefetchMboxContent - Unable to prefetch mbox content, Error %s", sendRequestError); dispatchMboxPrefetchResult(sendRequestError, event); return; } - final String error = sendTargetRequest(null, targetPrefetchRequests, targetParameters, - lifecycleData, identityData, event, connection -> { - - if (connection == null) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "prefetchMboxContent - Unable to prefetch mbox content, Error %s", - TargetErrors.NO_CONNECTION); - dispatchMboxPrefetchResult(TargetErrors.NO_CONNECTION, event); - return; - } - - final JSONObject responseJson = targetResponseParser.parseResponseToJson(connection); - final String responseError = targetResponseParser.getErrorMessage(responseJson); - final int responseCode = connection.getResponseCode(); - connection.close(); + final String error = + sendTargetRequest( + null, + targetPrefetchRequests, + targetParameters, + lifecycleData, + identityData, + event, + connection -> { + if (connection == null) { + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "prefetchMboxContent - Unable to prefetch mbox content," + + " Error %s", + TargetErrors.NO_CONNECTION); + dispatchMboxPrefetchResult(TargetErrors.NO_CONNECTION, event); + return; + } + + final JSONObject responseJson = + targetResponseParser.parseResponseToJson(connection); + final String responseError = + targetResponseParser.getErrorMessage(responseJson); + final int responseCode = connection.getResponseCode(); + connection.close(); + + if (responseJson == null) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "prefetchMboxContent - (%s)" + + TargetErrors.NULL_RESPONSE_JSON); + dispatchMboxPrefetchResult( + String.format( + ("%s %s"), + TargetErrors.NULL_RESPONSE_JSON, + responseError), + event); + return; + } + + if (!StringUtils.isNullOrEmpty(responseError)) { + if (responseError.contains(TargetErrors.NOTIFICATION_ERROR_TAG)) { + targetState.clearNotifications(); + } + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, + TargetErrors.ERROR_RESPONSE + responseError); + dispatchMboxPrefetchResult( + TargetErrors.ERROR_RESPONSE + responseError, event); + return; + } + + if (responseCode != HttpURLConnection.HTTP_OK) { + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "prefetchMboxContent - Unable to prefetch mbox content," + + " Error %s", + TargetErrors.ERROR_RESPONSE + responseCode); + dispatchMboxPrefetchResult(TargetErrors.ERROR_RESPONSE, event); + return; + } - if (responseJson == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "prefetchMboxContent - (%s)" + TargetErrors.NULL_RESPONSE_JSON); - dispatchMboxPrefetchResult(String.format(("%s %s"),TargetErrors.NULL_RESPONSE_JSON,responseError), event); - return; - } - - if (!StringUtils.isNullOrEmpty(responseError)) { - if (responseError.contains(TargetErrors.NOTIFICATION_ERROR_TAG)) { targetState.clearNotifications(); - } - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.ERROR_RESPONSE + responseError); - dispatchMboxPrefetchResult(TargetErrors.ERROR_RESPONSE + responseError, event); - return; - } - - if (responseCode != HttpURLConnection.HTTP_OK) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "prefetchMboxContent - Unable to prefetch mbox content, Error %s", - TargetErrors.ERROR_RESPONSE + responseCode); - dispatchMboxPrefetchResult(TargetErrors.ERROR_RESPONSE, event); - return; - } - - targetState.clearNotifications(); - - // save the network request timestamp for computing the session id expiration - targetState.updateSessionTimestamp(false); - setTntIdInternal(targetResponseParser.getTntId(responseJson)); - targetState.updateEdgeHost(targetResponseParser.getEdgeHost(responseJson)); - - getApi().createSharedState(targetState.generateSharedState(), event); - - final Map prefetchedMboxes = targetResponseParser.extractPrefetchedMboxes( - responseJson); - if (TargetUtils.isNullOrEmpty(prefetchedMboxes)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.NO_PREFETCH_MBOXES); - dispatchMboxPrefetchResult(TargetErrors.NO_PREFETCH_MBOXES, event); - return; - } - - targetState.mergePrefetchedMboxJson(prefetchedMboxes); - - // check if we have duplicates in memory and remove them - targetState.removeDuplicateLoadedMboxes(); - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "prefetchMboxContent - Current cached mboxes : %s, size: %d", - Arrays.toString(targetState.getPrefetchedMbox().keySet().toArray()), - targetState.getPrefetchedMbox().size()); - - dispatchMboxPrefetchResult(null, event); - }); + + // save the network request timestamp for computing the session id + // expiration + targetState.updateSessionTimestamp(false); + setTntIdInternal(targetResponseParser.getTntId(responseJson)); + targetState.updateEdgeHost( + targetResponseParser.getEdgeHost(responseJson)); + + getApi().createSharedState(targetState.generateSharedState(), event); + + final Map prefetchedMboxes = + targetResponseParser.extractPrefetchedMboxes(responseJson); + if (TargetUtils.isNullOrEmpty(prefetchedMboxes)) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + TargetErrors.NO_PREFETCH_MBOXES); + dispatchMboxPrefetchResult(TargetErrors.NO_PREFETCH_MBOXES, event); + return; + } + + targetState.mergePrefetchedMboxJson(prefetchedMboxes); + + // check if we have duplicates in memory and remove them + targetState.removeDuplicateLoadedMboxes(); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "prefetchMboxContent - Current cached mboxes : %s, size: %d", + Arrays.toString( + targetState.getPrefetchedMbox().keySet().toArray()), + targetState.getPrefetchedMbox().size()); + + dispatchMboxPrefetchResult(null, event); + }); if (!StringUtils.isNullOrEmpty(error)) { dispatchMboxPrefetchResult(error, event); } @@ -874,44 +1151,60 @@ private void prefetchMboxContent(final List targetPrefetchReques /** * Creates a network connection and sends the request to target server. * - * @param batchRequests {@link List} representing the desired mboxes to load - * @param prefetchRequests {@link List} representing the desired mboxes to preftech + * @param batchRequests {@link List} representing the desired mboxes to load + * @param prefetchRequests {@link List} representing the desired mboxes to + * preftech * @param targetParameters {@link TargetParameters} object to be passed in all prefetch requests - * @param lifecycleData {@code Map} shared state of Lifecycle extension - * @param identityData {@code Map} shared state of Identity} extension - * @param event {@link Event} associated Target request content event + * @param lifecycleData {@code Map} shared state of Lifecycle extension + * @param identityData {@code Map} shared state of Identity} extension + * @param event {@link Event} associated Target request content event * @param networkCallback {@link NetworkCallback} instance */ - private String sendTargetRequest(final List batchRequests, - final List prefetchRequests, - final TargetParameters targetParameters, - final Map lifecycleData, - final Map identityData, - final Event event, - final NetworkCallback networkCallback) { + private String sendTargetRequest( + final List batchRequests, + final List prefetchRequests, + final TargetParameters targetParameters, + final Map lifecycleData, + final Map identityData, + final Event event, + final NetworkCallback networkCallback) { if (networkService == null) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.NETWORK_SERVICE_UNAVAILABLE); + Log.error( + TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.NETWORK_SERVICE_UNAVAILABLE); return TargetErrors.NETWORK_SERVICE_UNAVAILABLE; } if (targetRequestBuilder == null) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.REQUEST_BUILDER_INIT_FAILED); + Log.error( + TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.REQUEST_BUILDER_INIT_FAILED); return TargetErrors.REQUEST_BUILDER_INIT_FAILED; } final Map lifecycleContextData = getLifecycleDataForTarget(lifecycleData); // Give preference to property token passed in configuration over event data "at_property". - final String propertyToken = !StringUtils.isNullOrEmpty(targetState.getPropertyToken()) - ? targetState.getPropertyToken() - : DataReader.optString(event.getEventData(), TargetConstants.EventDataKeys.AT_PROPERTY, ""); - - final JSONObject payloadJson = targetRequestBuilder.getRequestPayload(prefetchRequests, - batchRequests, targetParameters, targetState.getNotifications(), propertyToken, - identityData, lifecycleContextData); + final String propertyToken = + !StringUtils.isNullOrEmpty(targetState.getPropertyToken()) + ? targetState.getPropertyToken() + : DataReader.optString( + event.getEventData(), + TargetConstants.EventDataKeys.AT_PROPERTY, + ""); + + final JSONObject payloadJson = + targetRequestBuilder.getRequestPayload( + prefetchRequests, + batchRequests, + targetParameters, + targetState.getNotifications(), + propertyToken, + identityData, + lifecycleContextData); if (JSONUtils.isNullOrEmpty(payloadJson)) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, "sendTargetRequest - Unable to send target request, Payload json is (%s)", (payloadJson == null ? "null" : "empty")); return TargetErrors.REQUEST_GENERATION_FAILED; @@ -927,33 +1220,43 @@ private String sendTargetRequest(final List batchRequests, final String url = getTargetRequestUrl(); final String payloadJsonString = payloadJson.toString(); final byte[] payload = payloadJsonString.getBytes(StandardCharsets.UTF_8); - final NetworkRequest networkRequest = new NetworkRequest(url, HttpMethod.POST, payload, headers, timeout, timeout); + final NetworkRequest networkRequest = + new NetworkRequest(url, HttpMethod.POST, payload, headers, timeout, timeout); - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, "sendTargetRequest - Target request was sent with url %s, body %s", - url, payloadJsonString); + url, + payloadJsonString); networkService.connectAsync(networkRequest, networkCallback); return null; } /** * Internal method to send a batch request. + * *

* - * @param targetBatchRequests {@code List} representing the desired mboxes to load - * @param targetParameters {@link TargetParameters} object to be passed in all prefetch requests - * @param lifecycleData {@code Map} shared state of {@code Lifecycle} extension - * @param identityData {@code Map} shared state of {@code Identity} extension - * @param event {@link Event} which triggered this method call + * @param targetBatchRequests {@code List} representing the desired mboxes to + * load + * @param targetParameters {@link TargetParameters} object to be passed in all prefetch requests + * @param lifecycleData {@code Map} shared state of {@code Lifecycle} extension + * @param identityData {@code Map} shared state of {@code Identity} extension + * @param event {@link Event} which triggered this method call */ - private void batchRequests(final List targetBatchRequests, - final TargetParameters targetParameters, - final Map lifecycleData, - final Map identityData, - final Event event) { + private void batchRequests( + final List targetBatchRequests, + final TargetParameters targetParameters, + final Map lifecycleData, + final Map identityData, + final Event event) { if (TargetUtils.isNullOrEmpty(targetBatchRequests)) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "batchRequests - Unable to process the batch requests, Target Batch Requests are %s.", + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "batchRequests - Unable to process the batch requests, Target Batch Requests" + + " are %s.", (targetBatchRequests == null ? "null" : "empty")); runDefaultCallbacks(targetBatchRequests, event); return; @@ -961,7 +1264,9 @@ private void batchRequests(final List targetBatchRequests, final String sendRequestError = prepareForTargetRequest(); if (sendRequestError != null) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, "batchRequests - Unable to process the batch requests, Error - %s", sendRequestError); runDefaultCallbacks(targetBatchRequests, event); @@ -971,63 +1276,94 @@ private void batchRequests(final List targetBatchRequests, final List requestsToSend; if (!inPreviewMode()) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, "Current cached mboxes : %s, size: %d", - Arrays.toString(targetState.getPrefetchedMbox().keySet().toArray()), targetState.getPrefetchedMbox().size()); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Current cached mboxes : %s, size: %d", + Arrays.toString(targetState.getPrefetchedMbox().keySet().toArray()), + targetState.getPrefetchedMbox().size()); requestsToSend = processCachedTargetRequest(targetBatchRequests, event); } else { requestsToSend = targetBatchRequests; } if (TargetUtils.isNullOrEmpty(requestsToSend) && targetState.getNotifications().isEmpty()) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, "Unable to process the batch requests, requests and notifications are empty"); return; } - final String error = sendTargetRequest(requestsToSend, null, targetParameters, - lifecycleData, identityData, event, connection -> { - processTargetRequestResponse(requestsToSend, connection, event); - }); + final String error = + sendTargetRequest( + requestsToSend, + null, + targetParameters, + lifecycleData, + identityData, + event, + connection -> { + processTargetRequestResponse(requestsToSend, connection, event); + }); if (!StringUtils.isNullOrEmpty(error)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "batchRequests - " + TargetErrors.NO_CONNECTION); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "batchRequests - " + TargetErrors.NO_CONNECTION); runDefaultCallbacks(requestsToSend, event); } } /** - * Checks if the cached mboxs contain the data for each of the {@code TargetRequest} in the input List. - *

- * If a cached mbox exists, then dispatch the mbox content. + * Checks if the cached mboxs contain the data for each of the {@code TargetRequest} in the + * input List. + * + *

If a cached mbox exists, then dispatch the mbox content. * * @param batchRequests an {@code List} representing the desired mboxes to load * @return {@code List} that didn't hit the cache */ - List processCachedTargetRequest(final List batchRequests, final Event event) { + List processCachedTargetRequest( + final List batchRequests, final Event event) { final List requestsToSend = new ArrayList<>(); for (TargetRequest targetRequest : batchRequests) { if (!targetState.getPrefetchedMbox().containsKey(targetRequest.getMboxName())) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, "processCachedTargetRequest - (%s) (%s) ", - TargetErrors.NO_CACHED_MBOX_FOUND, targetRequest.getMboxName()); + TargetErrors.NO_CACHED_MBOX_FOUND, + targetRequest.getMboxName()); requestsToSend.add(targetRequest); continue; } - final JSONObject cachedMboxJson = targetState.getPrefetchedMbox().get(targetRequest.getMboxName()); + final JSONObject cachedMboxJson = + targetState.getPrefetchedMbox().get(targetRequest.getMboxName()); - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, "processCachedTargetRequest - Cached mbox found for %s with data %s", - targetRequest.getMboxName(), cachedMboxJson); - - final String content = targetResponseParser.extractMboxContent(cachedMboxJson); - final Map a4tParams = targetResponseParser.getAnalyticsForTargetPayload(cachedMboxJson); - final Map responseTokens = targetResponseParser.getResponseTokens(cachedMboxJson); - final Map clickMetricA4TParams = targetResponseParser.extractClickMetricAnalyticsPayload( + targetRequest.getMboxName(), cachedMboxJson); - dispatchMboxContent(StringUtils.isNullOrEmpty(content) ? targetRequest.getDefaultContent() : content, - a4tParams, clickMetricA4TParams, + final String content = targetResponseParser.extractMboxContent(cachedMboxJson); + final Map a4tParams = + targetResponseParser.getAnalyticsForTargetPayload(cachedMboxJson); + final Map responseTokens = + targetResponseParser.getResponseTokens(cachedMboxJson); + final Map clickMetricA4TParams = + targetResponseParser.extractClickMetricAnalyticsPayload(cachedMboxJson); + + dispatchMboxContent( + StringUtils.isNullOrEmpty(content) + ? targetRequest.getDefaultContent() + : content, + a4tParams, + clickMetricA4TParams, responseTokens, targetRequest.getResponsePairId(), event); @@ -1040,15 +1376,19 @@ List processCachedTargetRequest(final List batchRe * Processes the network response for batch request. * * @param batchRequests {@code List} representing the desired mboxes to load - * @param connection {@link HttpConnecting} instance - * @param event {@link Event} which triggered this method call + * @param connection {@link HttpConnecting} instance + * @param event {@link Event} which triggered this method call */ - private void processTargetRequestResponse(final List batchRequests, - final HttpConnecting connection, - final Event event) { + private void processTargetRequestResponse( + final List batchRequests, + final HttpConnecting connection, + final Event event) { if (connection == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "processTargetRequestResponse - (%s)", TargetErrors.NO_CONNECTION); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "processTargetRequestResponse - (%s)", + TargetErrors.NO_CONNECTION); runDefaultCallbacks(batchRequests, event); return; } @@ -1059,7 +1399,11 @@ private void processTargetRequestResponse(final List batchRequest connection.close(); if (responseJson == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "processTargetRequestResponse - (%s)", TargetErrors.NULL_RESPONSE_JSON); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "processTargetRequestResponse - (%s)", + TargetErrors.NULL_RESPONSE_JSON); runDefaultCallbacks(batchRequests, event); return; } @@ -1068,15 +1412,22 @@ private void processTargetRequestResponse(final List batchRequest if (responseError.contains(TargetErrors.NOTIFICATION_ERROR_TAG)) { targetState.clearNotifications(); } - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.ERROR_RESPONSE + responseError); + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, + TargetErrors.ERROR_RESPONSE + responseError); runDefaultCallbacks(batchRequests, event); return; } if (responseCode != HttpURLConnection.HTTP_OK) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, "processTargetRequestResponse - (%) Error (%s), Error code (%s)", - TargetErrors.ERROR_RESPONSE, responseError, responseCode); + TargetErrors.ERROR_RESPONSE, + responseError, + responseCode); runDefaultCallbacks(batchRequests, event); return; } @@ -1090,7 +1441,8 @@ private void processTargetRequestResponse(final List batchRequest getApi().createSharedState(targetState.generateSharedState(), event); - Map batchedMboxes = targetResponseParser.extractBatchedMBoxes(responseJson); + Map batchedMboxes = + targetResponseParser.extractBatchedMBoxes(responseJson); if (TargetUtils.isNullOrEmpty(batchedMboxes)) { runDefaultCallbacks(batchRequests, event); return; @@ -1100,55 +1452,78 @@ private void processTargetRequestResponse(final List batchRequest for (TargetRequest targetRequest : batchRequests) { if (!batchedMboxes.containsKey(targetRequest.getMboxName())) { - dispatchMboxContent(targetRequest.getDefaultContent(), null, null, null, - targetRequest.getResponsePairId(), event); + dispatchMboxContent( + targetRequest.getDefaultContent(), + null, + null, + null, + targetRequest.getResponsePairId(), + event); continue; } final JSONObject mboxJson = batchedMboxes.get(targetRequest.getMboxName()); final String content = targetResponseParser.extractMboxContent(mboxJson); - final Map responseTokens = targetResponseParser.getResponseTokens(mboxJson); - final Map clickMetricA4TParams = targetResponseParser.extractClickMetricAnalyticsPayload(mboxJson); + final Map responseTokens = + targetResponseParser.getResponseTokens(mboxJson); + final Map clickMetricA4TParams = + targetResponseParser.extractClickMetricAnalyticsPayload(mboxJson); - final Map a4tParams = targetResponseParser.getAnalyticsForTargetPayload(mboxJson); + final Map a4tParams = + targetResponseParser.getAnalyticsForTargetPayload(mboxJson); if (!TargetUtils.isNullOrEmpty(a4tParams)) { - dispatchAnalyticsForTargetRequest(targetResponseParser.getAnalyticsForTargetPayload(mboxJson, - targetState.getSessionId())); + dispatchAnalyticsForTargetRequest( + targetResponseParser.getAnalyticsForTargetPayload( + mboxJson, targetState.getSessionId())); } - dispatchMboxContent(StringUtils.isNullOrEmpty(content) ? targetRequest.getDefaultContent() : content, - a4tParams, clickMetricA4TParams, + dispatchMboxContent( + StringUtils.isNullOrEmpty(content) + ? targetRequest.getDefaultContent() + : content, + a4tParams, + clickMetricA4TParams, responseTokens, - targetRequest.getResponsePairId(), event); + targetRequest.getResponsePairId(), + event); } } /** - * Adds the display notification for the given mbox to the {@link TargetState#getNotifications()} list. + * Adds the display notification for the given mbox to the {@link + * TargetState#getNotifications()} list. * - * @param mboxName the displayed mbox name {@link String} - * @param mboxJson the cached mbox {@link JSONObject} + * @param mboxName the displayed mbox name {@link String} + * @param mboxJson the cached mbox {@link JSONObject} * @param targetParameters {@link TargetParameters} object corresponding to the display location - * @param lifecycleData the lifecycle {@code Map lifecycleData, - final long timestamp) { + private boolean addDisplayNotification( + final String mboxName, + final JSONObject mboxJson, + final TargetParameters targetParameters, + final Map lifecycleData, + final long timestamp) { if (targetRequestBuilder == null) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.REQUEST_BUILDER_INIT_FAILED); + Log.error( + TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.REQUEST_BUILDER_INIT_FAILED); return false; } final Map lifecycleContextData = getLifecycleDataForTarget(lifecycleData); - final JSONObject displayNotificationJson = targetRequestBuilder.getDisplayNotificationJsonObject(mboxName, mboxJson, - targetParameters, timestamp, lifecycleContextData); + final JSONObject displayNotificationJson = + targetRequestBuilder.getDisplayNotificationJsonObject( + mboxName, mboxJson, targetParameters, timestamp, lifecycleContextData); if (displayNotificationJson == null) { - Log.debug(TargetConstants.LOG_TAG, "addDisplayNotification - " + TargetErrors.DISPLAY_NOTIFICATION_NULL_FOR_MBOX, + Log.debug( + TargetConstants.LOG_TAG, + "addDisplayNotification - " + TargetErrors.DISPLAY_NOTIFICATION_NULL_FOR_MBOX, mboxName); return false; } @@ -1160,13 +1535,16 @@ private boolean addDisplayNotification(final String mboxName, final JSONObject m /** * Process the network response after the notification network call. * - * @param connection {@link HttpConnecting} instance + * @param connection {@link HttpConnecting} instance * @param event the {@link Event} which triggered this method call */ private void processNotificationResponse(final HttpConnecting connection, final Event event) { if (connection == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "processNotificationResponse - %s", TargetErrors.NO_CONNECTION); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "processNotificationResponse - %s", + TargetErrors.NO_CONNECTION); return; } @@ -1176,7 +1554,10 @@ private void processNotificationResponse(final HttpConnecting connection, final connection.close(); if (responseJson == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "processNotificationResponse (%s)" + TargetErrors.NULL_RESPONSE_JSON); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "processNotificationResponse (%s)" + TargetErrors.NULL_RESPONSE_JSON); return; } @@ -1184,13 +1565,19 @@ private void processNotificationResponse(final HttpConnecting connection, final if (responseError.contains(TargetErrors.NOTIFICATION_ERROR_TAG)) { targetState.clearNotifications(); } - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.ERROR_RESPONSE + responseError); + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, + TargetErrors.ERROR_RESPONSE + responseError); return; } if (responseCode != HttpURLConnection.HTTP_OK) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "processNotificationResponse" + TargetErrors.ERROR_RESPONSE, responseCode); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "processNotificationResponse" + TargetErrors.ERROR_RESPONSE, + responseCode); return; } @@ -1205,30 +1592,40 @@ private void processNotificationResponse(final HttpConnecting connection, final } /** - * Adds the clicked notification for the given mbox to the {@link TargetState#getNotifications()} list. + * Adds the clicked notification for the given mbox to the {@link + * TargetState#getNotifications()} list. * - * @param mboxJson the clicked notification {@link JSONObject} for the clicked location + * @param mboxJson the clicked notification {@link JSONObject} for the clicked location * @param targetParameters {@link TargetParameters} object corresponding to the clicked location - * @param lifecycleData the lifecycle {@code Map lifecycleData, - final long timestamp) { + private boolean addClickedNotificationToList( + final JSONObject mboxJson, + final TargetParameters targetParameters, + final Map lifecycleData, + final long timestamp) { if (targetRequestBuilder == null) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.REQUEST_BUILDER_INIT_FAILED); + Log.error( + TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.REQUEST_BUILDER_INIT_FAILED); return false; } // set lifecycle data to that targetRequestBuilder final Map lifecycleContextData = getLifecycleDataForTarget(lifecycleData); - final JSONObject clickNotificationJson = targetRequestBuilder.getClickNotificationJsonObject(mboxJson, targetParameters, - timestamp, lifecycleContextData); + final JSONObject clickNotificationJson = + targetRequestBuilder.getClickNotificationJsonObject( + mboxJson, targetParameters, timestamp, lifecycleContextData); if (clickNotificationJson == null) { - Log.debug(TargetConstants.LOG_TAG, "addClickedNotificationToList - %s", TargetErrors.CLICK_NOTIFICATION_NOT_SENT); + Log.debug( + TargetConstants.LOG_TAG, + "addClickedNotificationToList - %s", + TargetErrors.CLICK_NOTIFICATION_NOT_SENT); return false; } @@ -1238,37 +1635,49 @@ private boolean addClickedNotificationToList(final JSONObject mboxJson, /** * Starts preview mode if the deeplink contains the preview query parameters. - *

- * It then dispatches a new event to messages to create a custom full screen message for target preview. - * Bail out if the Target configurations are not found or if preview is disabled in Target configuration or if {@code TargetPreviewManager} cannot be instantiated. * - * @param deepLink {@link String} the deep link extracted from the {@link EventType#GENERIC_DATA} {@link EventSource#OS} event + *

It then dispatches a new event to messages to create a custom full screen message for + * target preview. Bail out if the Target configurations are not found or if preview is disabled + * in Target configuration or if {@code TargetPreviewManager} cannot be instantiated. + * + * @param deepLink {@link String} the deep link extracted from the {@link + * EventType#GENERIC_DATA} {@link EventSource#OS} event */ private void setupPreviewMode(final String deepLink) { final String sendRequestError = prepareForTargetRequest(); if (sendRequestError != null) { - Log.debug(TargetConstants.LOG_TAG, "setupPreviewMode - " + TargetErrors.TARGET_NOT_ENABLED_FOR_PREVIEW, + Log.debug( + TargetConstants.LOG_TAG, + "setupPreviewMode - " + TargetErrors.TARGET_NOT_ENABLED_FOR_PREVIEW, sendRequestError); return; } if (!targetState.isPreviewEnabled()) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "setupPreviewMode - " + TargetErrors.TARGET_PREVIEW_DISABLED); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "setupPreviewMode - " + TargetErrors.TARGET_PREVIEW_DISABLED); return; } - targetPreviewManager.enterPreviewModeWithDeepLinkParams(targetState.getClientCode(), deepLink); + targetPreviewManager.enterPreviewModeWithDeepLinkParams( + targetState.getClientCode(), deepLink); } /** * Dispatches a Target response event for a raw prefetch or execute request. * - * @param isContentRequest a {@code boolean} indicating whether it is a prefetch or execute request. - * @param responseData (Nullable) {@code List>} containing the raw request response for the mboxes. - * @param requestEvent (required) {@link Event} the associated Target request content event. + * @param isContentRequest a {@code boolean} indicating whether it is a prefetch or execute + * request. + * @param responseData (Nullable) {@code List>} containing the raw request + * response for the mboxes. + * @param requestEvent (required) {@link Event} the associated Target request content event. */ - private void dispatchTargetRawResponseIfNeeded(final boolean isContentRequest, final Map responseData, - final Event requestEvent) { + private void dispatchTargetRawResponseIfNeeded( + final boolean isContentRequest, + final Map responseData, + final Event requestEvent) { if (!isContentRequest) { return; } @@ -1278,18 +1687,30 @@ private void dispatchTargetRawResponseIfNeeded(final boolean isContentRequest, f /** * Dispatches the Target response content event for a raw prefetch or execute request. * - * @param responseData (Nullable) {@code List>} containing the raw execute request response for the mboxes. - * @param requestEvent (required) {@link Event} the associated TargetRequestContent event. + * @param responseData (Nullable) {@code List>} containing the raw execute + * request response for the mboxes. + * @param requestEvent (required) {@link Event} the associated TargetRequestContent event. */ - void dispatchTargetRawResponse(final Map responseData, final Event requestEvent) { + void dispatchTargetRawResponse( + final Map responseData, final Event requestEvent) { final Map data = new HashMap<>(); data.put(TargetConstants.EventDataKeys.RESPONSE_DATA, responseData); // Create Event and dispatch to EventHub - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, "dispatchTargetRawResponse - (%s) ", TARGET_EVENT_DISPATCH_MESSAGE); - final Event responseEvent = new Event.Builder(TargetConstants.EventName.TARGET_RAW_RESPONSE_EVENT_NAME, EventType.TARGET, - EventSource.RESPONSE_CONTENT).setEventData(data).inResponseToEvent(requestEvent).build(); + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, + "dispatchTargetRawResponse - (%s) ", + TARGET_EVENT_DISPATCH_MESSAGE); + final Event responseEvent = + new Event.Builder( + TargetConstants.EventName.TARGET_RAW_RESPONSE_EVENT_NAME, + EventType.TARGET, + EventSource.RESPONSE_CONTENT) + .setEventData(data) + .inResponseToEvent(requestEvent) + .build(); getApi().dispatch(responseEvent); } @@ -1304,11 +1725,18 @@ private void dispatchMboxPrefetchResult(final String error, final Event event) { eventData.put(TargetConstants.EventDataKeys.PREFETCH_ERROR, error); eventData.put(TargetConstants.EventDataKeys.PREFETCH_RESULT, error == null); // Create Event and dispatch to EventHub - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, "dispatchMboxContent - " + TARGET_EVENT_DISPATCH_MESSAGE); - final Event responseEvent = new Event.Builder(TargetConstants.EventName.PREFETCH_RESPONSE, - EventType.TARGET, - EventSource.RESPONSE_CONTENT) - .setEventData(eventData).inResponseToEvent(event).build(); + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, + "dispatchMboxContent - " + TARGET_EVENT_DISPATCH_MESSAGE); + final Event responseEvent = + new Event.Builder( + TargetConstants.EventName.PREFETCH_RESPONSE, + EventType.TARGET, + EventSource.RESPONSE_CONTENT) + .setEventData(eventData) + .inResponseToEvent(event) + .build(); getApi().dispatch(responseEvent); } @@ -1316,18 +1744,21 @@ private void dispatchMboxPrefetchResult(final String error, final Event event) { * Dispatches the Target Response Content Event. * * @param content (required) the target content generated by the Target extension object. - * @param a4tParams (Nullable) the A4T params {@code Map} for the Mbox. It will be null if A4T is not enabled on Target. + * @param a4tParams (Nullable) the A4T params {@code Map} for the Mbox. It will + * be null if A4T is not enabled on Target. * @param clickMetricA4TParams (Nullable) the click metric A4T parameter for the Mbox. - * @param responseTokens (Nullable) the Response Tokens for the Mbox. It may be null if Response Tokens are not activated on Target. - * @param pairId (required) the pairId of the associated TargetRequestContent event. + * @param responseTokens (Nullable) the Response Tokens for the Mbox. It may be null if Response + * Tokens are not activated on Target. + * @param pairId (required) the pairId of the associated TargetRequestContent event. * @param event {@code Event} associated target request content event. */ - void dispatchMboxContent(final String content, - final Map a4tParams, - final Map clickMetricA4TParams, - final Map responseTokens, - final String pairId, - final Event event) { + void dispatchMboxContent( + final String content, + final Map a4tParams, + final Map clickMetricA4TParams, + final Map responseTokens, + final String pairId, + final Event event) { final Map data = new HashMap<>(); data.put(TargetConstants.EventDataKeys.TARGET_CONTENT, content); @@ -1341,19 +1772,31 @@ void dispatchMboxContent(final String content, } if (clickMetricA4TParams != null) { - dataPayload.put(TargetConstants.TargetResponse.CLICK_METRIC_ANALYTICS_PAYLOAD, clickMetricA4TParams); + dataPayload.put( + TargetConstants.TargetResponse.CLICK_METRIC_ANALYTICS_PAYLOAD, + clickMetricA4TParams); } data.put(TargetConstants.EventDataKeys.TARGET_DATA_PAYLOAD, dataPayload); if (!StringUtils.isNullOrEmpty(pairId)) { data.put(TargetConstants.EventDataKeys.TARGET_RESPONSE_PAIR_ID, pairId); } - data.put(TargetConstants.EventDataKeys.TARGET_RESPONSE_EVENT_ID, event.getUniqueIdentifier()); + data.put( + TargetConstants.EventDataKeys.TARGET_RESPONSE_EVENT_ID, + event.getUniqueIdentifier()); // Create Event and dispatch to EventHub - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, "dispatchMboxContent - " + TARGET_EVENT_DISPATCH_MESSAGE); - final Event responseEvent = new Event.Builder(TargetConstants.EventName.TARGET_REQUEST_RESPONSE, - EventType.TARGET, EventSource.RESPONSE_CONTENT).setEventData(data).build(); + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, + "dispatchMboxContent - " + TARGET_EVENT_DISPATCH_MESSAGE); + final Event responseEvent = + new Event.Builder( + TargetConstants.EventName.TARGET_REQUEST_RESPONSE, + EventType.TARGET, + EventSource.RESPONSE_CONTENT) + .setEventData(data) + .build(); getApi().dispatch(responseEvent); } @@ -1365,8 +1808,11 @@ void dispatchMboxContent(final String content, void dispatchAnalyticsForTargetRequest(final Map payload) { if (TargetUtils.isNullOrEmpty(payload)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "dispatchAnalyticsForTargetRequest - Failed to dispatch analytics. Payload is either null or empty"); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "dispatchAnalyticsForTargetRequest - Failed to dispatch analytics. Payload is" + + " either null or empty"); return; } @@ -1377,24 +1823,28 @@ void dispatchAnalyticsForTargetRequest(final Map payload) { eventData.put(TargetConstants.EventDataKeys.TRACK_INTERNAL, true); // Create Event and dispatch - final Event analyticsForTargetEvent = new Event.Builder(TargetConstants.EventName.ANALYTICS_FOR_TARGET_REQUEST_EVENT_NAME, EventType.ANALYTICS, - EventSource.REQUEST_CONTENT) - .setEventData(eventData) - .build(); + final Event analyticsForTargetEvent = + new Event.Builder( + TargetConstants.EventName.ANALYTICS_FOR_TARGET_REQUEST_EVENT_NAME, + EventType.ANALYTICS, + EventSource.REQUEST_CONTENT) + .setEventData(eventData) + .build(); getApi().dispatch(analyticsForTargetEvent); } /** * Dispatches a response event for an identity request * - * @param event {@link Event} the associated TargetRequestIdentity event + * @param event {@link Event} the associated TargetRequestIdentity event */ void dispatchIdentity(final Event event) { final Map responseEventData = new HashMap<>(); // attach thirdPartyId to response event only if there is valid value if (!StringUtils.isNullOrEmpty(targetState.getThirdPartyId())) { - responseEventData.put(TargetConstants.EventDataKeys.THIRD_PARTY_ID, targetState.getThirdPartyId()); + responseEventData.put( + TargetConstants.EventDataKeys.THIRD_PARTY_ID, targetState.getThirdPartyId()); } // attach tntId to response event only if there is valid value @@ -1402,11 +1852,14 @@ void dispatchIdentity(final Event event) { responseEventData.put(TargetConstants.EventDataKeys.TNT_ID, targetState.getTntId()); } responseEventData.put(TargetConstants.EventDataKeys.SESSION_ID, targetState.getSessionId()); - final Event responseEvent = new Event.Builder(TargetConstants.EventName.IDENTITY_RESPONSE, - EventType.TARGET, EventSource.RESPONSE_IDENTITY) - .setEventData(responseEventData) - .inResponseToEvent(event) - .build(); + final Event responseEvent = + new Event.Builder( + TargetConstants.EventName.IDENTITY_RESPONSE, + EventType.TARGET, + EventSource.RESPONSE_IDENTITY) + .setEventData(responseEventData) + .inResponseToEvent(event) + .build(); getApi().dispatch(responseEvent); } @@ -1417,7 +1870,11 @@ void dispatchIdentity(final Event event) { */ private TargetRequestBuilder getRequestBuilder() { if (deviceInfoService == null) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.REQUEST_BUILDER_INIT_FAILED + " Device Info services are not available"); + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, + TargetErrors.REQUEST_BUILDER_INIT_FAILED + + " Device Info services are not available"); return null; } @@ -1436,81 +1893,117 @@ private boolean inPreviewMode() { /** * Saves the tntId and the edge host value derived from it to the {@link TargetState}. - *

- * If a valid tntId is provided and the privacy status is {@link MobilePrivacyStatus#OPT_OUT} or - * the provided tntId is same as the existing value, then the method returns with no further action. + * + *

If a valid tntId is provided and the privacy status is {@link MobilePrivacyStatus#OPT_OUT} + * or the provided tntId is same as the existing value, then the method returns with no further + * action. * * @param updatedTntId {@link String} containing new tntId that needs to be set. */ void setTntIdInternal(final String updatedTntId) { // do not set identifier if privacy is opt-out and the id is not being cleared - if (targetState.getMobilePrivacyStatus() == MobilePrivacyStatus.OPT_OUT && !StringUtils.isNullOrEmpty(updatedTntId)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "updateTntId - Cannot update Target tntId due to opt out privacy status."); + if (targetState.getMobilePrivacyStatus() == MobilePrivacyStatus.OPT_OUT + && !StringUtils.isNullOrEmpty(updatedTntId)) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "updateTntId - Cannot update Target tntId due to opt out privacy status."); return; } if (tntIdValuesAreEqual(targetState.getTntId(), updatedTntId)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "updateTntId - Won't update Target tntId as provided value is same as the existing tntId value (%s).", updatedTntId); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "updateTntId - Won't update Target tntId as provided value is same as the" + + " existing tntId value (%s).", + updatedTntId); return; } final String edgeHost = extractEdgeHost(updatedTntId); if (!StringUtils.isNullOrEmpty(edgeHost)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, "updateTntId - The edge host value derived from the given tntId (%s) is (%s).", - updatedTntId, edgeHost); + updatedTntId, + edgeHost); targetState.updateEdgeHost(edgeHost); } else { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "updateTntId - The edge host value cannot be derived from the given tntId (%s) and it is removed from the data store.", + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "updateTntId - The edge host value cannot be derived from the given tntId (%s)" + + " and it is removed from the data store.", updatedTntId); targetState.updateEdgeHost(null); } - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, "setTntIdInternal - Updating tntId with value (%s).", updatedTntId); + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, + "setTntIdInternal - Updating tntId with value (%s).", + updatedTntId); targetState.updateTntId(updatedTntId); } /** - * Saves the {@code #thirdPartyId} to the Target DataStore or remove its key in the dataStore if the newThirdPartyId {@link String} is null + * Saves the {@code #thirdPartyId} to the Target DataStore or remove its key in the dataStore if + * the newThirdPartyId {@link String} is null * * @param updatedThirdPartyId newThirdPartyID {@link String} to be set */ void setThirdPartyIdInternal(final String updatedThirdPartyId) { // do not set identifier if privacy is opt-out and the id is not being cleared - if (targetState.getMobilePrivacyStatus() == MobilePrivacyStatus.OPT_OUT && !StringUtils.isNullOrEmpty(updatedThirdPartyId)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "setThirdPartyIdInternal - Cannot update Target thirdPartyId due to opt out privacy status."); + if (targetState.getMobilePrivacyStatus() == MobilePrivacyStatus.OPT_OUT + && !StringUtils.isNullOrEmpty(updatedThirdPartyId)) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "setThirdPartyIdInternal - Cannot update Target thirdPartyId due to opt out" + + " privacy status."); return; } - if (targetState.getThirdPartyId() != null && targetState.getThirdPartyId().equals(updatedThirdPartyId)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "setThirdPartyIdInternal - New thirdPartyId value is same as the existing thirdPartyId (%s).", targetState.getThirdPartyId()); + if (targetState.getThirdPartyId() != null + && targetState.getThirdPartyId().equals(updatedThirdPartyId)) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "setThirdPartyIdInternal - New thirdPartyId value is same as the existing" + + " thirdPartyId (%s).", + targetState.getThirdPartyId()); return; } - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, "setThirdPartyIdInternal - Updating thirdPartyId with value (%s).", updatedThirdPartyId); + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, + "setThirdPartyIdInternal - Updating thirdPartyId with value (%s).", + updatedThirdPartyId); targetState.updateThirdPartyId(updatedThirdPartyId); } /** * Derives and returns the edge host value from the provided tntId. - *

- * The tntId has the format {@literal UUID.}. The edge host value - * can be derived from the profile location hint. - * For example, if the tntId is {@literal 10abf6304b2714215b1fd39a870f01afc.28_20}, - * then the edgeHost will be {@literal mboxedge28.tt.omtrdc.net}. - *

- * If the provided tntId is null or empty, or if the edge host value cannot be determined + * + *

The tntId has the format {@literal UUID.}. The edge host value can + * be derived from the profile location hint. For example, if the tntId is {@literal + * 10abf6304b2714215b1fd39a870f01afc.28_20}, then the edgeHost will be {@literal + * mboxedge28.tt.omtrdc.net}. + * + *

If the provided tntId is null or empty, or if the edge host value cannot be determined * * @param newTntId {@link String} containing the tntId used to derive the edge host value. */ private String extractEdgeHost(final String newTntId) { if (StringUtils.isNullOrEmpty(newTntId)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "extractEdgeHost - Cannot extract Edge host from the provided tntId as it is null or empty."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "extractEdgeHost - Cannot extract Edge host from the provided tntId as it is" + + " null or empty."); return null; } @@ -1521,26 +2014,36 @@ private String extractEdgeHost(final String newTntId) { if (matcher.find()) { locationHint = matcher.group(); - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "extractEdgeHost - Provided tntId (%s) contains location hint (%s).", newTntId, + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "extractEdgeHost - Provided tntId (%s) contains location hint (%s).", + newTntId, locationHint); } String edgeHost = null; if (!StringUtils.isNullOrEmpty(locationHint)) { - edgeHost = String.format(TargetConstants.API_URL_HOST_BASE, String.format(TargetConstants.EDGE_HOST_BASE, - locationHint)); - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "extractEdgeHost - Edge host (%s) is derived from the provided tntId (%s).", - edgeHost, locationHint); + edgeHost = + String.format( + TargetConstants.API_URL_HOST_BASE, + String.format(TargetConstants.EDGE_HOST_BASE, locationHint)); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "extractEdgeHost - Edge host (%s) is derived from the provided tntId (%s).", + edgeHost, + locationHint); } return edgeHost; } /** - * Compares if the given two tntID's are equal. tntId is a concatenation of {tntId}.{edgehostValue} - * false is returned when tntID's are different. - * true is returned when tntID's are same. + * Compares if the given two tntID's are equal. tntId is a concatenation of + * {tntId}.{edgehostValue} false is returned when tntID's are different. true is returned when + * tntID's are same. * * @param oldId old tntId {@link String} * @param newId new tntId {@code String} @@ -1548,56 +2051,74 @@ private String extractEdgeHost(final String newTntId) { */ private boolean tntIdValuesAreEqual(final String oldId, final String newId) { if (oldId == null && newId == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "tntIdValuesAreEqual - old and new tntId is null."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "tntIdValuesAreEqual - old and new tntId is null."); return true; } if (oldId == null || newId == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "tntIdValuesAreEqual - %s is null.", (oldId == null ? "oldId" : "newId")); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "tntIdValuesAreEqual - %s is null.", + (oldId == null ? "oldId" : "newId")); return false; } if (oldId.equals(newId)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "tntIdValuesAreEqual - old tntId is equal to new tntId."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "tntIdValuesAreEqual - old tntId is equal to new tntId."); return true; } - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "tntIdValuesAreEqual - old tntId is not equal to new tntId."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "tntIdValuesAreEqual - old tntId is not equal to new tntId."); return false; } /** * Saves the provided session id {@code String} to the Target DataStore if it is a new value. - * Prior to persisting the new session id value, the session is reset and a new session is started. + * Prior to persisting the new session id value, the session is reset and a new session is + * started. * * @param newSessionId {@link String} containing the new session id to be set */ void setSessionId(final String newSessionId) { // an empty session id will reset the current session if (targetState.getMobilePrivacyStatus() == MobilePrivacyStatus.OPT_OUT) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "setSessionId - Cannot update Target session id due to opted out privacy status."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "setSessionId - Cannot update Target session id due to opted out privacy" + + " status."); return; } if (StringUtils.isNullOrEmpty(newSessionId)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "setSessionId - Removing session information from the Data store, new session id value is null or empty."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "setSessionId - Removing session information from the Data store, new session" + + " id value is null or empty."); targetState.resetSession(); return; } - // for a new session id: persist the new session id then update the session timestamp. otherwise, just update the timestamp. + // for a new session id: persist the new session id then update the session timestamp. + // otherwise, just update the timestamp. if (!newSessionId.equals(targetState.getSessionId())) { targetState.updateSessionId(newSessionId); } targetState.updateSessionTimestamp(false); - } - /** - * Clears identities including tntId, thirdPartyId and edgeHost. - */ + /** Clears identities including tntId, thirdPartyId and edgeHost. */ private void resetIdentity() { setTntIdInternal(null); setThirdPartyIdInternal(null); @@ -1613,16 +2134,22 @@ private void resetIdentity() { */ private Map getLifecycleDataForTarget(final Map lifecycleData) { if (TargetUtils.isNullOrEmpty(lifecycleData)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, "getLifecycleDataForTarget - lifecycleData is (%s)", (lifecycleData == null ? "null" : "empty")); return null; } - // copy the event's data so we don't accidentally overwrite it for someone else consuming this event - final Map tempLifecycleContextData = new HashMap<>(DataReader.optStringMap( - lifecycleData, - TargetConstants.Lifecycle.LIFECYCLE_CONTEXT_DATA, null)); + // copy the event's data so we don't accidentally overwrite it for someone else consuming + // this event + final Map tempLifecycleContextData = + new HashMap<>( + DataReader.optStringMap( + lifecycleData, + TargetConstants.Lifecycle.LIFECYCLE_CONTEXT_DATA, + null)); final Map lifecycleContextData = new HashMap<>(); @@ -1647,24 +2174,31 @@ private Map getLifecycleDataForTarget(final Map */ private void runDefaultCallbacks(final List batchRequests, final Event event) { if (TargetUtils.isNullOrEmpty(batchRequests)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, "runDefaultCallbacks - Batch requests are (%s)", (batchRequests == null ? "null" : "empty")); return; } for (TargetRequest request : batchRequests) { - //Pass null for a4t params and response tokens in case of default callback. - dispatchMboxContent(request.getDefaultContent(), null, null, - null, request.getResponsePairId(), event); + // Pass null for a4t params and response tokens in case of default callback. + dispatchMboxContent( + request.getDefaultContent(), + null, + null, + null, + request.getResponsePairId(), + event); } } /** * Returns the version info by concatenating Mobile Core and Target SDK versions. - *

- * If EventHub shared state is not available, or if version info is not present in the shared state, {@literal unknown} - * will be returned for Mobile Core version. + * + *

If EventHub shared state is not available, or if version info is not present in the shared + * state, {@literal unknown} will be returned for Mobile Core version. * * @param eventHubData {@code Map} containing shared state data for EventHub. * @return {@link String} containing Mobile Core and Target SDK versions. @@ -1674,16 +2208,19 @@ private String getSdkVersion(final Map eventHubData) { return ""; } - final String coreVersion = DataReader.optString(eventHubData, TargetConstants.EventHub.VERSION, "unknown"); + final String coreVersion = + DataReader.optString(eventHubData, TargetConstants.EventHub.VERSION, "unknown"); // sdkVersion is a combination of Mobile Core+Target SDK version - return String.format("%s+%s",coreVersion,Target.extensionVersion()); + return String.format("%s+%s", coreVersion, Target.extensionVersion()); } /** - * Returns the Target SDK info containing platform and wrapper details in the format {@literal AdobeTargetMobile-Android<-wrapperFriendlyName>}. - *

- * If EventHub shared state is not available, or if an SDK wrapper is not used, the information will omit the wrapper details. + * Returns the Target SDK info containing platform and wrapper details in the format {@literal + * AdobeTargetMobile-Android<-wrapperFriendlyName>}. + * + *

If EventHub shared state is not available, or if an SDK wrapper is not used, the + * information will omit the wrapper details. * * @param eventHubData {@code Map} containing shared state data for EventHub. * @return {@link String} containing SDK info. @@ -1694,18 +2231,24 @@ private String getSdkInfo(final Map eventHubData) { return sdkBase; } - final Map wrapperMap = DataReader.optTypedMap(Object.class, eventHubData, TargetConstants.EventHub.WRAPPER, null); + final Map wrapperMap = + DataReader.optTypedMap( + Object.class, eventHubData, TargetConstants.EventHub.WRAPPER, null); if (TargetUtils.isNullOrEmpty(wrapperMap)) { return sdkBase; } - final String wrapperFriendlyName = DataReader.optString(wrapperMap, TargetConstants.EventHub.WRAPPER_FRIENDLY_NAME, TargetConstants.DEFAULT_WRAPPER_FRIENDLY_NAME); + final String wrapperFriendlyName = + DataReader.optString( + wrapperMap, + TargetConstants.EventHub.WRAPPER_FRIENDLY_NAME, + TargetConstants.DEFAULT_WRAPPER_FRIENDLY_NAME); if (wrapperFriendlyName.equals(TargetConstants.DEFAULT_WRAPPER_FRIENDLY_NAME)) { return sdkBase; } // sdkVersion is a combination of Mobile Core+Target SDK version - return String.format("%s-%s",sdkBase,wrapperFriendlyName); + return String.format("%s-%s", sdkBase, wrapperFriendlyName); } /** @@ -1715,7 +2258,12 @@ private String getSdkInfo(final Map eventHubData) { * @return the last known valid {@code Lifecycle} state, may be null if no valid state was found */ private Map retrieveLifecycleSharedState(final Event event) { - final SharedStateResult lifecycleSharedState = getApi().getSharedState(TargetConstants.Lifecycle.EXTENSION_NAME, event, false, SharedStateResolution.ANY); + final SharedStateResult lifecycleSharedState = + getApi().getSharedState( + TargetConstants.Lifecycle.EXTENSION_NAME, + event, + false, + SharedStateResolution.ANY); return lifecycleSharedState != null ? lifecycleSharedState.getValue() : null; } @@ -1726,7 +2274,12 @@ private Map retrieveLifecycleSharedState(final Event event) { * @return the last known valid {@code Identity} state, may be null if no valid state was found */ private Map retrieveIdentitySharedState(final Event event) { - final SharedStateResult identitySharedState = getApi().getSharedState(TargetConstants.Identity.EXTENSION_NAME, event, false, SharedStateResolution.ANY); + final SharedStateResult identitySharedState = + getApi().getSharedState( + TargetConstants.Identity.EXTENSION_NAME, + event, + false, + SharedStateResolution.ANY); return identitySharedState != null ? identitySharedState.getValue() : null; } @@ -1734,10 +2287,16 @@ private Map retrieveIdentitySharedState(final Event event) { * Gets the latest valid {@code Configuration} shared state at the given {@code event} version. * * @param event the {@code Configuration} state version to retrieve - * @return the last known valid {@code Configuration} state, may be null if no valid state was found + * @return the last known valid {@code Configuration} state, may be null if no valid state was + * found */ private Map retrieveConfigurationSharedState(final Event event) { - final SharedStateResult configSharedState = getApi().getSharedState(TargetConstants.Configuration.EXTENSION_NAME, event, false, SharedStateResolution.ANY); + final SharedStateResult configSharedState = + getApi().getSharedState( + TargetConstants.Configuration.EXTENSION_NAME, + event, + false, + SharedStateResolution.ANY); return configSharedState != null ? configSharedState.getValue() : null; } @@ -1748,7 +2307,12 @@ private Map retrieveConfigurationSharedState(final Event event) * @return the last known valid {@code EventHub} state, may be null if no valid state was found. */ private Map retrieveEventHubSharedState(final Event event) { - final SharedStateResult eventHubSharedState = getApi().getSharedState(TargetConstants.EventHub.EXTENSION_NAME, event, false, SharedStateResolution.ANY); + final SharedStateResult eventHubSharedState = + getApi().getSharedState( + TargetConstants.EventHub.EXTENSION_NAME, + event, + false, + SharedStateResolution.ANY); return eventHubSharedState != null ? eventHubSharedState.getValue() : null; } -} \ No newline at end of file +} diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetJson.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetJson.java index ed09e89..859f78e 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetJson.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetJson.java @@ -1,14 +1,13 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; @@ -16,133 +15,134 @@ import java.util.List; final class TargetJson { - static final String MESSAGE = "message"; - static final String ID = "id"; - static final String ID_TNT_ID = "tntId"; - static final String ID_THIRD_PARTY_ID = "thirdPartyId"; - static final String ID_MARKETING_CLOUD_VISITOR_ID = "marketingCloudVisitorId"; - static final String ID_CUSTOMER_IDS = "customerIds"; - static final String ANALYTICS_LOGGING = "logging"; - static final String ANALYTICS_CLIENT_SIDE = "client_side"; - static final String AAM_PARAMETERS = "audienceManager"; - static final String EXPERIENCE_CLOUD = "experienceCloud"; - static final String CONTEXT_PARAMETERS = "context"; - static final String ANALYTICS_PARAMETERS = "analytics"; - static final String ANALYTICS_PAYLOAD = "payload"; - static final String OPTIONS = "options"; - static final String METRICS = "metrics"; - static final String ENVIRONMENT_ID = "environmentId"; // client environment id, optional - static final String PREFETCH = "prefetch"; - static final String EXECUTE = "execute"; - static final String MBOX_RESPONSES = "mboxResponses"; - static final String PARAMETERS = "parameters"; - static final String PROFILE_PARAMETERS = "profileParameters"; - static final String PRODUCT = "product"; - static final String ORDER = "order"; - static final String NOTIFICATIONS = "notifications"; - static final String MBOXES = "mboxes"; - static final String EDGE_HOST = "edgeHost"; - static final String TOKEN = "token"; - static final String PROPERTY = "property"; - static final String HTML = "html"; - static final String JSON = "json"; - - static final List CACHED_MBOX_ACCEPTED_KEYS = Arrays.asList(Mbox.NAME, Mbox.STATE, - OPTIONS, ANALYTICS_PARAMETERS, METRICS); - - static class CustomerIds { - static final String ID = "id"; - static final String INTEGRATION_CODE = "integrationCode"; - static final String AUTHENTICATION_STATE = "authenticatedState"; - private CustomerIds() {} - } - - static class Context { - static final String CHANNEL = "channel"; - static final String CHANNEL_MOBILE = "mobile"; - static final String MOBILE_PLATFORM = "mobilePlatform"; - static final String APPLICATION = "application"; - static final String SCREEN = "screen"; - static final String USER_AGENT = "userAgent"; - static final String TIME_OFFSET = "timeOffsetInMinutes"; - static final String PLATFORM_TYPE = "platformType"; - static final String DEVICE_NAME = "deviceName"; - static final String DEVICE_TYPE = "deviceType"; - static final String APP_ID = "id"; - static final String APP_NAME = "name"; - static final String APP_VERSION = "version"; - static final String SCREEN_WIDTH = "width"; - static final String SCREEN_HEIGHT = "height"; - static final String SCREEN_COLOR_DEPTH = "colorDepth"; - static final int COLOR_DEPTH_32 = 32; - static final String SCREEN_ORIENTATION = "orientation"; - static final String ORIENTATION_PORTRAIT = "portrait"; - static final String ORIENTATION_LANDSCAPE = "landscape"; - - private Context() {} - } - - static class AAMParameters { - static final String BLOB = "blob"; - static final String LOCATION_HINT = "locationHint"; - - private AAMParameters() {} - } - - static class Mbox { - static final String NAME = "name"; - static final String STATE = "state"; - static final String INDEX = "index"; - - private Mbox() {} - } - - static class Option { - static final String TYPE = "type"; - static final String CONTENT = "content"; - static final String RESPONSE_TOKENS = "responseTokens"; - - private Option() {} - } - - static class Metric { - static final String TYPE = "type"; - static final String EVENT_TOKEN = "eventToken"; - - private Metric() {} - } - - static class Notification { - static final String ID = "id"; - static final String TIMESTAMP = "timestamp"; - static final String TOKENS = "tokens"; - static final String TYPE = "type"; - static final String MBOX = "mbox"; - - private Notification() {} - } - - static class Product { - static final String ID = "id"; - static final String CATEGORY_ID = "categoryId"; - - private Product() {} - } - - static class Order { - static final String ID = "id"; - static final String TOTAL = "total"; - static final String PURCHASED_PRODUCT_IDS = "purchasedProductIds"; - - private Order() {} - } - - static class MetricType { - static final String DISPLAY = "display"; - static final String CLICK = "click"; - - private MetricType() {} - } - - private TargetJson() {} + static final String MESSAGE = "message"; + static final String ID = "id"; + static final String ID_TNT_ID = "tntId"; + static final String ID_THIRD_PARTY_ID = "thirdPartyId"; + static final String ID_MARKETING_CLOUD_VISITOR_ID = "marketingCloudVisitorId"; + static final String ID_CUSTOMER_IDS = "customerIds"; + static final String ANALYTICS_LOGGING = "logging"; + static final String ANALYTICS_CLIENT_SIDE = "client_side"; + static final String AAM_PARAMETERS = "audienceManager"; + static final String EXPERIENCE_CLOUD = "experienceCloud"; + static final String CONTEXT_PARAMETERS = "context"; + static final String ANALYTICS_PARAMETERS = "analytics"; + static final String ANALYTICS_PAYLOAD = "payload"; + static final String OPTIONS = "options"; + static final String METRICS = "metrics"; + static final String ENVIRONMENT_ID = "environmentId"; // client environment id, optional + static final String PREFETCH = "prefetch"; + static final String EXECUTE = "execute"; + static final String MBOX_RESPONSES = "mboxResponses"; + static final String PARAMETERS = "parameters"; + static final String PROFILE_PARAMETERS = "profileParameters"; + static final String PRODUCT = "product"; + static final String ORDER = "order"; + static final String NOTIFICATIONS = "notifications"; + static final String MBOXES = "mboxes"; + static final String EDGE_HOST = "edgeHost"; + static final String TOKEN = "token"; + static final String PROPERTY = "property"; + static final String HTML = "html"; + static final String JSON = "json"; + + static final List CACHED_MBOX_ACCEPTED_KEYS = + Arrays.asList(Mbox.NAME, Mbox.STATE, OPTIONS, ANALYTICS_PARAMETERS, METRICS); + + static class CustomerIds { + static final String ID = "id"; + static final String INTEGRATION_CODE = "integrationCode"; + static final String AUTHENTICATION_STATE = "authenticatedState"; + + private CustomerIds() {} + } + + static class Context { + static final String CHANNEL = "channel"; + static final String CHANNEL_MOBILE = "mobile"; + static final String MOBILE_PLATFORM = "mobilePlatform"; + static final String APPLICATION = "application"; + static final String SCREEN = "screen"; + static final String USER_AGENT = "userAgent"; + static final String TIME_OFFSET = "timeOffsetInMinutes"; + static final String PLATFORM_TYPE = "platformType"; + static final String DEVICE_NAME = "deviceName"; + static final String DEVICE_TYPE = "deviceType"; + static final String APP_ID = "id"; + static final String APP_NAME = "name"; + static final String APP_VERSION = "version"; + static final String SCREEN_WIDTH = "width"; + static final String SCREEN_HEIGHT = "height"; + static final String SCREEN_COLOR_DEPTH = "colorDepth"; + static final int COLOR_DEPTH_32 = 32; + static final String SCREEN_ORIENTATION = "orientation"; + static final String ORIENTATION_PORTRAIT = "portrait"; + static final String ORIENTATION_LANDSCAPE = "landscape"; + + private Context() {} + } + + static class AAMParameters { + static final String BLOB = "blob"; + static final String LOCATION_HINT = "locationHint"; + + private AAMParameters() {} + } + + static class Mbox { + static final String NAME = "name"; + static final String STATE = "state"; + static final String INDEX = "index"; + + private Mbox() {} + } + + static class Option { + static final String TYPE = "type"; + static final String CONTENT = "content"; + static final String RESPONSE_TOKENS = "responseTokens"; + + private Option() {} + } + + static class Metric { + static final String TYPE = "type"; + static final String EVENT_TOKEN = "eventToken"; + + private Metric() {} + } + + static class Notification { + static final String ID = "id"; + static final String TIMESTAMP = "timestamp"; + static final String TOKENS = "tokens"; + static final String TYPE = "type"; + static final String MBOX = "mbox"; + + private Notification() {} + } + + static class Product { + static final String ID = "id"; + static final String CATEGORY_ID = "categoryId"; + + private Product() {} + } + + static class Order { + static final String ID = "id"; + static final String TOTAL = "total"; + static final String PURCHASED_PRODUCT_IDS = "purchasedProductIds"; + + private Order() {} + } + + static class MetricType { + static final String DISPLAY = "display"; + static final String CLICK = "click"; + + private MetricType() {} + } + + private TargetJson() {} } diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetOrder.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetOrder.java index 197f503..52e0f61 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetOrder.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetOrder.java @@ -1,14 +1,13 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; @@ -16,21 +15,18 @@ import com.adobe.marketing.mobile.util.DataReader; import com.adobe.marketing.mobile.util.DataReaderException; import com.adobe.marketing.mobile.util.StringUtils; - import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; -/** - * Class for specifying Target order parameters - */ +/** Class for specifying Target order parameters */ public class TargetOrder { private static final String CLASS_NAME = "TargetOrder"; - final private String id; - final private double total; - final private List purchasedProductIds; + private final String id; + private final double total; + private final List purchasedProductIds; /** * Initialize a {@link TargetOrder} with an order {@link #id}, order {@link #total} and a list @@ -40,7 +36,8 @@ public class TargetOrder { * @param total {@code double} order total amount * @param purchasedProductIds a list of purchased product ids */ - public TargetOrder(final String id, final double total, final List purchasedProductIds) { + public TargetOrder( + final String id, final double total, final List purchasedProductIds) { this.id = id; this.total = total; this.purchasedProductIds = purchasedProductIds; @@ -82,14 +79,16 @@ Map toEventData() { final Map orderMap = new HashMap<>(); orderMap.put(TargetConstants.EventDataKeys.Order.ID, this.id); orderMap.put(TargetConstants.EventDataKeys.Order.TOTAL, this.total); - orderMap.put(TargetConstants.EventDataKeys.Order.PURCHASED_PRODUCT_IDS, this.purchasedProductIds); + orderMap.put( + TargetConstants.EventDataKeys.Order.PURCHASED_PRODUCT_IDS, + this.purchasedProductIds); return orderMap; } /** * Creates a {@code TargetOrder} object using information provided in {@code data} map. - *

- * This method returns null if the provided {@code data} is null or empty, or if it does not + * + *

This method returns null if the provided {@code data} is null or empty, or if it does not * contain required info for creating a {@link TargetOrder} object. * * @param data {@code Map} containing Target Order data. @@ -97,22 +96,36 @@ Map toEventData() { */ static TargetOrder fromEventData(final Map data) { if (TargetUtils.isNullOrEmpty(data)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME,"Cannot create TargetOrder object, provided data Map is empty or null."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Cannot create TargetOrder object, provided data Map is empty or null."); return null; } try { final String id = DataReader.getString(data, TargetConstants.EventDataKeys.Order.ID); if (StringUtils.isNullOrEmpty(id)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "Cannot create TargetOrder object, provided data Map doesn't contain valid order ID."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Cannot create TargetOrder object, provided data Map doesn't contain valid" + + " order ID."); return null; } - final double total = DataReader.getDouble(data, TargetConstants.EventDataKeys.Order.TOTAL); - final List purchasedProductIds = DataReader.getStringList(data, TargetConstants.EventDataKeys.Order.PURCHASED_PRODUCT_IDS); + final double total = + DataReader.getDouble(data, TargetConstants.EventDataKeys.Order.TOTAL); + final List purchasedProductIds = + DataReader.getStringList( + data, TargetConstants.EventDataKeys.Order.PURCHASED_PRODUCT_IDS); return new TargetOrder(id, total, purchasedProductIds); } catch (final DataReaderException e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME,"Cannot create TargetOrder object, provided data contains invalid fields (%s).", e.getLocalizedMessage()); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Cannot create TargetOrder object, provided data contains invalid fields (%s).", + e.getLocalizedMessage()); return null; } } @@ -125,11 +138,13 @@ public boolean equals(final Object o) { TargetOrder that = (TargetOrder) o; if (id != null ? !id.equals(that.id) : that.id != null) return false; if (total != that.total) return false; - return purchasedProductIds != null ? purchasedProductIds.equals(that.purchasedProductIds) : that.purchasedProductIds == null; + return purchasedProductIds != null + ? purchasedProductIds.equals(that.purchasedProductIds) + : that.purchasedProductIds == null; } @Override public int hashCode() { return Objects.hash(id, total, purchasedProductIds); } -} \ No newline at end of file +} diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetParameters.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetParameters.java index 5f3cf95..7d03f47 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetParameters.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetParameters.java @@ -1,44 +1,44 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; import com.adobe.marketing.mobile.services.Log; import com.adobe.marketing.mobile.util.DataReader; import com.adobe.marketing.mobile.util.DataReaderException; - import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; /** - * Target parameter class, used for specifying custom parameters to be sent in Target requests, - * such as location (former mbox) parameters, profile parameters, order/product parameters.
- * + * Target parameter class, used for specifying custom parameters to be sent in Target requests, such + * as location (former mbox) parameters, profile parameters, order/product parameters.
* Use {@link TargetParameters.Builder} to build the desired parameters */ - public class TargetParameters { private static final String CLASS_NAME = "TargetParameters"; - final private Map parameters; - final private Map profileParameters; - final private TargetProduct product; - final private TargetOrder order; + private final Map parameters; + private final Map profileParameters; + private final TargetProduct product; + private final TargetOrder order; private TargetParameters(final Builder builder) { - this.parameters = builder.parameters == null ? new HashMap() : builder.parameters; - this.profileParameters = builder.profileParameters == null ? new HashMap() : builder.profileParameters; + this.parameters = + builder.parameters == null ? new HashMap() : builder.parameters; + this.profileParameters = + builder.profileParameters == null + ? new HashMap() + : builder.profileParameters; this.product = builder.product; this.order = builder.order; } @@ -108,16 +108,22 @@ static TargetParameters merge(final List parametersList) { mergedParams.remove(""); } } catch (final Exception e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, "Failed to merge parameters, (%s)", e); + Log.warning( + TargetConstants.LOG_TAG, CLASS_NAME, "Failed to merge parameters, (%s)", e); } try { - if (targetParams.profileParameters != null && targetParams.profileParameters.size() > 0) { + if (targetParams.profileParameters != null + && targetParams.profileParameters.size() > 0) { mergedProfileParams.putAll(targetParams.profileParameters); mergedProfileParams.remove(""); } } catch (final Exception e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, "Failed to merge profile parameters, (%s)", e); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Failed to merge profile parameters, (%s)", + e); } if (targetParams.product != null) { @@ -136,15 +142,14 @@ static TargetParameters merge(final List parametersList) { .build(); } + /** Builder class for {@link TargetParameters} */ public static class Builder { private Map parameters; private Map profileParameters; private TargetProduct product; private TargetOrder order; - /** - * Create a {@link TargetParameters} object Builder - */ + /** Create a {@link TargetParameters} object Builder */ public Builder() {} /** @@ -220,18 +225,20 @@ public Map toEventData() { parametersMap.put(TargetConstants.EventDataKeys.MBOX_PARAMETERS, this.parameters); parametersMap.put(TargetConstants.EventDataKeys.PROFILE_PARAMETERS, this.profileParameters); if (this.order != null) { - parametersMap.put(TargetConstants.EventDataKeys.ORDER_PARAMETERS, this.order.toEventData()); + parametersMap.put( + TargetConstants.EventDataKeys.ORDER_PARAMETERS, this.order.toEventData()); } if (this.product != null) { - parametersMap.put(TargetConstants.EventDataKeys.PRODUCT_PARAMETERS, this.product.toEventData()); + parametersMap.put( + TargetConstants.EventDataKeys.PRODUCT_PARAMETERS, this.product.toEventData()); } return parametersMap; } /** * Creates a {@code TargetParameters} object using information provided in {@code data} map. - *

- * This method returns null if the provided {@code data} is null or empty, or if it does not + * + *

This method returns null if the provided {@code data} is null or empty, or if it does not * contain required info for creating a {@link TargetParameters} object. * * @param data {@code Map} containing Target parameters data. @@ -239,15 +246,23 @@ public Map toEventData() { */ static TargetParameters fromEventData(final Map data) { if (TargetUtils.isNullOrEmpty(data)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME,"Cannot create TargetParameters object, provided data Map is empty or null."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Cannot create TargetParameters object, provided data Map is empty or null."); return null; } try { - final Map parameters = DataReader.getStringMap(data, TargetConstants.EventDataKeys.MBOX_PARAMETERS); - final Map profileParameters = DataReader.getStringMap(data, TargetConstants.EventDataKeys.PROFILE_PARAMETERS); - final Map productParameters = DataReader.getStringMap(data, TargetConstants.EventDataKeys.PRODUCT_PARAMETERS); - final Map orderParameters = DataReader.getTypedMap(Object.class, data, TargetConstants.EventDataKeys.ORDER_PARAMETERS); + final Map parameters = + DataReader.getStringMap(data, TargetConstants.EventDataKeys.MBOX_PARAMETERS); + final Map profileParameters = + DataReader.getStringMap(data, TargetConstants.EventDataKeys.PROFILE_PARAMETERS); + final Map productParameters = + DataReader.getStringMap(data, TargetConstants.EventDataKeys.PRODUCT_PARAMETERS); + final Map orderParameters = + DataReader.getTypedMap( + Object.class, data, TargetConstants.EventDataKeys.ORDER_PARAMETERS); return new TargetParameters.Builder() .parameters(parameters) @@ -256,7 +271,10 @@ static TargetParameters fromEventData(final Map data) { .product(TargetProduct.fromEventData(productParameters)) .build(); } catch (final DataReaderException e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME,"Cannot create TargetProduct object, provided data contains invalid fields."); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Cannot create TargetProduct object, provided data contains invalid fields."); return null; } } @@ -267,8 +285,11 @@ public boolean equals(final Object o) { if (o == null || getClass() != o.getClass()) return false; TargetParameters that = (TargetParameters) o; - if (parameters != null ? !parameters.equals(that.parameters) : that.parameters != null) return false; - if (profileParameters != null ? !profileParameters.equals(that.profileParameters) : that.profileParameters != null) return false; + if (parameters != null ? !parameters.equals(that.parameters) : that.parameters != null) + return false; + if (profileParameters != null + ? !profileParameters.equals(that.profileParameters) + : that.profileParameters != null) return false; if (order != null ? !order.equals(that.order) : that.order != null) return false; return product != null ? product.equals(that.product) : that.product == null; } diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPrefetch.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPrefetch.java index 828c0dd..d668d32 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPrefetch.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPrefetch.java @@ -1,29 +1,28 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; import com.adobe.marketing.mobile.services.Log; import com.adobe.marketing.mobile.util.DataReader; import com.adobe.marketing.mobile.util.DataReaderException; - import java.util.HashMap; import java.util.Map; +/** Class representing a Target Prefetch request. */ public class TargetPrefetch { private static final String CLASS_NAME = "TargetPrefetch"; - final private String mboxName; - final private TargetParameters targetParameters; + private final String mboxName; + private final TargetParameters targetParameters; /** * Get {@link #mboxName} for this request @@ -45,6 +44,7 @@ TargetParameters getTargetParameters() { /** * Instantiate a {@link TargetPrefetch} object + * * @param mboxName {@link String} mbox name for this prefetch * @param targetParameters {@link TargetParameters} for this prefetch */ @@ -62,15 +62,17 @@ public Map toEventData() { final Map prefetchMap = new HashMap<>(); prefetchMap.put(TargetConstants.EventDataKeys.MBOX_NAME, this.mboxName); if (this.targetParameters != null) { - prefetchMap.put(TargetConstants.EventDataKeys.TARGET_PARAMETERS, this.targetParameters.toEventData()); + prefetchMap.put( + TargetConstants.EventDataKeys.TARGET_PARAMETERS, + this.targetParameters.toEventData()); } return prefetchMap; } /** * Creates a {@code TargetPrefetch} object using information provided in {@code data} map. - *

- * This method returns null if the provided {@code data} is null or empty, or if it does not + * + *

This method returns null if the provided {@code data} is null or empty, or if it does not * contain required info for creating a {@link TargetPrefetch} object. * * @param data {@code Map} containing Target Prefetch data. @@ -78,17 +80,26 @@ public Map toEventData() { */ static TargetPrefetch fromEventData(final Map data) { if (TargetUtils.isNullOrEmpty(data)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME,"Cannot create TargetPrefetch object, provided data Map is empty or null."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Cannot create TargetPrefetch object, provided data Map is empty or null."); return null; } try { - final String mboxName = DataReader.getString(data, TargetConstants.EventDataKeys.MBOX_NAME); - final Map targetParameters = DataReader.getTypedMap(Object.class, data, TargetConstants.EventDataKeys.TARGET_PARAMETERS); + final String mboxName = + DataReader.getString(data, TargetConstants.EventDataKeys.MBOX_NAME); + final Map targetParameters = + DataReader.getTypedMap( + Object.class, data, TargetConstants.EventDataKeys.TARGET_PARAMETERS); return new TargetPrefetch(mboxName, TargetParameters.fromEventData(targetParameters)); } catch (final DataReaderException e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME,"Cannot create TargetPrefetch object, provided data contains invalid fields."); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Cannot create TargetPrefetch object, provided data contains invalid fields."); return null; } } diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewButtonEventListener.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewButtonEventListener.java new file mode 100644 index 0000000..b2c5f90 --- /dev/null +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewButtonEventListener.java @@ -0,0 +1,61 @@ +/* + Copyright 2023 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ + +package com.adobe.marketing.mobile.target; + +import androidx.annotation.NonNull; +import com.adobe.marketing.mobile.services.Log; +import com.adobe.marketing.mobile.services.ui.FloatingButton; +import com.adobe.marketing.mobile.services.ui.Presentable; +import com.adobe.marketing.mobile.services.ui.PresentationError; +import com.adobe.marketing.mobile.services.ui.floatingbutton.FloatingButtonEventListener; + +class TargetPreviewButtonEventListener implements FloatingButtonEventListener { + + private static final String CLASS_NAME = "TargetPreviewButtonEventListener"; + private final TargetPreviewManager previewManager; + + TargetPreviewButtonEventListener(final TargetPreviewManager targetPreviewManager) { + this.previewManager = targetPreviewManager; + } + + @Override + public void onTapDetected(@NonNull final Presentable presentable) { + Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "Target preview button was clicked"); + previewManager.fetchWebView(); + } + + @Override + public void onPanDetected(@NonNull final Presentable presentable) {} + + @Override + public void onDismiss(@NonNull final Presentable presentable) { + Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "Target preview button was dismissed"); + } + + @Override + public void onError( + @NonNull final Presentable presentable, + @NonNull final PresentationError presentationError) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "onError - Failed to display Target preview button"); + } + + @Override + public void onHide(@NonNull final Presentable presentable) {} + + @Override + public void onShow(@NonNull final Presentable presentable) { + Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "Target preview button was shown"); + } +} diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewButtonListener.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewButtonListener.java deleted file mode 100644 index f418caa..0000000 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewButtonListener.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright 2023 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ - -package com.adobe.marketing.mobile.target; - -import com.adobe.marketing.mobile.services.ui.FloatingButtonListener; - -class TargetPreviewButtonListener implements FloatingButtonListener { - - private TargetPreviewManager previewManager; - - TargetPreviewButtonListener(final TargetPreviewManager targetPreviewManager) { - this.previewManager = targetPreviewManager; - } - - @Override - public void onTapDetected() { - previewManager.fetchWebView(); - } - - @Override - public void onPanDetected() { - } - -} diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewFullscreenDelegate.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewFullscreenDelegate.java deleted file mode 100644 index 529122a..0000000 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewFullscreenDelegate.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright 2023 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ - -package com.adobe.marketing.mobile.target; - -import com.adobe.marketing.mobile.services.Log; -import com.adobe.marketing.mobile.services.ui.FullscreenMessage; -import com.adobe.marketing.mobile.services.ui.FullscreenMessageDelegate; - -class TargetPreviewFullscreenDelegate implements FullscreenMessageDelegate { - private static final String CLASS_NAME = "TargetPreviewFullscreenDelegate"; - final private TargetPreviewManager targetPreviewManager; - - TargetPreviewFullscreenDelegate(final TargetPreviewManager previewManager) { - this.targetPreviewManager = previewManager; - } - - /** - * Invoked when a {@code UIFullScreenMessage} is displayed. - * - * @param message the {@link FullscreenMessage} being displayed - */ - @Override - public void onShow(final FullscreenMessage message) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "Target preview selection screen was displayed"); - } - - @Override - public void onDismiss(final FullscreenMessage message) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "Target preview selection screen was dismissed"); - } - - @Override - public boolean overrideUrlLoad(final FullscreenMessage message, final String url) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, String.format("Target preview override url received: %s", url)); - targetPreviewManager.previewConfirmedWithUrl(message, url); - return true; - } - - @Override - public void onShowFailure() { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "onShowFailure - Failed to display Target preview selection screen."); - } -} diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewFullscreenEventListener.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewFullscreenEventListener.java new file mode 100644 index 0000000..df9b5d1 --- /dev/null +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewFullscreenEventListener.java @@ -0,0 +1,71 @@ +/* + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ + +package com.adobe.marketing.mobile.target; + +import androidx.annotation.NonNull; +import com.adobe.marketing.mobile.services.Log; +import com.adobe.marketing.mobile.services.ui.InAppMessage; +import com.adobe.marketing.mobile.services.ui.Presentable; +import com.adobe.marketing.mobile.services.ui.PresentationError; +import com.adobe.marketing.mobile.services.ui.message.InAppMessageEventListener; + +class TargetPreviewFullscreenEventListener implements InAppMessageEventListener { + private static final String CLASS_NAME = "TargetPreviewFullscreenDelegate"; + private final TargetPreviewManager targetPreviewManager; + + TargetPreviewFullscreenEventListener(final TargetPreviewManager previewManager) { + this.targetPreviewManager = previewManager; + } + + @Override + public void onDismiss(@NonNull final Presentable presentable) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Target preview selection screen was dismissed"); + } + + @Override + public void onError( + @NonNull final Presentable presentable, + @NonNull final PresentationError presentationError) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "onError - Failed to display Target preview selection screen."); + } + + @Override + public void onHide(@NonNull final Presentable presentable) {} + + @Override + public void onShow(@NonNull final Presentable presentable) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Target preview selection screen was displayed"); + } + + @Override + public void onBackPressed(@NonNull final Presentable presentable) {} + + @Override + public boolean onUrlLoading( + @NonNull final Presentable presentable, @NonNull final String url) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + String.format("Target preview override url received: %s", url)); + targetPreviewManager.previewConfirmedWithUrl(presentable, url); + return true; + } +} diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewManager.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewManager.java index cfc40e6..a0ec5d1 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewManager.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetPreviewManager.java @@ -1,5 +1,5 @@ /* - Copyright 2023 Adobe. All rights reserved. + Copyright 2022 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -7,24 +7,32 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ +*/ package com.adobe.marketing.mobile.target; +import android.content.Context; +import android.content.res.AssetManager; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.Base64; import com.adobe.marketing.mobile.services.HttpMethod; import com.adobe.marketing.mobile.services.Log; import com.adobe.marketing.mobile.services.NetworkRequest; import com.adobe.marketing.mobile.services.Networking; import com.adobe.marketing.mobile.services.NetworkingConstants; import com.adobe.marketing.mobile.services.ui.FloatingButton; -import com.adobe.marketing.mobile.services.ui.FullscreenMessage; -import com.adobe.marketing.mobile.services.ui.MessageSettings; +import com.adobe.marketing.mobile.services.ui.InAppMessage; +import com.adobe.marketing.mobile.services.ui.Presentable; import com.adobe.marketing.mobile.services.ui.UIService; +import com.adobe.marketing.mobile.services.ui.floatingbutton.FloatingButtonSettings; +import com.adobe.marketing.mobile.services.ui.message.InAppMessageSettings; +import com.adobe.marketing.mobile.services.uri.UriOpening; +import com.adobe.marketing.mobile.util.DefaultPresentationUtilityProvider; import com.adobe.marketing.mobile.util.StreamUtils; import com.adobe.marketing.mobile.util.StringUtils; import com.adobe.marketing.mobile.util.URLBuilder; - - +import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URI; @@ -36,15 +44,15 @@ class TargetPreviewManager { private static final String CLASS_NAME = "TargetPreviewManager"; static final String CHARSET_UTF_8 = "UTF-8"; - private final static int FILL_DEVICE_DISPLAY = 100; - // ======================================================================================== // private fields // ======================================================================================== - final private Networking networkService; - final private UIService uiService; + private final Networking networkService; + private final UIService uiService; + private final UriOpening uriService; + private final Context context; protected String previewParams; protected String token; protected String endPoint; @@ -53,30 +61,37 @@ class TargetPreviewManager { private Boolean fetchingWebView; private String clientCode; - protected FloatingButton floatingButton; + protected Presentable floatingButtonPresentable; /** * Constructor, returns an instance of the {@code TargetPreviewManager}. * * @param networkService an instance of {@link Networking} to be used by the extension * @param uiService an instance of {@link UIService} to be used by the extension + * @param uriService an instance of {@link UriOpening} to be used by the extension * @see com.adobe.marketing.mobile.services.ServiceProvider */ - TargetPreviewManager(final Networking networkService, final UIService uiService) { + TargetPreviewManager( + final Networking networkService, + final UIService uiService, + final UriOpening uriService, + final Context context) { this.networkService = networkService; this.uiService = uiService; + this.uriService = uriService; + this.context = context; fetchingWebView = false; } - // ======================================================================================== // protected methods // ======================================================================================== /** - * Returns current preview parameters representing the json received from target servers as a {@code String}. - *

- * Or null if preview mode was reset or not started. + * Returns current preview parameters representing the json received from target servers as a + * {@code String}. + * + *

Or null if preview mode was reset or not started. * * @return {@link String} preview parameters */ @@ -86,16 +101,15 @@ protected String getPreviewParameters() { /** * Returns the current preview token if available. - *

- * Or returns null if preview mode was reset or not started. * - * @return {@link String} preview token + *

Or returns null if preview mode was reset or not started. + * + * @return {@link String} preview token */ protected String getPreviewToken() { return token; } - /** * Sets the local variable {@code #restartUrl} with the provided value. * @@ -106,21 +120,39 @@ protected void setRestartDeepLink(final String restartDeepLink) { } /** - * Starts the preview mode by parsing the preview deep link, fetching the webView from target server, displaying - * the preview button and creating a new custom message for the preview view. + * Starts the preview mode by parsing the preview deep link, fetching the webView from target + * server, displaying the preview button and creating a new custom message for the preview view. * * @param clientCode a {@link String} clientcode * @param deepLink a {@link String} target preview deeplink */ - protected void enterPreviewModeWithDeepLinkParams(final String clientCode, final String deepLink) { + protected void enterPreviewModeWithDeepLinkParams( + final String clientCode, final String deepLink) { if (networkService == null) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, "enterPreviewModeWithDeepLinkParams - Unable to enter preview mode, NetworkServices is not available."); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "enterPreviewModeWithDeepLinkParams - Unable to enter preview mode," + + " NetworkServices is not available."); return; } if (uiService == null) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, "enterPreviewModeWithDeepLinkParams - Unable to enter preview mode, UIService is not available."); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "enterPreviewModeWithDeepLinkParams - Unable to enter preview mode, UIService" + + " is not available."); + return; + } + + if (uriService == null) { + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "enterPreviewModeWithDeepLinkParams - Unable to enter preview mode, UriOpening" + + " is not available."); return; } @@ -128,8 +160,11 @@ protected void enterPreviewModeWithDeepLinkParams(final String clientCode, final // bail out on null/empty deepLink if (StringUtils.isNullOrEmpty(deepLink)) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "enterPreviewModeWithDeepLinkParams - Unable to enter preview mode with empty/invalid url"); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "enterPreviewModeWithDeepLinkParams - Unable to enter preview mode with" + + " empty/invalid url"); return; } @@ -138,8 +173,12 @@ protected void enterPreviewModeWithDeepLinkParams(final String clientCode, final try { url = URI.create(deepLink); } catch (final IllegalArgumentException e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - String.format("enterPreviewModeWithDeepLinkParams - Unable to enter preview mode, Invalid deep link provided, %s. Error (%s)", + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + String.format( + "enterPreviewModeWithDeepLinkParams - Unable to enter preview mode," + + " Invalid deep link provided, %s. Error (%s)", deepLink, e.getMessage())); return; } @@ -149,8 +188,13 @@ protected void enterPreviewModeWithDeepLinkParams(final String clientCode, final final Map queryParams = TargetUtils.extractQueryParameters(query); if (TargetUtils.isNullOrEmpty(queryParams)) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - String.format("enterPreviewModeWithDeepLinkParams - Unable to enter preview mode. Cannot retrieve preview token from provided deeplink : %s", deepLink)); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + String.format( + "enterPreviewModeWithDeepLinkParams - Unable to enter preview mode." + + " Cannot retrieve preview token from provided deeplink : %s", + deepLink)); return; } @@ -162,16 +206,18 @@ protected void enterPreviewModeWithDeepLinkParams(final String clientCode, final } /** - * This method will be called by the {@code TargetPreviewFullscreenDelegate} to process given url. - *

- * If it is a cancel url, it dismisses the message and exits preview mode. - * If it is a confirm url, it dismisses the message, updates preview parameters and starts a - * new view if preview restart url is set. + * This method will be called by the {@code TargetPreviewFullscreenEventListener} to process + * given url. + * + *

If it is a cancel url, it dismisses the message and exits preview mode. If it is a confirm + * url, it dismisses the message, updates preview parameters and starts a new view if preview + * restart url is set. * - * @param message A target preview {@link FullscreenMessage} instance + * @param message A target preview {@link Presentable} instance * @param stringUrl A {@link String} url associated with the clicked button */ - protected void previewConfirmedWithUrl(final FullscreenMessage message, final String stringUrl) { + protected void previewConfirmedWithUrl( + final Presentable message, final String stringUrl) { // dismiss the message without exiting preview mode. // remove the message no matter what the clicked URL is. @@ -184,7 +230,10 @@ protected void previewConfirmedWithUrl(final FullscreenMessage message, final St try { url = URI.create(stringUrl); } catch (final Exception e) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "previewConfirmedWithUrl - Invalid URL obtained from Target Preview Message %s", + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "previewConfirmedWithUrl - Invalid URL obtained from Target Preview Message %s", stringUrl); return; } @@ -193,8 +242,11 @@ protected void previewConfirmedWithUrl(final FullscreenMessage message, final St final String scheme = url.getScheme(); if (!TargetConstants.PreviewKeys.DEEPLINK_SCHEME.equals(scheme)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "previewConfirmedWithUrl - Provided deeplink scheme is not equal to the target scheme"); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "previewConfirmedWithUrl - Provided deeplink scheme is not equal to the target" + + " scheme"); return; } @@ -210,11 +262,18 @@ protected void previewConfirmedWithUrl(final FullscreenMessage message, final St final Map queryParams = TargetUtils.extractQueryParameters(query); if (TargetUtils.isNullOrEmpty(queryParams)) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, String.format("previewConfirmedWithUrl - Target Preview URL does not have preview query parameter : URL : %s", query)); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + String.format( + "previewConfirmedWithUrl - Target Preview URL does not have preview" + + " query parameter : URL : %s", + query)); return; } - final String previewParameters = queryParams.get(TargetConstants.PreviewKeys.PREVIEW_PARAMETERS); + final String previewParameters = + queryParams.get(TargetConstants.PreviewKeys.PREVIEW_PARAMETERS); try { if (!StringUtils.isNullOrEmpty(previewParameters)) { @@ -222,74 +281,116 @@ protected void previewConfirmedWithUrl(final FullscreenMessage message, final St } } catch (final UnsupportedEncodingException e) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, "Unable to URL decode the preview parameters, Error %s", e); + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Unable to URL decode the preview parameters, Error %s", + e); } // open the restart url if it exists if (StringUtils.isNullOrEmpty(restartUrl)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "previewConfirmedWithUrl - Empty Preview restart url"); - } else if (!uiService.showUrl(restartUrl)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME,"previewConfirmedWithUrl - Failed to load given preview restart url %s", restartUrl); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "previewConfirmedWithUrl - Empty Preview restart url"); + } else if (!uriService.openUri(restartUrl)) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "previewConfirmedWithUrl - Failed to load given preview restart url %s", + restartUrl); } } } /** * This method initiates a new async request to fetch the web view for the target preview. - *

- * If the connection is successful and a valid response is received, a {@code UIService.UIFullScreenMessage} will be created and displayed. - * This method will be called on preview deepLink or preview button tap detection. - * This method will not initiate a web view fetch request, if there is a request already in process. * + *

If the connection is successful and a valid response is received, a {@code + * UIService.UIFullScreenMessage} will be created and displayed. This method will be called on + * preview deepLink or preview button tap detection. This method will not initiate a web view + * fetch request, if there is a request already in process. */ protected void fetchWebView() { // Do not proceed if fetching is already in progress. if (fetchingWebView) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "fetchWebView - TargetPreview was already initialized. Fetching webView in progress."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "fetchWebView - TargetPreview was already initialized. Fetching webView in" + + " progress."); return; } fetchingWebView = true; final String targetUrl = getUrlForTargetPreviewRequest(); - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "fetchWebView - Sending preview request to url %s", targetUrl); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "fetchWebView - Sending preview request to url %s", + targetUrl); // prepare the request headers final Map requestHeaders = new HashMap<>(); - requestHeaders.put(NetworkingConstants.Headers.ACCEPT, NetworkingConstants.HeaderValues.ACCEPT_TEXT_HTML); - requestHeaders.put(NetworkingConstants.Headers.CONTENT_TYPE,NetworkingConstants.HeaderValues.CONTENT_TYPE_URL_ENCODED); - - final NetworkRequest request = new NetworkRequest(targetUrl, HttpMethod.GET, null, requestHeaders, TargetConstants.DEFAULT_NETWORK_TIMEOUT, TargetConstants.DEFAULT_NETWORK_TIMEOUT); - networkService.connectAsync(request, connection -> { - if (connection == null) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, "Target Preview unable to open connect to fetch webview"); - fetchingWebView = false; - return; - } - - - if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { - final String serverResponse = StreamUtils.readAsString(connection.getInputStream()); - if (!StringUtils.isNullOrEmpty(serverResponse)) { - webViewHtml = serverResponse; - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "Successfully fetched webview for preview mode, response body %s", - webViewHtml); - createAndShowMessage(); - } - } else { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME, String.format("Failed to fetch preview webview with connection status %s, response body %s", - connection.getResponseCode(), connection.getResponseMessage())); - } - - connection.close(); - fetchingWebView = false; - }); + requestHeaders.put( + NetworkingConstants.Headers.ACCEPT, + NetworkingConstants.HeaderValues.ACCEPT_TEXT_HTML); + requestHeaders.put( + NetworkingConstants.Headers.CONTENT_TYPE, + NetworkingConstants.HeaderValues.CONTENT_TYPE_URL_ENCODED); + + final NetworkRequest request = + new NetworkRequest( + targetUrl, + HttpMethod.GET, + null, + requestHeaders, + TargetConstants.DEFAULT_NETWORK_TIMEOUT, + TargetConstants.DEFAULT_NETWORK_TIMEOUT); + networkService.connectAsync( + request, + connection -> { + if (connection == null) { + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Target Preview unable to open connect to fetch webview"); + fetchingWebView = false; + return; + } + + if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { + final String serverResponse = + StreamUtils.readAsString(connection.getInputStream()); + if (!StringUtils.isNullOrEmpty(serverResponse)) { + webViewHtml = serverResponse; + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Successfully fetched webview for preview mode, response body" + + " %s", + webViewHtml); + createAndShowMessage(); + } + } else { + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, + String.format( + "Failed to fetch preview webview with connection status %s," + + " response body %s", + connection.getResponseCode(), + connection.getResponseMessage())); + } + + connection.close(); + fetchingWebView = false; + }); } - /** - * Called when the preview message is closed, it resets all the target preview properties. - * - */ + /** Called when the preview message is closed, it resets all the target preview properties. */ protected void resetTargetPreviewProperties() { token = null; webViewHtml = null; @@ -298,47 +399,56 @@ protected void resetTargetPreviewProperties() { previewParams = null; // remove preview button - if (floatingButton != null) { - floatingButton.remove(); - floatingButton = null; + if (floatingButtonPresentable != null) { + floatingButtonPresentable.dismiss(); + floatingButtonPresentable = null; } } - // ======================================================================================== // private methods // ======================================================================================== /** - * Extracts token and endPoint parameters if present in the deepLink query params {@code Map} and sets them - * in local variables for later user. - *

- * Tries to read the preview endpoint from the preview parameters, if unavailable assign {@link #endPoint} with the default - * endpoint. - * Tries to read the preview token from the preview parameters, if unavailable returns false. + * Extracts token and endPoint parameters if present in the deepLink query params {@code Map} + * and sets them in local variables for later user. + * + *

Tries to read the preview endpoint from the preview parameters, if unavailable assign + * {@link #endPoint} with the default endpoint. Tries to read the preview token from the preview + * parameters, if unavailable returns false. * * @param previewParameters {@link Map} representing preview parameters - * @return {@code boolean} representing the success of reading the preview token from the previewParameters + * @return {@code boolean} representing the success of reading the preview token from the + * previewParameters */ private boolean setupTargetPreviewParameters(final Map previewParameters) { // read and set endpoint try { - final String previewEndPoint = previewParameters.get(TargetConstants.PreviewKeys.PREVIEW_ENDPOINT); + final String previewEndPoint = + previewParameters.get(TargetConstants.PreviewKeys.PREVIEW_ENDPOINT); if (!StringUtils.isNullOrEmpty(previewEndPoint)) { this.endPoint = URLDecoder.decode(previewEndPoint, CHARSET_UTF_8); } else { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "setupTargetPreviewParameters - Using the Default endpoint"); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "setupTargetPreviewParameters - Using the Default endpoint"); this.endPoint = TargetConstants.PreviewKeys.DEFAULT_TARGET_PREVIEW_ENDPOINT; } } catch (UnsupportedEncodingException e) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "Decode error while extracting preview endpoint, Error %s", e); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Decode error while extracting preview endpoint, Error %s", + e); } // read and set preview token try { - final String encodedToken = previewParameters.get(TargetConstants.PreviewKeys.PREVIEW_TOKEN); + final String encodedToken = + previewParameters.get(TargetConstants.PreviewKeys.PREVIEW_TOKEN); if (!StringUtils.isNullOrEmpty(encodedToken)) { token = URLDecoder.decode(encodedToken, CHARSET_UTF_8); @@ -346,78 +456,113 @@ private boolean setupTargetPreviewParameters(final Map previewPa } } catch (final UnsupportedEncodingException e) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "Decode error while extracting preview token, Error %s", e); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Decode error while extracting preview token, Error %s", + e); } return false; } - /** * Creates and displays a {@code UIService.FloatingButton}. - *

- * Also attaches a {@code TargetPreviewButtonListener} to the {@code #floatingButton} to listen to the events on - * that {@code #floatingButton}. - * Doesn't create a {@code UIService.FloatingButton} instance, if the {@code UIService} is unavailable. * + *

Also attaches a {@code TargetPreviewButtonListener} to the {@code #floatingButton} to + * listen to the events on that {@code #floatingButton}. Doesn't create a {@code + * UIService.FloatingButton} instance, if the {@code UIService} is unavailable. */ private void createAndShowFloatingButton() { - if (floatingButton != null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "createAndShowFloatingButton - Floating button already exists"); + if (floatingButtonPresentable != null) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "createAndShowFloatingButton - Floating button already exists"); return; } - TargetPreviewButtonListener targetPreviewButtonListener = new TargetPreviewButtonListener(this); - floatingButton = uiService.createFloatingButton(targetPreviewButtonListener); + final AssetManager assetManager = context.getAssets(); + if (assetManager == null) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "createAndShowFloatingButton - Unable to instantiate the floating button for" + + " target preview, cannot find button image"); + return; + } - if (floatingButton != null) { - floatingButton.display(); - } else { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "createAndShowFloatingButton - Unable to instantiate the floating button for target preview"); + try { + final String backgroundImageString = + StreamUtils.readAsString( + assetManager.open(TargetConstants.PREVIEW_FLOATING_BUTTON_ASSET_FILE)); + final byte[] backgroundImage = Base64.decode(backgroundImageString, Base64.DEFAULT); + final Bitmap floatingButtonImage = + BitmapFactory.decodeStream(new ByteArrayInputStream(backgroundImage)); + + floatingButtonPresentable = + uiService.create( + new FloatingButton( + new FloatingButtonSettings.Builder() + .initialGraphic(floatingButtonImage) + .build(), + new TargetPreviewButtonEventListener(this)), + new DefaultPresentationUtilityProvider()); + floatingButtonPresentable.show(); + } catch (final Exception e) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "createAndShowFloatingButton - Unable to instantiate the floating button for" + + " target preview %s", + e.getMessage()); } } /** * Creates and displays a {@code UIService.UIFullScreenMessage}. - *

- * Also attaches a {@code TargetPreviewFullscreenDelegate} to the {@code UIService.UIFullScreenMessage} to listen to the button clicks on - * that message. - * Doesn't create a {@code UIService.UIFullScreenMessage} instance, if the {@link UIService} is unavailable or if there is another - * {@code UIService.UIFullScreenMessage} already being displayed. * + *

Also attaches a {@code TargetPreviewFullscreenDelegate} to the {@code + * UIService.UIFullScreenMessage} to listen to the button clicks on that message. Doesn't create + * a {@code UIService.UIFullScreenMessage} instance, if the {@link UIService} is unavailable or + * if there is another {@code UIService.UIFullScreenMessage} already being displayed. */ private void createAndShowMessage() { - - final TargetPreviewFullscreenDelegate previewFullscreenListener = new TargetPreviewFullscreenDelegate(this); - final MessageSettings messageSettings = new MessageSettings(); // Target fullscreen messages are displayed at 100% scale - messageSettings.setHeight(FILL_DEVICE_DISPLAY); - messageSettings.setWidth(FILL_DEVICE_DISPLAY); - messageSettings.setParent(this); - messageSettings.setVerticalAlign(MessageSettings.MessageAlignment.TOP); - messageSettings.setHorizontalAlign(MessageSettings.MessageAlignment.CENTER); - messageSettings.setDisplayAnimation(MessageSettings.MessageAnimation.NONE); - messageSettings.setDismissAnimation(MessageSettings.MessageAnimation.NONE); - messageSettings.setBackdropColor("#FFFFFF"); // html code for white - messageSettings.setBackdropOpacity(1); - final FullscreenMessage message = uiService.createFullscreenMessage(webViewHtml, previewFullscreenListener, false , messageSettings); - - if (message != null) { - message.show(); - } else { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "createAndShowMessage - Unable to instantiate the full screen message for target preview"); + final InAppMessageSettings inAppMessageSettings = + new InAppMessageSettings.Builder() + .content(webViewHtml) + .backgroundColor("#FFFFFFF") + .backdropOpacity(1) + .build(); + + try { + final Presentable inAppMessagePresentable = + uiService.create( + new InAppMessage( + inAppMessageSettings, + new TargetPreviewFullscreenEventListener(this)), + new DefaultPresentationUtilityProvider()); + inAppMessagePresentable.show(); + } catch (final Exception e) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "createAndShowMessage - Unable to instantiate the full screen message for" + + " target preview %s", + e.getMessage()); } } /** * Creates a url for the target preview request. * - * @return {@link String} the preview request url with {@link #endPoint}, {@link #clientCode} and {@link #token} + * @return {@link String} the preview request url with {@link #endPoint}, {@link #clientCode} + * and {@link #token} */ private String getUrlForTargetPreviewRequest() { - return new URLBuilder().enableSSL(true) + return new URLBuilder() + .enableSSL(true) .setServer(endPoint) .addPath("ui") .addPath("admin") @@ -426,4 +571,4 @@ private String getUrlForTargetPreviewRequest() { .addQueryParameter("token", token) .build(); } -} \ No newline at end of file +} diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetProduct.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetProduct.java index 40c1ced..9e80822 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetProduct.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetProduct.java @@ -1,14 +1,13 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; @@ -16,22 +15,20 @@ import com.adobe.marketing.mobile.util.DataReader; import com.adobe.marketing.mobile.util.DataReaderException; import com.adobe.marketing.mobile.util.StringUtils; - import java.util.HashMap; import java.util.Map; import java.util.Objects; -/** - * Class for specifying Target product parameters - */ +/** Class for specifying Target product parameters */ public class TargetProduct { private static final String CLASS_NAME = "TargetProduct"; - final private String id; - final private String categoryId; + private final String id; + private final String categoryId; /** - * Initialize a {@link TargetProduct} with a product {@link #id} and a productCategoryId {@link #categoryId} + * Initialize a {@link TargetProduct} with a product {@link #id} and a productCategoryId {@link + * #categoryId} * * @param id {@link String} product id * @param categoryId {@link String} product category id @@ -73,8 +70,8 @@ Map toEventData() { /** * Creates a {@code TargetProduct} object using information provided in {@code data} map. - *

- * This method returns null if the provided {@code data} is null or empty, or if it does not + * + *

This method returns null if the provided {@code data} is null or empty, or if it does not * contain required info for creating a {@link TargetProduct} object. * * @param data {@code Map} containing Target Product data. @@ -82,21 +79,32 @@ Map toEventData() { */ static TargetProduct fromEventData(final Map data) { if (TargetUtils.isNullOrEmpty(data)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME,"Cannot create TargetProduct object, provided data Map is empty or null."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Cannot create TargetProduct object, provided data Map is empty or null."); return null; } try { final String id = DataReader.getString(data, TargetConstants.EventDataKeys.Product.ID); if (StringUtils.isNullOrEmpty(id)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "Cannot create TargetProduct object, provided data Map doesn't contain valid product ID."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Cannot create TargetProduct object, provided data Map doesn't contain" + + " valid product ID."); return null; } - final String categoryId = DataReader.getString(data, TargetConstants.EventDataKeys.Product.CATEGORY_ID); + final String categoryId = + DataReader.getString(data, TargetConstants.EventDataKeys.Product.CATEGORY_ID); return new TargetProduct(id, categoryId); } catch (final DataReaderException e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME,"Cannot create TargetProduct object, provided data contains invalid fields."); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Cannot create TargetProduct object, provided data contains invalid fields."); return null; } } diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetRequest.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetRequest.java index 7900ef0..361b5b7 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetRequest.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetRequest.java @@ -1,14 +1,13 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; @@ -16,20 +15,17 @@ import com.adobe.marketing.mobile.services.Log; import com.adobe.marketing.mobile.util.DataReader; import com.adobe.marketing.mobile.util.DataReaderException; - import java.util.HashMap; import java.util.Map; import java.util.Objects; -/** - * Target request object. - */ +/** Target request object. */ public class TargetRequest { private static final String CLASS_NAME = "TargetProduct"; - final private String mboxName; - final private TargetParameters targetParameters; - final private String defaultContent; + private final String mboxName; + private final TargetParameters targetParameters; + private final String defaultContent; private String responsePairId; private AdobeCallback contentCallback; private AdobeTargetDetailedCallback contentWithDataCallback; @@ -37,13 +33,17 @@ public class TargetRequest { /** * Instantiate a {@link TargetRequest} object * - * @param mboxName {@link String} mbox name for this request + * @param mboxName {@link String} mbox name for this request * @param targetParameters {@link TargetParameters} for this request - * @param defaultContent {@code String} default content for this request - * @param contentCallback {@code AdobeCallback} which will get called with Target mbox content + * @param defaultContent {@code String} default content for this request + * @param contentCallback {@code AdobeCallback} which will get called with Target mbox + * content */ - public TargetRequest(final String mboxName, final TargetParameters targetParameters, - final String defaultContent, final AdobeCallback contentCallback) { + public TargetRequest( + final String mboxName, + final TargetParameters targetParameters, + final String defaultContent, + final AdobeCallback contentCallback) { this.mboxName = mboxName; this.targetParameters = targetParameters; this.defaultContent = defaultContent; @@ -53,14 +53,18 @@ public TargetRequest(final String mboxName, final TargetParameters targetParamet /** * Instantiate a {@link TargetRequest} object. * - * @param mboxName {@link String} mbox name for this request. + * @param mboxName {@link String} mbox name for this request. * @param targetParameters {@link TargetParameters} for this request. - * @param defaultContent {@link String} default content for this request. - * @param contentWithDataCallback {@link AdobeTargetDetailedCallback} which will get called with Target mbox content and other optional data such as Target response tokens, - * analytics payload, click metric analytics payload if available. + * @param defaultContent {@link String} default content for this request. + * @param contentWithDataCallback {@link AdobeTargetDetailedCallback} which will get called with + * Target mbox content and other optional data such as Target response tokens, analytics + * payload, click metric analytics payload if available. */ - public TargetRequest(final String mboxName, final TargetParameters targetParameters, final String defaultContent, - final AdobeTargetDetailedCallback contentWithDataCallback) { + public TargetRequest( + final String mboxName, + final TargetParameters targetParameters, + final String defaultContent, + final AdobeTargetDetailedCallback contentWithDataCallback) { this.mboxName = mboxName; this.targetParameters = targetParameters; this.defaultContent = defaultContent; @@ -141,15 +145,17 @@ public Map toEventData() { requestMap.put(TargetConstants.EventDataKeys.DEFAULT_CONTENT, this.defaultContent); requestMap.put(TargetConstants.EventDataKeys.TARGET_RESPONSE_PAIR_ID, this.responsePairId); if (this.targetParameters != null) { - requestMap.put(TargetConstants.EventDataKeys.TARGET_PARAMETERS, this.targetParameters.toEventData()); + requestMap.put( + TargetConstants.EventDataKeys.TARGET_PARAMETERS, + this.targetParameters.toEventData()); } return requestMap; } /** * Creates a {@code TargetRequest} object using information provided in {@code data} map. - *

- * This method returns null if the provided {@code data} is null or empty, or if it does not + * + *

This method returns null if the provided {@code data} is null or empty, or if it does not * contain required info for creating a {@link TargetRequest} object. * * @param data {@code Map} containing Target Request data. @@ -157,22 +163,39 @@ public Map toEventData() { */ static TargetRequest fromEventData(final Map data) { if (TargetUtils.isNullOrEmpty(data)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME,"Cannot create TargetRequest object, provided data Map is empty or null."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Cannot create TargetRequest object, provided data Map is empty or null."); return null; } try { - final String mboxName = DataReader.getString(data, TargetConstants.EventDataKeys.MBOX_NAME); - final Map targetParameters = DataReader.getTypedMap(Object.class, data, TargetConstants.EventDataKeys.TARGET_PARAMETERS); - final String defaultContent = DataReader.getString(data, TargetConstants.EventDataKeys.DEFAULT_CONTENT); - final String responsePairId = DataReader.getString(data, TargetConstants.EventDataKeys.TARGET_RESPONSE_PAIR_ID); - - TargetRequest targetRequest = new TargetRequest(mboxName, TargetParameters.fromEventData(targetParameters), defaultContent, (AdobeCallback) null); + final String mboxName = + DataReader.getString(data, TargetConstants.EventDataKeys.MBOX_NAME); + final Map targetParameters = + DataReader.getTypedMap( + Object.class, data, TargetConstants.EventDataKeys.TARGET_PARAMETERS); + final String defaultContent = + DataReader.getString(data, TargetConstants.EventDataKeys.DEFAULT_CONTENT); + final String responsePairId = + DataReader.getString( + data, TargetConstants.EventDataKeys.TARGET_RESPONSE_PAIR_ID); + + TargetRequest targetRequest = + new TargetRequest( + mboxName, + TargetParameters.fromEventData(targetParameters), + defaultContent, + (AdobeCallback) null); targetRequest.setResponsePairId(responsePairId); return targetRequest; } catch (final DataReaderException e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME,"Cannot create TargetRequest object, provided data contains invalid fields."); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Cannot create TargetRequest object, provided data contains invalid fields."); return null; } } @@ -183,16 +206,33 @@ public boolean equals(final Object o) { if (o == null || getClass() != o.getClass()) return false; TargetRequest that = (TargetRequest) o; - if (mboxName != null ? !mboxName.equals(that.mboxName) : that.mboxName != null) return false; - if (targetParameters != null ? !targetParameters.equals(that.targetParameters) : that.targetParameters != null) return false; - if (defaultContent != null ? !defaultContent.equals(that.defaultContent) : that.defaultContent != null) return false; - if (responsePairId != null ? !responsePairId.equals(that.responsePairId) : that.responsePairId != null) return false; - if (contentCallback != null ? !contentCallback.equals(that.contentCallback) : that.contentCallback != null) return false; - return contentWithDataCallback != null ? contentWithDataCallback.equals(that.contentWithDataCallback) : that.contentWithDataCallback == null; + if (mboxName != null ? !mboxName.equals(that.mboxName) : that.mboxName != null) + return false; + if (targetParameters != null + ? !targetParameters.equals(that.targetParameters) + : that.targetParameters != null) return false; + if (defaultContent != null + ? !defaultContent.equals(that.defaultContent) + : that.defaultContent != null) return false; + if (responsePairId != null + ? !responsePairId.equals(that.responsePairId) + : that.responsePairId != null) return false; + if (contentCallback != null + ? !contentCallback.equals(that.contentCallback) + : that.contentCallback != null) return false; + return contentWithDataCallback != null + ? contentWithDataCallback.equals(that.contentWithDataCallback) + : that.contentWithDataCallback == null; } @Override public int hashCode() { - return Objects.hash(mboxName, targetParameters, contentCallback, contentWithDataCallback, defaultContent, responsePairId); + return Objects.hash( + mboxName, + targetParameters, + contentCallback, + contentWithDataCallback, + defaultContent, + responsePairId); } } diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetRequestBuilder.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetRequestBuilder.java index 88ab673..208e5d2 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetRequestBuilder.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetRequestBuilder.java @@ -1,14 +1,13 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; @@ -17,826 +16,948 @@ import com.adobe.marketing.mobile.services.Log; import com.adobe.marketing.mobile.util.DataReader; import com.adobe.marketing.mobile.util.StringUtils; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; -/** - * This class is used to create the json body for the target requests. - */ +/** This class is used to create the json body for the target requests. */ class TargetRequestBuilder { - private static final String CLASS_NAME = "TargetRequestBuilder"; - private final DeviceInforming deviceInfoService; - private final TargetPreviewManager targetPreviewManager; - private final TargetState targetState; - - /** - * Constructor for TargetRequestBuilder. - * @param deviceInfoService {@link DeviceInforming} instance - * @param targetPreviewManager {@link TargetPreviewManager} instance - */ - TargetRequestBuilder(final DeviceInforming deviceInfoService, - final TargetPreviewManager targetPreviewManager, - final TargetState targetState) { - this.deviceInfoService = deviceInfoService; - this.targetPreviewManager = targetPreviewManager; - this.targetState = targetState; - } - - /** - * Creates the target request {@code JSONObject} that we have to send to target APIs. - * - * @param prefetchArray the list of {@link TargetPrefetch} objects with mboxes that we want to prefetch - * @param executeArray the list of {@link TargetRequest} objects with mboxes that we want to execute - * @param parameters {@link TargetParameters} object provided by the customer - * @param notifications viewed mboxes that we cached - * @param propertyToken a {@link String} to be passed for all requests - * @param identitySharedState {@code Map prefetchArray, - final List executeArray, - final TargetParameters parameters, - final List notifications, - final String propertyToken, - final Map identitySharedState, - final Map lifecycleData) { - try { - // add default parameters - final JSONObject defaultParamJson = getDefaultJsonObject(null, - null, - null, - targetState.getEnvironmentId(), - identitySharedState); - - // add prefetch mBoxes - final JSONArray prefetchMboxesNode = getPrefetchMboxes(prefetchArray, parameters, lifecycleData); - - if (prefetchMboxesNode != null && prefetchMboxesNode.length() > 0) { - final JSONObject prefetchJson = new JSONObject(); - prefetchJson.put(TargetJson.MBOXES, prefetchMboxesNode); - defaultParamJson.put(TargetJson.PREFETCH, prefetchJson); - } - - // add notification mBoxes - if (notifications != null && !notifications.isEmpty()) { - defaultParamJson.put(TargetJson.NOTIFICATIONS, new JSONArray(notifications)); - } - - // add execute mBoxes - final JSONArray executeMboxesNode = getExecuteMboxes(executeArray, parameters, lifecycleData); - - if (executeMboxesNode != null && executeMboxesNode.length() > 0) { - final JSONObject executeJson = new JSONObject(); - executeJson.put(TargetJson.MBOXES, executeMboxesNode); - defaultParamJson.put(TargetJson.EXECUTE, executeJson); - } - - // Add property token - if (!StringUtils.isNullOrEmpty(propertyToken)) { - final JSONObject tokenJson = new JSONObject(); - tokenJson.put(TargetJson.TOKEN, propertyToken); - defaultParamJson.put(TargetJson.PROPERTY, tokenJson); - } - - // add preview parameters - final JSONObject previewParameters = getPreviewParameters(); - - if (previewParameters != null) { - final Iterator keys = previewParameters.keys(); - - while (keys.hasNext()) { - final String key = keys.next(); - defaultParamJson.put(key, previewParameters.get(key)); - } - } - - return defaultParamJson; - } catch (final JSONException e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.REQUEST_GENERATION_FAILED, e); - return null; - } - } - - /** - * Creates the {@code JSONObject} needed for the Target API requests. - * - * @param defaultJsonObject {@code JSONObject} containing the base request data attached to all Target requests. - * @param prefetch the {@code Map} containing the request prefetch data. - * @param execute the {@code Map} containing the request execute data. - * @param notifications {@code List>} containing the display or click notification data. - * @param propertyToken a {@link String} containing the configured Target {@code at_property}. - * @return the pre-built {@link JSONObject} for Target request. - */ - JSONObject getRequestPayload(final JSONObject defaultJsonObject, - final Map prefetch, - final Map execute, - final List> notifications, - final String propertyToken) { - try { - // add default parameters - final JSONObject defaultParamJson = defaultJsonObject == null ? new JSONObject() : defaultJsonObject; - - // add prefetch node - if (prefetch != null && !prefetch.isEmpty()) { - final JSONObject prefetchNode = new JSONObject(prefetch); - defaultParamJson.put(TargetJson.PREFETCH, prefetchNode); - } - - // add execute node - if (execute != null && !execute.isEmpty()) { - final JSONObject executeNode = new JSONObject(execute); - defaultParamJson.put(TargetJson.EXECUTE, executeNode); - } - - // add notifications node - if (notifications != null && !notifications.isEmpty()) { - final JSONArray notificationArrayNode = new JSONArray(); - for (Map notification : notifications) { - final JSONObject notificationNode = new JSONObject(notification); - notificationArrayNode.put(notificationNode); - } - defaultParamJson.put(TargetJson.NOTIFICATIONS, notificationArrayNode); - } - - // Add property token - if (!StringUtils.isNullOrEmpty(propertyToken)) { - final JSONObject tokenJson = new JSONObject(); - tokenJson.put(TargetJson.TOKEN, propertyToken); - defaultParamJson.put(TargetJson.PROPERTY, tokenJson); - } - - // add preview parameters - final JSONObject previewParameters = getPreviewParameters(); - if (previewParameters != null) { - final Iterator keys = previewParameters.keys(); - while (keys.hasNext()) { - final String key = keys.next(); - defaultParamJson.put(key, previewParameters.get(key)); - } - } - - return defaultParamJson; - } catch (final JSONException e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, "getRequestPayload - (%s) (%s)", TargetErrors.REQUEST_GENERATION_FAILED, e); - return null; - } - } - - /** - * Creates the display notification payload - * - * @param mboxName mbox name - * @param cachedMboxJson the cached mbox - * @param parameters {@link TargetParameters} object associated with the notification - * @param timestamp {@code long} timestamp associated with the event - * @param lifecycleData {@code Map} shared state of lifecycle extension - * @return the {@link JSONObject} payload for notification - */ - JSONObject getDisplayNotificationJsonObject(final String mboxName, final JSONObject cachedMboxJson, - final TargetParameters parameters, final long timestamp, - final Map lifecycleData) { - try { - final JSONObject notificationNode = new JSONObject(); - notificationNode.put(TargetJson.Notification.ID, UUID.randomUUID().toString()); - notificationNode.put(TargetJson.Notification.TIMESTAMP, timestamp); - notificationNode.put(TargetJson.Metric.TYPE, TargetJson.MetricType.DISPLAY); - setTargetParametersJson(notificationNode, parameters, lifecycleData); - - final JSONObject mboxNode = new JSONObject(); - mboxNode.put(TargetJson.Mbox.NAME, mboxName); - - if (cachedMboxJson == null) { - return null; - } - - final String mboxState = cachedMboxJson.optString(TargetJson.Mbox.STATE, ""); - - if (!mboxState.isEmpty()) { - mboxNode.put(TargetJson.Mbox.STATE, mboxState); - } - - notificationNode.put(TargetJson.Notification.MBOX, mboxNode); - - //Gather display event tokens - final JSONArray optionsArray = cachedMboxJson.optJSONArray(TargetJson.OPTIONS); - - if (optionsArray != null) { - - final JSONArray tokens = new JSONArray(); - - for (int i = 0; i < optionsArray.length(); i++) { - final JSONObject option = optionsArray.optJSONObject(i); - - if (option == null || StringUtils.isNullOrEmpty(option.optString(TargetJson.Metric.EVENT_TOKEN, ""))) { - continue; - } - - final String optionEventToken = option.optString(TargetJson.Metric.EVENT_TOKEN, ""); - tokens.put(optionEventToken); - } - - if (tokens.length() == 0) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - TargetErrors.DISPLAY_NOTIFICATION_TOKEN_EMPTY); - return null; - } - - notificationNode.put(TargetJson.Notification.TOKENS, tokens); - } - - return notificationNode; - } catch (final JSONException exception) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.DISPLAY_NOTIFICATION_CREATE_FAILED, exception); - } - - return null; - } - - /** - * Creates the clicked mbox json object based on the cached mbox json node. - * It will contain the following params: mbox, parameters, order, product, clickToken , hit and timestamp. - * mbox order and product parameters of them might be missing if they are not provided from the public API. - * - * @param cachedMboxJson an {@link JSONObject} mbox node cached after prefetch/load request - * @param parameters {@link TargetParameters} corresponding to the clicked location - * @param timestamp {@code long} timestamp associated with the event - * @param lifecycleData {@code Map} shared state of lifecycle extension - * @return mbox node for the click notification - */ - JSONObject getClickNotificationJsonObject(final JSONObject cachedMboxJson, - final TargetParameters parameters, - final long timestamp, - final Map lifecycleData) { - try { - final JSONObject notificationNode = new JSONObject(); - notificationNode.put(TargetJson.Notification.ID, UUID.randomUUID().toString()); - notificationNode.put(TargetJson.Notification.TIMESTAMP, timestamp); - notificationNode.put(TargetJson.Metric.TYPE, TargetJson.MetricType.CLICK); - setTargetParametersJson(notificationNode, parameters, lifecycleData); - - if (cachedMboxJson == null) { - return notificationNode; - } - - final String mboxName = cachedMboxJson.getString(TargetJson.Mbox.NAME); - - final JSONObject mboxNode = new JSONObject(); - mboxNode.put(TargetJson.Mbox.NAME, mboxName); - - notificationNode.put(TargetJson.Notification.MBOX, mboxNode); - - final JSONArray metrics = cachedMboxJson.getJSONArray(TargetJson.METRICS); - - final JSONArray tokens = new JSONArray(); - - for (int i = 0; i < metrics.length(); i++) { - final JSONObject metric = metrics.optJSONObject(i); - - if (metric == null || !TargetJson.MetricType.CLICK.equals(metric.optString(TargetJson.Metric.TYPE, "")) - || metric.optString(TargetJson.Metric.EVENT_TOKEN, "").isEmpty()) { - continue; - } - - final String metricToken = metric.optString(TargetJson.Metric.EVENT_TOKEN, ""); - tokens.put(metricToken); - } - - if (tokens.length() == 0) { - throw new JSONException(TargetErrors.TOKEN_LIST_EMPTY_OR_NULL); - } - - notificationNode.put(TargetJson.Notification.TOKENS, tokens); - - return notificationNode; - } catch (final JSONException exception) { - Log.warning(TargetConstants.LOG_TAG, TargetErrors.CLICK_NOTIFICATION_CREATE_FAILED, - cachedMboxJson.toString()); - } - - return null; - } - - /** - * Gets the default {@code JSONObject} attached to every Target API request. - * - * @param id {@code Map} containing the identifiers for the visitor. - * @param context {@code Map} specifying the context for the request. - * @param experienceCloud {@code Map} containing the Analytics and Audience Manager integration info. - * @param environmentId {@code long} containing the Target environmentId. - * @param identityData {@code Map} shared state of Identity extension - * @return {@code JSONObject} containing the default Target request payload. - */ - JSONObject getDefaultJsonObject(final Map id, - final Map context, - final Map experienceCloud, - final long environmentId, - final Map identityData) { - try { - final JSONObject defaultParamJson = new JSONObject(); - - // add id Node - final JSONObject idNode; - - if (id != null && !id.isEmpty()) { - idNode = new JSONObject(id); - } else { - idNode = new JSONObject(); - - if (!StringUtils.isNullOrEmpty(targetState.getTntId())) { - idNode.put(TargetJson.ID_TNT_ID, targetState.getTntId()); - } - - if (!StringUtils.isNullOrEmpty(targetState.getThirdPartyId())) { - idNode.put(TargetJson.ID_THIRD_PARTY_ID, targetState.getThirdPartyId()); - } - - final String visitorMarketingCloudId = DataReader.optString(identityData, TargetConstants.Identity.VISITOR_ID_MID, ""); - if (!StringUtils.isNullOrEmpty(visitorMarketingCloudId)) { - idNode.put(TargetJson.ID_MARKETING_CLOUD_VISITOR_ID, visitorMarketingCloudId); - } - - final List> visitorCustomerIds = DataReader.optTypedListOfMap(Object.class, identityData, TargetConstants.Identity.VISITOR_IDS_LIST, null); - if (visitorCustomerIds != null && !visitorCustomerIds.isEmpty()) { - idNode.put(TargetJson.ID_CUSTOMER_IDS, getCustomerIDs(visitorCustomerIds)); - } - } - - if (idNode.length() > 0) { - defaultParamJson.put(TargetJson.ID, idNode); - } - - // add context Node - final JSONObject contextNode; - - if (context != null && !context.isEmpty()) { - contextNode = new JSONObject(context); - } else { - contextNode = getContextObject(); - } - - defaultParamJson.put(TargetJson.CONTEXT_PARAMETERS, contextNode); - - // add experienceCloud Node - final JSONObject experienceCloudNode; - - if (experienceCloud != null && !experienceCloud.isEmpty()) { - experienceCloudNode = new JSONObject(experienceCloud); - } else { - final String visitorBlob = DataReader.optString(identityData, TargetConstants.Identity.VISITOR_ID_BLOB, ""); - final String visitorLocationHint = DataReader.optString(identityData, TargetConstants.Identity.VISITOR_ID_LOCATION_HINT, ""); - experienceCloudNode = getExperienceCloudObject(visitorBlob, visitorLocationHint); - } - - defaultParamJson.put(TargetJson.EXPERIENCE_CLOUD, experienceCloudNode); - - // add environmentId - if (environmentId != 0L) { - defaultParamJson.put(TargetJson.ENVIRONMENT_ID, environmentId); - } - - return defaultParamJson; - - } catch (final JSONException e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, "Failed to create base JSON object for Target request (%s)", e); - return null; - } - } - - /** - * Creates a {@code JSONArray} containing all the batch mboxes, the mboxes will have an auto-incremental index. - * - * @param targetRequestList the {@code List} of batch request - * @param globalParameters global {@link TargetParameters} to be merged with per-mbox parameters - * @param lifecycleData {@code Map} shared state of lifecycle extension - * @return the {@code JSONArray} generated from the input {@code targetRequestList} - */ - private JSONArray getExecuteMboxes(final List targetRequestList, - final TargetParameters globalParameters, - final Map lifecycleData) { - if (targetRequestList == null) { - return null; - } - - final JSONArray mBoxArrayNode = new JSONArray(); - int index = 0; - - for (TargetRequest currentMbox : targetRequestList) { - try { - mBoxArrayNode.put(createMboxJsonObject(currentMbox.getMboxName(), - currentMbox.getTargetParameters(), index, globalParameters, lifecycleData)); - index++; - } catch (final JSONException exception) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "getExecuteMboxes -Failed to create Json Node for mbox %s (%s)", - currentMbox.getMboxName(), exception); - } - } - - return mBoxArrayNode; - } - - private JSONObject getContextObject() throws JSONException { - final JSONObject contextJson = new JSONObject(); - contextJson.put(TargetJson.Context.CHANNEL, TargetJson.Context.CHANNEL_MOBILE); - contextJson.put(TargetJson.Context.MOBILE_PLATFORM, getPlatformContextObject()); - contextJson.put(TargetJson.Context.APPLICATION, getAppContextObject()); - contextJson.put(TargetJson.Context.SCREEN, getScreenContextObject()); - - final String userAgent = deviceInfoService.getDefaultUserAgent(); - - if (!StringUtils.isNullOrEmpty(userAgent)) { - contextJson.put(TargetJson.Context.USER_AGENT, userAgent); - } - - contextJson.put(TargetJson.Context.TIME_OFFSET, TargetUtils.getUTCTimeOffsetMinutes()); - - return contextJson; - } - - private JSONObject getScreenContextObject() throws JSONException { - final JSONObject screenJson = new JSONObject(); - - DeviceInforming.DisplayInformation displayInformation = deviceInfoService.getDisplayInformation(); - - if (displayInformation != null) { - screenJson.put(TargetJson.Context.SCREEN_WIDTH, displayInformation.getWidthPixels()); - screenJson.put(TargetJson.Context.SCREEN_HEIGHT, displayInformation.getHeightPixels()); - } - - screenJson.put(TargetJson.Context.SCREEN_COLOR_DEPTH, TargetJson.Context.COLOR_DEPTH_32); - - int orientation = deviceInfoService.getCurrentOrientation(); - - if (orientation != 0) { - screenJson.put(TargetJson.Context.SCREEN_ORIENTATION, orientation == 1 - ? TargetJson.Context.ORIENTATION_PORTRAIT : TargetJson.Context.ORIENTATION_LANDSCAPE); - } - - return screenJson; - } - - private JSONObject getAppContextObject() throws JSONException { - final JSONObject appJson = new JSONObject(); - - final String appId = deviceInfoService.getApplicationPackageName(); - - if (appId != null) { - appJson.put(TargetJson.Context.APP_ID, appId); - } - - final String appName = deviceInfoService.getApplicationName(); - - if (appName != null) { - appJson.put(TargetJson.Context.APP_NAME, appName); - } - - final String appVersion = deviceInfoService.getApplicationVersion(); - - if (appVersion != null) { - appJson.put(TargetJson.Context.APP_VERSION, appVersion); - } - - return appJson; - } - - private JSONObject getPlatformContextObject() throws JSONException { - final JSONObject platformJson = new JSONObject(); - - platformJson.put(TargetJson.Context.PLATFORM_TYPE, deviceInfoService.getCanonicalPlatformName()); - - final String deviceManufacturer = deviceInfoService.getDeviceManufacturer(); - final String deviceName = deviceInfoService.getDeviceName(); - - if (deviceName != null) { - platformJson.put(TargetJson.Context.DEVICE_NAME, - (deviceManufacturer != null ? deviceManufacturer + " " : "") + deviceName); - } - - final DeviceInforming.DeviceType deviceType = deviceInfoService.getDeviceType(); - - if (deviceType != null && deviceType != DeviceInforming.DeviceType.UNKNOWN) { - platformJson.put(TargetJson.Context.DEVICE_TYPE, deviceType.name().toLowerCase()); - } - - return platformJson; - } - - private JSONObject getExperienceCloudObject(final String visitorBlob, final String visitorLocationHint) throws JSONException { - final JSONObject analyticsJson = new JSONObject(); - analyticsJson.put(TargetJson.ANALYTICS_LOGGING, TargetJson.ANALYTICS_CLIENT_SIDE); - - final JSONObject experienceCloudJson = new JSONObject(); - experienceCloudJson.put(TargetJson.ANALYTICS_PARAMETERS, analyticsJson); - - final JSONObject audienceManagerJson = new JSONObject(); - // collect blob and location hint from visitor id service - if (!StringUtils.isNullOrEmpty(visitorBlob)) { - audienceManagerJson.put(TargetJson.AAMParameters.BLOB, visitorBlob); - } - - if (!StringUtils.isNullOrEmpty(visitorLocationHint)) { - audienceManagerJson.put(TargetJson.AAMParameters.LOCATION_HINT, visitorLocationHint); - } - - if (audienceManagerJson.length() > 0) { - experienceCloudJson.put(TargetJson.AAM_PARAMETERS, audienceManagerJson); - } - - return experienceCloudJson; - } - - /** - * Creates a {@code JSONArray} from the customer visitor ids. - * - * @param customerIDs the {@code List} of customer visitor id - * @return the {@code JSONArray} generated - */ - private JSONArray getCustomerIDs(final List> customerIDs) { - final JSONArray customerIDsArrayNode = new JSONArray(); - - try { - for (Map visitorID : customerIDs) { - final JSONObject newVisitorIDNode = new JSONObject(); - - // Add CustomerId's Id - final String id = DataReader.optString(visitorID, TargetConstants.Identity.VISITOR_IDS_KEY_ID, null); - if (StringUtils.isNullOrEmpty(id)) { - continue; // id is a mandatory field, ignore populating this customerId if not available - } - newVisitorIDNode.put(TargetJson.CustomerIds.ID, id); - - // Add CustomerId's IntegrationCode - final String type = DataReader.optString(visitorID, TargetConstants.Identity.VISITOR_IDS_ID_KEY_TYPE, null); - if (StringUtils.isNullOrEmpty(type)) { - continue; // integrationCode is a mandatory field, ignoring customerId if not available - } - newVisitorIDNode.put(TargetJson.CustomerIds.INTEGRATION_CODE, type); - - // Add CustomerId's AuthenticationState - final int authenticationStateInt = DataReader.optInt(visitorID, TargetConstants.Identity.VISITOR_IDS_KEY_AUTHENTICATION_STATE, -1); - newVisitorIDNode.put(TargetJson.CustomerIds.AUTHENTICATION_STATE, getAuthenticationStateToString(VisitorID.AuthenticationState.fromInteger(authenticationStateInt))); - customerIDsArrayNode.put(newVisitorIDNode); - } - } catch (final JSONException exception) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, "Failed to create json node for customer visitor ids (%s)", exception); - } - - return customerIDsArrayNode; - } - - /** - * Returns the authentication state string value for a given {@code AuthenticationState}. - * - * @param value The {@link VisitorID.AuthenticationState} value to be translated into string - * @return The corresponding string value. - */ - private String getAuthenticationStateToString(final VisitorID.AuthenticationState value) { - switch (value) { - case AUTHENTICATED: - return "authenticated"; - - case LOGGED_OUT: - return "logged_out"; - - default: - return "unknown"; - } - } - - /** - * Creates a {@code JSONArray} containing all the prefetch mboxes, the mboxes will be have an auto-incremental index. - * - * @param prefetchList the {@code List} of prefetch - * @param globalParameters global {@link TargetParameters} to be merged with per-mbox parameters - * @param lifecycleData {@code Map} shared state of lifecycle extension - * @return the {@code JSONArray} generated from the input {@code prefetchList} - */ - private JSONArray getPrefetchMboxes(final List prefetchList, - final TargetParameters globalParameters, - final Map lifecycleData) { - if (prefetchList == null) { - return null; - } - - final JSONArray prefetchMboxesArrayNode = new JSONArray(); - int index = 0; - - for (final TargetPrefetch currentMbox : prefetchList) { - try { - prefetchMboxesArrayNode.put(createMboxJsonObject(currentMbox.getMboxName(), - currentMbox.getTargetParameters(), index, globalParameters, lifecycleData)); - index++; - } catch (final JSONException exception) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "getPrefetchMboxes - Failed to create json node for mbox %s (%s)", - currentMbox.getMboxName(), exception); - } - } - - return prefetchMboxesArrayNode; - } - - /** - * Creates a {@code JSONObject} with the provided target request. This json will contain the mbox name, mbox index, - * order parameters, product parameters, mbox parameters if they are present. This node will be added in - * the mboxes array in target network requests. - * - * @param mboxName {@link String} mbox name - * @param targetParameters {@link TargetParameters} per-mbox target parameters - * @param index the index - * @param globalParameters global {@link TargetParameters} to be merged with per-mbox parameters - * @param lifecycleData {@code Map} shared state of lifecycle extension - * @return {@link JSONObject} contains all the information provided for the mbox - * @throws JSONException json exception when it fails to add node to the json object - */ - private JSONObject createMboxJsonObject(final String mboxName, - final TargetParameters targetParameters, - final int index, - final TargetParameters globalParameters, - final Map lifecycleData) throws JSONException { - final JSONObject mboxNode = new JSONObject(); - - mboxNode.put(TargetJson.Mbox.INDEX, index); - - mboxNode.put(TargetJson.Mbox.NAME, mboxName); - - final List targetParametersList = Arrays.asList(targetParameters, globalParameters); - final TargetParameters parameters = TargetParameters.merge(targetParametersList); - - setTargetParametersJson(mboxNode, parameters, lifecycleData); - - return mboxNode; - } - - private void setTargetParametersJson(final JSONObject jsonNode, - final TargetParameters parameters, - final Map lifecycleData) throws JSONException { - if (parameters == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "setTargetParametersJson - Unable to set the target parameters, TargetParamters are null"); - return; - } - - // set mbox parameters - final JSONObject mboxParametersNode = getMboxParameters(parameters.getParameters(), lifecycleData); - - if (mboxParametersNode.length() > 0) { - jsonNode.put(TargetJson.PARAMETERS, mboxParametersNode); - } - - // set profile parameters - final JSONObject profileParamJson = new JSONObject(parameters.getProfileParameters()); - - if (profileParamJson.length() > 0) { - jsonNode.put(TargetJson.PROFILE_PARAMETERS, profileParamJson); - } - - // set order details - final JSONObject orderNode = getOrderParameters(parameters.getOrder()); - - if (orderNode != null && orderNode.length() > 0) { - jsonNode.put(TargetJson.ORDER, orderNode); - } - - // set product details - final JSONObject productNode = getProductParameters(parameters.getProduct()); - - if (productNode != null && productNode.length() > 0) { - jsonNode.put(TargetJson.PRODUCT, productNode); - } - } - - /** - * Creates the mbox parameters {@code JSONObject} with the provided data. - * - * @param mboxParameters the mbox parameters provided by the user - * @param lifecycleData {@code Map} shared state of lifecycle extension - * @return {@link JSONObject} contains mbox data - */ - private JSONObject getMboxParameters(final Map mboxParameters, - final Map lifecycleData) { - final HashMap mboxParametersCopy = new HashMap<>(mboxParameters); - - // Remove at_property from mbox parameters which is no longer supported in v1 delivery API - if (mboxParametersCopy.containsKey(TargetConstants.MBOX_AT_PROPERTY_KEY)) { - mboxParametersCopy.remove(TargetConstants.MBOX_AT_PROPERTY_KEY); - } - - final JSONObject mboxParametersJson = new JSONObject(mboxParametersCopy); - - try { - if (lifecycleData != null && !lifecycleData.isEmpty()) { - for (Map.Entry param : lifecycleData.entrySet()) { - mboxParametersJson.put(param.getKey(), param.getValue()); - } - } - - } catch (final JSONException exception) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "getMboxParameters - Failed to append internal parameters to the target request json (%s)", - exception); - } - - return mboxParametersJson; - } - - /** - * Creates the order parameters {@code JSONObject} with the provided data. - * - * @param order the {@link TargetOrder} parameters provided by the user - * @return {@link JSONObject} contains order data - */ - private JSONObject getOrderParameters(final TargetOrder order) { - if (order == null || StringUtils.isNullOrEmpty(order.getId())) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "getOrderParameters - Unable to get the order parameters, TargetOrder is null"); - return null; - } - - final JSONObject orderJson = new JSONObject(); - - try { - orderJson.put(TargetJson.Order.ID, order.getId()); - - if (order.getTotal() != 0) { - orderJson.put(TargetJson.Order.TOTAL, order.getTotal()); - } - - List productIds = order.getPurchasedProductIds(); - - if (productIds != null && !productIds.isEmpty()) { - JSONArray productIdsJson = new JSONArray("[]"); - - for (String productId : productIds) { - productIdsJson.put(productId); - } - - orderJson.put(TargetJson.Order.PURCHASED_PRODUCT_IDS, productIdsJson); - } - - return orderJson; - } catch (final JSONException ex) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, "getOrderParameters - Failed to create target order parameters (%s)", ex); - } - - return null; - } - - /** - * Creates the product parameters {@code JSONObject} with the provided data. - * - * @param product {@link TargetProduct} provided by the user - * @return {@link JSONObject} contains product data - */ - private JSONObject getProductParameters(final TargetProduct product) { - if (product == null || StringUtils.isNullOrEmpty(product.getId())) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "getProductParameters - Unable to get the product parameters, TargetProduct is null"); - return null; - } - - final JSONObject productNode = new JSONObject(); - - try { - productNode.put(TargetJson.Product.ID, product.getId()); - if (!StringUtils.isNullOrEmpty(product.getCategoryId())) { - productNode.put(TargetJson.Product.CATEGORY_ID, product.getCategoryId()); - } - } catch (final JSONException exception) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "getProductParameters - Failed to append product parameters to the target request json (%s)", - exception); - return null; - } - - return productNode; - } - - /** - * Returns target preview parameters need to be appended to the current target {@code JSONObject}. - * - * @return target preview parameters in {@link JSONObject} format - */ - private JSONObject getPreviewParameters() { - if (targetPreviewManager.getPreviewToken() != null && targetPreviewManager.getPreviewParameters() != null) { - try { - return new JSONObject(targetPreviewManager.getPreviewParameters()); - } catch (final JSONException e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, - "getPreviewParameters - Could not compile the target preview params with the Target request (%s)", e.getMessage()); - } - } - - return null; - } + private static final String CLASS_NAME = "TargetRequestBuilder"; + private final DeviceInforming deviceInfoService; + private final TargetPreviewManager targetPreviewManager; + private final TargetState targetState; + + /** + * Constructor for TargetRequestBuilder. + * + * @param deviceInfoService {@link DeviceInforming} instance + * @param targetPreviewManager {@link TargetPreviewManager} instance + */ + TargetRequestBuilder( + final DeviceInforming deviceInfoService, + final TargetPreviewManager targetPreviewManager, + final TargetState targetState) { + this.deviceInfoService = deviceInfoService; + this.targetPreviewManager = targetPreviewManager; + this.targetState = targetState; + } + + /** + * Creates the target request {@code JSONObject} that we have to send to target APIs. + * + * @param prefetchArray the list of {@link TargetPrefetch} objects with mboxes that we want to + * prefetch + * @param executeArray the list of {@link TargetRequest} objects with mboxes that we want to + * execute + * @param parameters {@link TargetParameters} object provided by the customer + * @param notifications viewed mboxes that we cached + * @param propertyToken a {@link String} to be passed for all requests + * @param identitySharedState {@code Map prefetchArray, + final List executeArray, + final TargetParameters parameters, + final List notifications, + final String propertyToken, + final Map identitySharedState, + final Map lifecycleData) { + try { + // add default parameters + final JSONObject defaultParamJson = + getDefaultJsonObject( + null, null, null, targetState.getEnvironmentId(), identitySharedState); + + // add prefetch mBoxes + final JSONArray prefetchMboxesNode = + getPrefetchMboxes(prefetchArray, parameters, lifecycleData); + + if (prefetchMboxesNode != null && prefetchMboxesNode.length() > 0) { + final JSONObject prefetchJson = new JSONObject(); + prefetchJson.put(TargetJson.MBOXES, prefetchMboxesNode); + defaultParamJson.put(TargetJson.PREFETCH, prefetchJson); + } + + // add notification mBoxes + if (notifications != null && !notifications.isEmpty()) { + defaultParamJson.put(TargetJson.NOTIFICATIONS, new JSONArray(notifications)); + } + + // add execute mBoxes + final JSONArray executeMboxesNode = + getExecuteMboxes(executeArray, parameters, lifecycleData); + + if (executeMboxesNode != null && executeMboxesNode.length() > 0) { + final JSONObject executeJson = new JSONObject(); + executeJson.put(TargetJson.MBOXES, executeMboxesNode); + defaultParamJson.put(TargetJson.EXECUTE, executeJson); + } + + // Add property token + if (!StringUtils.isNullOrEmpty(propertyToken)) { + final JSONObject tokenJson = new JSONObject(); + tokenJson.put(TargetJson.TOKEN, propertyToken); + defaultParamJson.put(TargetJson.PROPERTY, tokenJson); + } + + // add preview parameters + final JSONObject previewParameters = getPreviewParameters(); + + if (previewParameters != null) { + final Iterator keys = previewParameters.keys(); + + while (keys.hasNext()) { + final String key = keys.next(); + defaultParamJson.put(key, previewParameters.get(key)); + } + } + + return defaultParamJson; + } catch (final JSONException e) { + Log.warning( + TargetConstants.LOG_TAG, CLASS_NAME, TargetErrors.REQUEST_GENERATION_FAILED, e); + return null; + } + } + + /** + * Creates the {@code JSONObject} needed for the Target API requests. + * + * @param defaultJsonObject {@code JSONObject} containing the base request data attached to all + * Target requests. + * @param prefetch the {@code Map} containing the request prefetch data. + * @param execute the {@code Map} containing the request execute data. + * @param notifications {@code List>} containing the display or click + * notification data. + * @param propertyToken a {@link String} containing the configured Target {@code at_property}. + * @return the pre-built {@link JSONObject} for Target request. + */ + JSONObject getRequestPayload( + final JSONObject defaultJsonObject, + final Map prefetch, + final Map execute, + final List> notifications, + final String propertyToken) { + try { + // add default parameters + final JSONObject defaultParamJson = + defaultJsonObject == null ? new JSONObject() : defaultJsonObject; + + // add prefetch node + if (prefetch != null && !prefetch.isEmpty()) { + final JSONObject prefetchNode = new JSONObject(prefetch); + defaultParamJson.put(TargetJson.PREFETCH, prefetchNode); + } + + // add execute node + if (execute != null && !execute.isEmpty()) { + final JSONObject executeNode = new JSONObject(execute); + defaultParamJson.put(TargetJson.EXECUTE, executeNode); + } + + // add notifications node + if (notifications != null && !notifications.isEmpty()) { + final JSONArray notificationArrayNode = new JSONArray(); + for (Map notification : notifications) { + final JSONObject notificationNode = new JSONObject(notification); + notificationArrayNode.put(notificationNode); + } + defaultParamJson.put(TargetJson.NOTIFICATIONS, notificationArrayNode); + } + + // Add property token + if (!StringUtils.isNullOrEmpty(propertyToken)) { + final JSONObject tokenJson = new JSONObject(); + tokenJson.put(TargetJson.TOKEN, propertyToken); + defaultParamJson.put(TargetJson.PROPERTY, tokenJson); + } + + // add preview parameters + final JSONObject previewParameters = getPreviewParameters(); + if (previewParameters != null) { + final Iterator keys = previewParameters.keys(); + while (keys.hasNext()) { + final String key = keys.next(); + defaultParamJson.put(key, previewParameters.get(key)); + } + } + + return defaultParamJson; + } catch (final JSONException e) { + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "getRequestPayload - (%s) (%s)", + TargetErrors.REQUEST_GENERATION_FAILED, + e); + return null; + } + } + + /** + * Creates the display notification payload + * + * @param mboxName mbox name + * @param cachedMboxJson the cached mbox + * @param parameters {@link TargetParameters} object associated with the notification + * @param timestamp {@code long} timestamp associated with the event + * @param lifecycleData {@code Map} shared state of lifecycle extension + * @return the {@link JSONObject} payload for notification + */ + JSONObject getDisplayNotificationJsonObject( + final String mboxName, + final JSONObject cachedMboxJson, + final TargetParameters parameters, + final long timestamp, + final Map lifecycleData) { + try { + final JSONObject notificationNode = new JSONObject(); + notificationNode.put(TargetJson.Notification.ID, UUID.randomUUID().toString()); + notificationNode.put(TargetJson.Notification.TIMESTAMP, timestamp); + notificationNode.put(TargetJson.Metric.TYPE, TargetJson.MetricType.DISPLAY); + setTargetParametersJson(notificationNode, parameters, lifecycleData); + + final JSONObject mboxNode = new JSONObject(); + mboxNode.put(TargetJson.Mbox.NAME, mboxName); + + if (cachedMboxJson == null) { + return null; + } + + final String mboxState = cachedMboxJson.optString(TargetJson.Mbox.STATE, ""); + + if (!mboxState.isEmpty()) { + mboxNode.put(TargetJson.Mbox.STATE, mboxState); + } + + notificationNode.put(TargetJson.Notification.MBOX, mboxNode); + + // Gather display event tokens + final JSONArray optionsArray = cachedMboxJson.optJSONArray(TargetJson.OPTIONS); + + if (optionsArray != null) { + + final JSONArray tokens = new JSONArray(); + + for (int i = 0; i < optionsArray.length(); i++) { + final JSONObject option = optionsArray.optJSONObject(i); + + if (option == null + || StringUtils.isNullOrEmpty( + option.optString(TargetJson.Metric.EVENT_TOKEN, ""))) { + continue; + } + + final String optionEventToken = + option.optString(TargetJson.Metric.EVENT_TOKEN, ""); + tokens.put(optionEventToken); + } + + if (tokens.length() == 0) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + TargetErrors.DISPLAY_NOTIFICATION_TOKEN_EMPTY); + return null; + } + + notificationNode.put(TargetJson.Notification.TOKENS, tokens); + } + + return notificationNode; + } catch (final JSONException exception) { + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + TargetErrors.DISPLAY_NOTIFICATION_CREATE_FAILED, + exception); + } + + return null; + } + + /** + * Creates the clicked mbox json object based on the cached mbox json node. It will contain the + * following params: mbox, parameters, order, product, clickToken , hit and timestamp. mbox + * order and product parameters of them might be missing if they are not provided from the + * public API. + * + * @param cachedMboxJson an {@link JSONObject} mbox node cached after prefetch/load request + * @param parameters {@link TargetParameters} corresponding to the clicked location + * @param timestamp {@code long} timestamp associated with the event + * @param lifecycleData {@code Map} shared state of lifecycle extension + * @return mbox node for the click notification + */ + JSONObject getClickNotificationJsonObject( + final JSONObject cachedMboxJson, + final TargetParameters parameters, + final long timestamp, + final Map lifecycleData) { + try { + final JSONObject notificationNode = new JSONObject(); + notificationNode.put(TargetJson.Notification.ID, UUID.randomUUID().toString()); + notificationNode.put(TargetJson.Notification.TIMESTAMP, timestamp); + notificationNode.put(TargetJson.Metric.TYPE, TargetJson.MetricType.CLICK); + setTargetParametersJson(notificationNode, parameters, lifecycleData); + + if (cachedMboxJson == null) { + return notificationNode; + } + + final String mboxName = cachedMboxJson.getString(TargetJson.Mbox.NAME); + + final JSONObject mboxNode = new JSONObject(); + mboxNode.put(TargetJson.Mbox.NAME, mboxName); + + notificationNode.put(TargetJson.Notification.MBOX, mboxNode); + + final JSONArray metrics = cachedMboxJson.getJSONArray(TargetJson.METRICS); + + final JSONArray tokens = new JSONArray(); + + for (int i = 0; i < metrics.length(); i++) { + final JSONObject metric = metrics.optJSONObject(i); + + if (metric == null + || !TargetJson.MetricType.CLICK.equals( + metric.optString(TargetJson.Metric.TYPE, "")) + || metric.optString(TargetJson.Metric.EVENT_TOKEN, "").isEmpty()) { + continue; + } + + final String metricToken = metric.optString(TargetJson.Metric.EVENT_TOKEN, ""); + tokens.put(metricToken); + } + + if (tokens.length() == 0) { + throw new JSONException(TargetErrors.TOKEN_LIST_EMPTY_OR_NULL); + } + + notificationNode.put(TargetJson.Notification.TOKENS, tokens); + + return notificationNode; + } catch (final JSONException exception) { + Log.warning( + TargetConstants.LOG_TAG, + TargetErrors.CLICK_NOTIFICATION_CREATE_FAILED, + cachedMboxJson.toString()); + } + + return null; + } + + /** + * Gets the default {@code JSONObject} attached to every Target API request. + * + * @param id {@code Map} containing the identifiers for the visitor. + * @param context {@code Map} specifying the context for the request. + * @param experienceCloud {@code Map} containing the Analytics and Audience + * Manager integration info. + * @param environmentId {@code long} containing the Target environmentId. + * @param identityData {@code Map} shared state of Identity extension + * @return {@code JSONObject} containing the default Target request payload. + */ + JSONObject getDefaultJsonObject( + final Map id, + final Map context, + final Map experienceCloud, + final long environmentId, + final Map identityData) { + try { + final JSONObject defaultParamJson = new JSONObject(); + + // add id Node + final JSONObject idNode; + + if (id != null && !id.isEmpty()) { + idNode = new JSONObject(id); + } else { + idNode = new JSONObject(); + + if (!StringUtils.isNullOrEmpty(targetState.getTntId())) { + idNode.put(TargetJson.ID_TNT_ID, targetState.getTntId()); + } + + if (!StringUtils.isNullOrEmpty(targetState.getThirdPartyId())) { + idNode.put(TargetJson.ID_THIRD_PARTY_ID, targetState.getThirdPartyId()); + } + + final String visitorMarketingCloudId = + DataReader.optString( + identityData, TargetConstants.Identity.VISITOR_ID_MID, ""); + if (!StringUtils.isNullOrEmpty(visitorMarketingCloudId)) { + idNode.put(TargetJson.ID_MARKETING_CLOUD_VISITOR_ID, visitorMarketingCloudId); + } + + final List> visitorCustomerIds = + DataReader.optTypedListOfMap( + Object.class, + identityData, + TargetConstants.Identity.VISITOR_IDS_LIST, + null); + if (visitorCustomerIds != null && !visitorCustomerIds.isEmpty()) { + idNode.put(TargetJson.ID_CUSTOMER_IDS, getCustomerIDs(visitorCustomerIds)); + } + } + + if (idNode.length() > 0) { + defaultParamJson.put(TargetJson.ID, idNode); + } + + // add context Node + final JSONObject contextNode; + + if (context != null && !context.isEmpty()) { + contextNode = new JSONObject(context); + } else { + contextNode = getContextObject(); + } + + defaultParamJson.put(TargetJson.CONTEXT_PARAMETERS, contextNode); + + // add experienceCloud Node + final JSONObject experienceCloudNode; + + if (experienceCloud != null && !experienceCloud.isEmpty()) { + experienceCloudNode = new JSONObject(experienceCloud); + } else { + final String visitorBlob = + DataReader.optString( + identityData, TargetConstants.Identity.VISITOR_ID_BLOB, ""); + final String visitorLocationHint = + DataReader.optString( + identityData, + TargetConstants.Identity.VISITOR_ID_LOCATION_HINT, + ""); + experienceCloudNode = getExperienceCloudObject(visitorBlob, visitorLocationHint); + } + + defaultParamJson.put(TargetJson.EXPERIENCE_CLOUD, experienceCloudNode); + + // add environmentId + if (environmentId != 0L) { + defaultParamJson.put(TargetJson.ENVIRONMENT_ID, environmentId); + } + + return defaultParamJson; + + } catch (final JSONException e) { + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Failed to create base JSON object for Target request (%s)", + e); + return null; + } + } + + /** + * Creates a {@code JSONArray} containing all the batch mboxes, the mboxes will have an + * auto-incremental index. + * + * @param targetRequestList the {@code List} of batch request + * @param globalParameters global {@link TargetParameters} to be merged with per-mbox parameters + * @param lifecycleData {@code Map} shared state of lifecycle extension + * @return the {@code JSONArray} generated from the input {@code targetRequestList} + */ + private JSONArray getExecuteMboxes( + final List targetRequestList, + final TargetParameters globalParameters, + final Map lifecycleData) { + if (targetRequestList == null) { + return null; + } + + final JSONArray mBoxArrayNode = new JSONArray(); + int index = 0; + + for (TargetRequest currentMbox : targetRequestList) { + try { + mBoxArrayNode.put( + createMboxJsonObject( + currentMbox.getMboxName(), + currentMbox.getTargetParameters(), + index, + globalParameters, + lifecycleData)); + index++; + } catch (final JSONException exception) { + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "getExecuteMboxes -Failed to create Json Node for mbox %s (%s)", + currentMbox.getMboxName(), + exception); + } + } + + return mBoxArrayNode; + } + + private JSONObject getContextObject() throws JSONException { + final JSONObject contextJson = new JSONObject(); + contextJson.put(TargetJson.Context.CHANNEL, TargetJson.Context.CHANNEL_MOBILE); + contextJson.put(TargetJson.Context.MOBILE_PLATFORM, getPlatformContextObject()); + contextJson.put(TargetJson.Context.APPLICATION, getAppContextObject()); + contextJson.put(TargetJson.Context.SCREEN, getScreenContextObject()); + + final String userAgent = deviceInfoService.getDefaultUserAgent(); + + if (!StringUtils.isNullOrEmpty(userAgent)) { + contextJson.put(TargetJson.Context.USER_AGENT, userAgent); + } + + contextJson.put(TargetJson.Context.TIME_OFFSET, TargetUtils.getUTCTimeOffsetMinutes()); + + return contextJson; + } + + private JSONObject getScreenContextObject() throws JSONException { + final JSONObject screenJson = new JSONObject(); + + DeviceInforming.DisplayInformation displayInformation = + deviceInfoService.getDisplayInformation(); + + if (displayInformation != null) { + screenJson.put(TargetJson.Context.SCREEN_WIDTH, displayInformation.getWidthPixels()); + screenJson.put(TargetJson.Context.SCREEN_HEIGHT, displayInformation.getHeightPixels()); + } + + screenJson.put(TargetJson.Context.SCREEN_COLOR_DEPTH, TargetJson.Context.COLOR_DEPTH_32); + + int orientation = deviceInfoService.getCurrentOrientation(); + + if (orientation != 0) { + screenJson.put( + TargetJson.Context.SCREEN_ORIENTATION, + orientation == 1 + ? TargetJson.Context.ORIENTATION_PORTRAIT + : TargetJson.Context.ORIENTATION_LANDSCAPE); + } + + return screenJson; + } + + private JSONObject getAppContextObject() throws JSONException { + final JSONObject appJson = new JSONObject(); + + final String appId = deviceInfoService.getApplicationPackageName(); + + if (appId != null) { + appJson.put(TargetJson.Context.APP_ID, appId); + } + + final String appName = deviceInfoService.getApplicationName(); + + if (appName != null) { + appJson.put(TargetJson.Context.APP_NAME, appName); + } + + final String appVersion = deviceInfoService.getApplicationVersion(); + + if (appVersion != null) { + appJson.put(TargetJson.Context.APP_VERSION, appVersion); + } + + return appJson; + } + + private JSONObject getPlatformContextObject() throws JSONException { + final JSONObject platformJson = new JSONObject(); + + platformJson.put( + TargetJson.Context.PLATFORM_TYPE, deviceInfoService.getCanonicalPlatformName()); + + final String deviceManufacturer = deviceInfoService.getDeviceManufacturer(); + final String deviceName = deviceInfoService.getDeviceName(); + + if (deviceName != null) { + platformJson.put( + TargetJson.Context.DEVICE_NAME, + (deviceManufacturer != null ? deviceManufacturer + " " : "") + deviceName); + } + + final DeviceInforming.DeviceType deviceType = deviceInfoService.getDeviceType(); + + if (deviceType != null && deviceType != DeviceInforming.DeviceType.UNKNOWN) { + platformJson.put(TargetJson.Context.DEVICE_TYPE, deviceType.name().toLowerCase()); + } + + return platformJson; + } + + private JSONObject getExperienceCloudObject( + final String visitorBlob, final String visitorLocationHint) throws JSONException { + final JSONObject analyticsJson = new JSONObject(); + analyticsJson.put(TargetJson.ANALYTICS_LOGGING, TargetJson.ANALYTICS_CLIENT_SIDE); + + final JSONObject experienceCloudJson = new JSONObject(); + experienceCloudJson.put(TargetJson.ANALYTICS_PARAMETERS, analyticsJson); + + final JSONObject audienceManagerJson = new JSONObject(); + // collect blob and location hint from visitor id service + if (!StringUtils.isNullOrEmpty(visitorBlob)) { + audienceManagerJson.put(TargetJson.AAMParameters.BLOB, visitorBlob); + } + + if (!StringUtils.isNullOrEmpty(visitorLocationHint)) { + audienceManagerJson.put(TargetJson.AAMParameters.LOCATION_HINT, visitorLocationHint); + } + + if (audienceManagerJson.length() > 0) { + experienceCloudJson.put(TargetJson.AAM_PARAMETERS, audienceManagerJson); + } + + return experienceCloudJson; + } + + /** + * Creates a {@code JSONArray} from the customer visitor ids. + * + * @param customerIDs the {@code List} of customer visitor id + * @return the {@code JSONArray} generated + */ + private JSONArray getCustomerIDs(final List> customerIDs) { + final JSONArray customerIDsArrayNode = new JSONArray(); + + try { + for (Map visitorID : customerIDs) { + final JSONObject newVisitorIDNode = new JSONObject(); + + // Add CustomerId's Id + final String id = + DataReader.optString( + visitorID, TargetConstants.Identity.VISITOR_IDS_KEY_ID, null); + if (StringUtils.isNullOrEmpty(id)) { + continue; // id is a mandatory field, ignore populating this customerId if not + // available + } + newVisitorIDNode.put(TargetJson.CustomerIds.ID, id); + + // Add CustomerId's IntegrationCode + final String type = + DataReader.optString( + visitorID, TargetConstants.Identity.VISITOR_IDS_ID_KEY_TYPE, null); + if (StringUtils.isNullOrEmpty(type)) { + continue; // integrationCode is a mandatory field, ignoring customerId if not + // available + } + newVisitorIDNode.put(TargetJson.CustomerIds.INTEGRATION_CODE, type); + + // Add CustomerId's AuthenticationState + final int authenticationStateInt = + DataReader.optInt( + visitorID, + TargetConstants.Identity.VISITOR_IDS_KEY_AUTHENTICATION_STATE, + -1); + newVisitorIDNode.put( + TargetJson.CustomerIds.AUTHENTICATION_STATE, + getAuthenticationStateToString( + VisitorID.AuthenticationState.fromInteger(authenticationStateInt))); + customerIDsArrayNode.put(newVisitorIDNode); + } + } catch (final JSONException exception) { + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Failed to create json node for customer visitor ids (%s)", + exception); + } + + return customerIDsArrayNode; + } + + /** + * Returns the authentication state string value for a given {@code AuthenticationState}. + * + * @param value The {@link VisitorID.AuthenticationState} value to be translated into string + * @return The corresponding string value. + */ + private String getAuthenticationStateToString(final VisitorID.AuthenticationState value) { + switch (value) { + case AUTHENTICATED: + return "authenticated"; + + case LOGGED_OUT: + return "logged_out"; + + default: + return "unknown"; + } + } + + /** + * Creates a {@code JSONArray} containing all the prefetch mboxes, the mboxes will be have an + * auto-incremental index. + * + * @param prefetchList the {@code List} of prefetch + * @param globalParameters global {@link TargetParameters} to be merged with per-mbox parameters + * @param lifecycleData {@code Map} shared state of lifecycle extension + * @return the {@code JSONArray} generated from the input {@code prefetchList} + */ + private JSONArray getPrefetchMboxes( + final List prefetchList, + final TargetParameters globalParameters, + final Map lifecycleData) { + if (prefetchList == null) { + return null; + } + + final JSONArray prefetchMboxesArrayNode = new JSONArray(); + int index = 0; + + for (final TargetPrefetch currentMbox : prefetchList) { + try { + prefetchMboxesArrayNode.put( + createMboxJsonObject( + currentMbox.getMboxName(), + currentMbox.getTargetParameters(), + index, + globalParameters, + lifecycleData)); + index++; + } catch (final JSONException exception) { + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "getPrefetchMboxes - Failed to create json node for mbox %s (%s)", + currentMbox.getMboxName(), + exception); + } + } + + return prefetchMboxesArrayNode; + } + + /** + * Creates a {@code JSONObject} with the provided target request. This json will contain the + * mbox name, mbox index, order parameters, product parameters, mbox parameters if they are + * present. This node will be added in the mboxes array in target network requests. + * + * @param mboxName {@link String} mbox name + * @param targetParameters {@link TargetParameters} per-mbox target parameters + * @param index the index + * @param globalParameters global {@link TargetParameters} to be merged with per-mbox parameters + * @param lifecycleData {@code Map} shared state of lifecycle extension + * @return {@link JSONObject} contains all the information provided for the mbox + * @throws JSONException json exception when it fails to add node to the json object + */ + private JSONObject createMboxJsonObject( + final String mboxName, + final TargetParameters targetParameters, + final int index, + final TargetParameters globalParameters, + final Map lifecycleData) + throws JSONException { + final JSONObject mboxNode = new JSONObject(); + + mboxNode.put(TargetJson.Mbox.INDEX, index); + + mboxNode.put(TargetJson.Mbox.NAME, mboxName); + + final List targetParametersList = + Arrays.asList(targetParameters, globalParameters); + final TargetParameters parameters = TargetParameters.merge(targetParametersList); + + setTargetParametersJson(mboxNode, parameters, lifecycleData); + + return mboxNode; + } + + private void setTargetParametersJson( + final JSONObject jsonNode, + final TargetParameters parameters, + final Map lifecycleData) + throws JSONException { + if (parameters == null) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "setTargetParametersJson - Unable to set the target parameters, TargetParamters" + + " are null"); + return; + } + + // set mbox parameters + final JSONObject mboxParametersNode = + getMboxParameters(parameters.getParameters(), lifecycleData); + + if (mboxParametersNode.length() > 0) { + jsonNode.put(TargetJson.PARAMETERS, mboxParametersNode); + } + + // set profile parameters + final JSONObject profileParamJson = new JSONObject(parameters.getProfileParameters()); + + if (profileParamJson.length() > 0) { + jsonNode.put(TargetJson.PROFILE_PARAMETERS, profileParamJson); + } + + // set order details + final JSONObject orderNode = getOrderParameters(parameters.getOrder()); + + if (orderNode != null && orderNode.length() > 0) { + jsonNode.put(TargetJson.ORDER, orderNode); + } + + // set product details + final JSONObject productNode = getProductParameters(parameters.getProduct()); + + if (productNode != null && productNode.length() > 0) { + jsonNode.put(TargetJson.PRODUCT, productNode); + } + } + + /** + * Creates the mbox parameters {@code JSONObject} with the provided data. + * + * @param mboxParameters the mbox parameters provided by the user + * @param lifecycleData {@code Map} shared state of lifecycle extension + * @return {@link JSONObject} contains mbox data + */ + private JSONObject getMboxParameters( + final Map mboxParameters, final Map lifecycleData) { + final HashMap mboxParametersCopy = new HashMap<>(mboxParameters); + + // Remove at_property from mbox parameters which is no longer supported in v1 delivery API + if (mboxParametersCopy.containsKey(TargetConstants.MBOX_AT_PROPERTY_KEY)) { + mboxParametersCopy.remove(TargetConstants.MBOX_AT_PROPERTY_KEY); + } + + final JSONObject mboxParametersJson = new JSONObject(mboxParametersCopy); + + try { + if (lifecycleData != null && !lifecycleData.isEmpty()) { + for (Map.Entry param : lifecycleData.entrySet()) { + mboxParametersJson.put(param.getKey(), param.getValue()); + } + } + + } catch (final JSONException exception) { + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "getMboxParameters - Failed to append internal parameters to the target request" + + " json (%s)", + exception); + } + + return mboxParametersJson; + } + + /** + * Creates the order parameters {@code JSONObject} with the provided data. + * + * @param order the {@link TargetOrder} parameters provided by the user + * @return {@link JSONObject} contains order data + */ + private JSONObject getOrderParameters(final TargetOrder order) { + if (order == null || StringUtils.isNullOrEmpty(order.getId())) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "getOrderParameters - Unable to get the order parameters, TargetOrder is null"); + return null; + } + + final JSONObject orderJson = new JSONObject(); + + try { + orderJson.put(TargetJson.Order.ID, order.getId()); + + if (order.getTotal() != 0) { + orderJson.put(TargetJson.Order.TOTAL, order.getTotal()); + } + + List productIds = order.getPurchasedProductIds(); + + if (productIds != null && !productIds.isEmpty()) { + JSONArray productIdsJson = new JSONArray("[]"); + + for (String productId : productIds) { + productIdsJson.put(productId); + } + + orderJson.put(TargetJson.Order.PURCHASED_PRODUCT_IDS, productIdsJson); + } + + return orderJson; + } catch (final JSONException ex) { + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "getOrderParameters - Failed to create target order parameters (%s)", + ex); + } + + return null; + } + + /** + * Creates the product parameters {@code JSONObject} with the provided data. + * + * @param product {@link TargetProduct} provided by the user + * @return {@link JSONObject} contains product data + */ + private JSONObject getProductParameters(final TargetProduct product) { + if (product == null || StringUtils.isNullOrEmpty(product.getId())) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "getProductParameters - Unable to get the product parameters, TargetProduct is" + + " null"); + return null; + } + + final JSONObject productNode = new JSONObject(); + + try { + productNode.put(TargetJson.Product.ID, product.getId()); + if (!StringUtils.isNullOrEmpty(product.getCategoryId())) { + productNode.put(TargetJson.Product.CATEGORY_ID, product.getCategoryId()); + } + } catch (final JSONException exception) { + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "getProductParameters - Failed to append product parameters to the target" + + " request json (%s)", + exception); + return null; + } + + return productNode; + } + + /** + * Returns target preview parameters need to be appended to the current target {@code + * JSONObject}. + * + * @return target preview parameters in {@link JSONObject} format + */ + private JSONObject getPreviewParameters() { + if (targetPreviewManager.getPreviewToken() != null + && targetPreviewManager.getPreviewParameters() != null) { + try { + return new JSONObject(targetPreviewManager.getPreviewParameters()); + } catch (final JSONException e) { + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "getPreviewParameters - Could not compile the target preview params with" + + " the Target request (%s)", + e.getMessage()); + } + } + + return null; + } } - diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetResponseParser.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetResponseParser.java index c4d4acd..364491b 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetResponseParser.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetResponseParser.java @@ -7,440 +7,463 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ +*/ package com.adobe.marketing.mobile.target; -import com.adobe.marketing.mobile.services.HttpConnecting; import androidx.annotation.Nullable; - +import com.adobe.marketing.mobile.services.HttpConnecting; import com.adobe.marketing.mobile.services.Log; import com.adobe.marketing.mobile.util.JSONUtils; import com.adobe.marketing.mobile.util.StreamUtils; import com.adobe.marketing.mobile.util.StringUtils; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; class TargetResponseParser { - private static final String CLASS_NAME = "TargetResponseParser"; - - /** - * Parse the target server response to a json object if there is no error. - *

- * Do not pass a null connection object to this method. - * This method return null if - *

    - *
  1. There is any error occurred while reading the JSON response.
  2. - *
  3. If the response code for the connection is not 200 (HTTP_OK).
  4. - *
  5. If the response from the server is empty or not a valid JSON.
  6. - *
- * - * @param connection the network {@link com.adobe.marketing.mobile.services.HttpConnecting} object returned from server - * @return the {@link JSONObject} if the response is valid - */ - @Nullable - JSONObject parseResponseToJson(final HttpConnecting connection) { - try { - if (connection != null) { - final String responseString = StreamUtils.readAsString(connection.getInputStream()); - if (StringUtils.isNullOrEmpty(responseString)) { - return null; - } - final JSONObject responseJson = new JSONObject(responseString); - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "Target Response was received : %s", responseString); - return responseJson; - } - } catch (final JSONException e) { - Log.error(TargetConstants.LOG_TAG, CLASS_NAME,"Unable to parse Target Response, Error (%s)", e); - } - return null; - } - - /** - * Extracts the mboxes from the server response for a certain key. - *

- * Used by methods {@code #extractPrefetchedMboxes(JSONObject)} and {@code #extractBatchedMBoxes(JSONObject)}. - * Do not pass a null {@code JSONObject} serverResponseJson. - * - * @param serverResponseJson A {@link JSONObject} server response - * @param key A {@link String} key name for which mbox need should the mboxes be extracted from - * @return all the mboxes for the given key - */ - private JSONArray getMboxesFromKey(final JSONObject serverResponseJson, final String key) { - final JSONObject containerJson = serverResponseJson.optJSONObject(key); - - if (containerJson == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "getMboxesFromKey - Unable to retrieve mboxes from key, json is null"); - return null; - } - - final JSONArray mboxJSONArray = containerJson.optJSONArray(TargetJson.MBOXES); - - if (mboxJSONArray == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "getMboxesFromKey - Unable to retrieve mboxes from key, mboxes array is null"); - return null; - } - - return mboxJSONArray; - } - - /** - * Extracts the batched mboxes from the server response and returns them as a {@code Map}, where the mbox name is the key - * and the {@code JSONObject} returned from the server is the value. - *

- * Returns null if there is no {@link TargetJson#MBOX_RESPONSES} key found in the server response. - * Do not pass a null {@code JSONObject} serverResponseJson. - * - * @param serverResponseJson A {@link JSONObject} server response - * @return A {@link Map} of all the batched mboxes - */ - @Nullable - Map extractBatchedMBoxes(final JSONObject serverResponseJson) { - final JSONArray batchedMboxes = getMboxesFromKey(serverResponseJson, TargetJson.EXECUTE); - - if (batchedMboxes == null) { - return null; - } - - final Map mboxResponses = new HashMap<>(); - - for (int i = 0; i < batchedMboxes.length(); i++) { - final JSONObject mboxJson = batchedMboxes.optJSONObject(i); - - if (mboxJson == null) { - continue; - } - - final String mboxName = mboxJson.optString(TargetJson.Mbox.NAME, ""); - - if (StringUtils.isNullOrEmpty(mboxName)) { - continue; - } - - mboxResponses.put(mboxName, mboxJson); - } - - return mboxResponses; - } - - /** - * Extracts the prefetched mboxes from the server response and returns them as a {@code Map}, where the mbox name is the key - * and the {@code JSONObject} returned from the server is the value. - *

- * Returns null if there is no {@code TargetJson#PREFETCH_MBOX_RESPONSES} key found in the server response. - * Do not pass a null {@code JSONObject} serverResponseJson. - * - * @param serverResponseJson A {@link JSONObject} server response - * @return A {@link Map} of all the prefetched mboxes - */ - @Nullable - Map extractPrefetchedMboxes(final JSONObject serverResponseJson) { - final JSONArray prefetchedMboxes = getMboxesFromKey(serverResponseJson, TargetJson.PREFETCH); - - if (prefetchedMboxes == null) { - return null; - } - - final Map mboxResponses = new HashMap(); - - for (int i = 0; i < prefetchedMboxes.length(); i++) { - final JSONObject mboxJson = prefetchedMboxes.optJSONObject(i); - - if (mboxJson == null) { - continue; - } - - final String mboxName = mboxJson.optString(TargetJson.Mbox.NAME, ""); - - if (StringUtils.isNullOrEmpty(mboxName)) { - continue; - } - - final Iterator keyIterator = mboxJson.keys(); - final List keyCache = new ArrayList(); - - while (keyIterator.hasNext()) { - keyCache.add(keyIterator.next()); - } - - for (final String key : keyCache) { - if (!TargetJson.CACHED_MBOX_ACCEPTED_KEYS.contains(key)) { - mboxJson.remove(key); - } - } - - mboxResponses.put(mboxName, mboxJson); - } - - return mboxResponses; - } - - /** - * Get the tnt id from the {@code JSONObject} server response. - *

- * Returns null if there is no {@code TargetJson#ID} key found in the server response. - * Do not pass a null {@code JSONObject} serverResponseJson. - * - * @param serverResponseJson A {@link JSONObject} server response - * @return A {@link String} tntid - */ - @Nullable - String getTntId(final JSONObject serverResponseJson) { - final JSONObject idJson = serverResponseJson.optJSONObject(TargetJson.ID); - - if (idJson == null) { - return null; - } - - return idJson.optString(TargetJson.ID_TNT_ID, ""); - } - - /** - * Get the edge host from the {@code JSONObject} server response - *

- * Returns an empty {@code String} if there is no {@code TargetJson#EDGE_HOST} key found in the server response. - * Do not pass a null {@code JSONObject} serverResponseJson. - * - * @param serverResponseJson A {@link JSONObject} server response - * @return A {@link String} edge host - */ - String getEdgeHost(final JSONObject serverResponseJson) { - return serverResponseJson.optString(TargetJson.EDGE_HOST, ""); - } - - - /** - * Grabs the a4t payload from the target response and convert the keys to correct format - *

- * Returns null if there is no analytics payload that needs to be sent. - * - * @param mboxJson A prefetched mbox {@link JSONObject} - * @return A {@link Map} containing a4t payload - */ - @Nullable - Map getAnalyticsForTargetPayload(final JSONObject mboxJson, final String sessionId) { - final Map payload = getAnalyticsForTargetPayload(mboxJson); - return preprocessAnalyticsForTargetPayload(payload, sessionId); - } - - /** - * Converts the A4T params keys to correct format as required by the Analytics - *

- * Returns null if {@code payload} is null or empty - * - * @param payload {@code Map} with A4t params - * @param sessionId Target session id - * @return {@code Map} with processed keys - */ - @Nullable - Map preprocessAnalyticsForTargetPayload(final Map payload, final String sessionId) { - if (TargetUtils.isNullOrEmpty(payload)) { - return null; - } - - final Map modifiedPayload = new HashMap(); - - for (Map.Entry entry : payload.entrySet()) { - modifiedPayload.put("&&" + entry.getKey(), entry.getValue()); - } - - if (!StringUtils.isNullOrEmpty(sessionId)) { - modifiedPayload.put(TargetConstants.EventDataKeys.A4T_SESSION_ID, sessionId); - } - - return modifiedPayload; - } - - /** - * Parse the JSON object parameter to read A4T payload and returns it as a {@code Map}. - * Returns null if {@code json} doesn't have A4T payload. - * - * @param json {@link JSONObject} containing analytics payload - * @return {@code Map} containing A4T params - */ - @Nullable - Map getAnalyticsForTargetPayload(final JSONObject json) { - if (json == null) { - return null; - } - - final JSONObject analyticsJson = json.optJSONObject(TargetJson.ANALYTICS_PARAMETERS); - - if (analyticsJson == null) { - return null; - } - - final JSONObject payloadJson = analyticsJson.optJSONObject(TargetJson.ANALYTICS_PAYLOAD); - - if (payloadJson == null) { - return null; - } - - return TargetUtils.toStringMap(payloadJson); - } - - /** - * Parse the Mbox JSON object to read Response Tokens from the Options. The data will be read from the first option in the options list. - * - * @param mboxJson Mbox {@link JSONObject} - * @return Response tokens from options payload as {@code Map}, or null if response tokens are not activated on Target. - */ - Map getResponseTokens(final JSONObject mboxJson) { - if (mboxJson == null) { - return null; - } - - final JSONArray optionsArray = mboxJson.optJSONArray(TargetJson.OPTIONS); - - if (JSONUtils.isNullOrEmpty(optionsArray)) { - return null; - } - - // Mbox payload will have a single option object in options array, which is accessed using the index 0 and - // further used to grab response tokens. - final JSONObject option = optionsArray.optJSONObject(0); - - if (option == null) { - return null; - } - - final JSONObject responseTokens = option.optJSONObject(TargetJson.Option.RESPONSE_TOKENS); - - if (responseTokens == null) { - return null; - } - - Map responseTokensMap = null; - try { - responseTokensMap = JSONUtils.toMap(responseTokens); - } catch (final JSONException e) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "Exception (%s) is thrown when parsing response tokens to create an object Map.", e); - } - return responseTokensMap; - } - - /** - * Extracts the click metric A4T params from the {@code mboxJson} and return them as a {@code Map}. - *

- * Returns null if click metric analytics payload is missing in the mbox payload or there is any error in parsing {@code mboxJson}. - * - * @param mboxJson {@link JSONObject} of a mbox - * @return {@code Map} containing click metric A4T params - */ - Map extractClickMetricAnalyticsPayload(final JSONObject mboxJson) { - final JSONObject clickMetric = getClickMetric(mboxJson); - return getAnalyticsForTargetPayload(clickMetric); - } - - /** - * Grab the click metric {@link JSONObject} and returns it - *

- * This method returns null if the input {@code mboxJson} is null, - * or if the metrics array is not present in the {@code mboxJson}, - * or if a valid click metric object is not found in the metrics array, - * or if the eventToken is not found in the click metric object - * - * @param mboxJson {@code JSONObject} for mbox - * @return {@code JSONObject} for click metric - */ - JSONObject getClickMetric(final JSONObject mboxJson) { - if (mboxJson == null) { - return null; - } - - final JSONArray metricsArray = mboxJson.optJSONArray(TargetJson.METRICS); - - if (JSONUtils.isNullOrEmpty(metricsArray)) { - return null; - } - - JSONObject clickMetric = null; - - for (int i = 0; i < metricsArray.length(); i++) { - final JSONObject metric = metricsArray.optJSONObject(i); - - if (metric == null || - !TargetJson.MetricType.CLICK.equals(metric.optString(TargetJson.Metric.TYPE, null)) - || StringUtils.isNullOrEmpty(metric.optString(TargetJson.Metric.EVENT_TOKEN, null))) { - continue; - } - - clickMetric = metric; - break; - } - - return clickMetric; - } - - /** - * Return the Target error message, if any - * - * @param responseJson {@link JSONObject} Target response JSON - * @return {@link String} response error, if any - */ - String getErrorMessage(final JSONObject responseJson) { - if (responseJson == null) { - return null; - } - - return responseJson.optString(TargetJson.MESSAGE, null); - } - - /** - * Return Mbox content from mboxJson, if any - * - * @param mboxJson {@link JSONObject} Target response JSON - * @return {@link String} mbox content, if any otherwise returns null - */ - String extractMboxContent(final JSONObject mboxJson) { - if (mboxJson == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "extractMboxContent - unable to extract mbox contents, mbox json is null"); - return null; - } - - final JSONArray optionsArray = mboxJson.optJSONArray(TargetJson.OPTIONS); - - if (optionsArray == null) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "extractMboxContent - unable to extract mbox contents, options array is null"); - return null; - } - - final StringBuilder contentBuilder = new StringBuilder(); - - for (int i = 0; i < optionsArray.length(); i++) { - final JSONObject option = optionsArray.optJSONObject(i); - - if (option == null || StringUtils.isNullOrEmpty(option.optString(TargetJson.Option.CONTENT, ""))) { - continue; - } - - final String optionType = option.optString(TargetJson.Option.TYPE, ""); - String optionContent = ""; - - if (optionType.equals(TargetJson.HTML)) { - optionContent = option.optString(TargetJson.Option.CONTENT, ""); - } else if (optionType.equals(TargetJson.JSON)) { - final Object content = option.opt(TargetJson.Option.CONTENT); - if (content != null) { - optionContent = content.toString(); - } - } - - contentBuilder.append(optionContent); - } - - return contentBuilder.toString(); - } -} \ No newline at end of file + private static final String CLASS_NAME = "TargetResponseParser"; + + /** + * Parse the target server response to a json object if there is no error. + * + *

Do not pass a null connection object to this method. This method return null if + * + *

    + *
  1. There is any error occurred while reading the JSON response. + *
  2. If the response code for the connection is not 200 (HTTP_OK). + *
  3. If the response from the server is empty or not a valid JSON. + *
+ * + * @param connection the network {@link com.adobe.marketing.mobile.services.HttpConnecting} + * object returned from server + * @return the {@link JSONObject} if the response is valid + */ + @Nullable JSONObject parseResponseToJson(final HttpConnecting connection) { + try { + if (connection != null) { + final String responseString = StreamUtils.readAsString(connection.getInputStream()); + if (StringUtils.isNullOrEmpty(responseString)) { + return null; + } + final JSONObject responseJson = new JSONObject(responseString); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Target Response was received : %s", + responseString); + return responseJson; + } + } catch (final JSONException e) { + Log.error( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Unable to parse Target Response, Error (%s)", + e); + } + return null; + } + + /** + * Extracts the mboxes from the server response for a certain key. + * + *

Used by methods {@code #extractPrefetchedMboxes(JSONObject)} and {@code + * #extractBatchedMBoxes(JSONObject)}. Do not pass a null {@code JSONObject} serverResponseJson. + * + * @param serverResponseJson A {@link JSONObject} server response + * @param key A {@link String} key name for which mbox need should the mboxes be extracted from + * @return all the mboxes for the given key + */ + private JSONArray getMboxesFromKey(final JSONObject serverResponseJson, final String key) { + final JSONObject containerJson = serverResponseJson.optJSONObject(key); + + if (containerJson == null) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "getMboxesFromKey - Unable to retrieve mboxes from key, json is null"); + return null; + } + + final JSONArray mboxJSONArray = containerJson.optJSONArray(TargetJson.MBOXES); + + if (mboxJSONArray == null) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "getMboxesFromKey - Unable to retrieve mboxes from key, mboxes array is null"); + return null; + } + + return mboxJSONArray; + } + + /** + * Extracts the batched mboxes from the server response and returns them as a {@code Map}, where + * the mbox name is the key and the {@code JSONObject} returned from the server is the value. + * + *

Returns null if there is no {@link TargetJson#MBOX_RESPONSES} key found in the server + * response. Do not pass a null {@code JSONObject} serverResponseJson. + * + * @param serverResponseJson A {@link JSONObject} server response + * @return A {@link Map} of all the batched mboxes + */ + @Nullable Map extractBatchedMBoxes(final JSONObject serverResponseJson) { + final JSONArray batchedMboxes = getMboxesFromKey(serverResponseJson, TargetJson.EXECUTE); + + if (batchedMboxes == null) { + return null; + } + + final Map mboxResponses = new HashMap<>(); + + for (int i = 0; i < batchedMboxes.length(); i++) { + final JSONObject mboxJson = batchedMboxes.optJSONObject(i); + + if (mboxJson == null) { + continue; + } + + final String mboxName = mboxJson.optString(TargetJson.Mbox.NAME, ""); + + if (StringUtils.isNullOrEmpty(mboxName)) { + continue; + } + + mboxResponses.put(mboxName, mboxJson); + } + + return mboxResponses; + } + + /** + * Extracts the prefetched mboxes from the server response and returns them as a {@code Map}, + * where the mbox name is the key and the {@code JSONObject} returned from the server is the + * value. + * + *

Returns null if there is no {@code TargetJson#PREFETCH_MBOX_RESPONSES} key found in the + * server response. Do not pass a null {@code JSONObject} serverResponseJson. + * + * @param serverResponseJson A {@link JSONObject} server response + * @return A {@link Map} of all the prefetched mboxes + */ + @Nullable Map extractPrefetchedMboxes(final JSONObject serverResponseJson) { + final JSONArray prefetchedMboxes = + getMboxesFromKey(serverResponseJson, TargetJson.PREFETCH); + + if (prefetchedMboxes == null) { + return null; + } + + final Map mboxResponses = new HashMap(); + + for (int i = 0; i < prefetchedMboxes.length(); i++) { + final JSONObject mboxJson = prefetchedMboxes.optJSONObject(i); + + if (mboxJson == null) { + continue; + } + + final String mboxName = mboxJson.optString(TargetJson.Mbox.NAME, ""); + + if (StringUtils.isNullOrEmpty(mboxName)) { + continue; + } + + final Iterator keyIterator = mboxJson.keys(); + final List keyCache = new ArrayList(); + + while (keyIterator.hasNext()) { + keyCache.add(keyIterator.next()); + } + + for (final String key : keyCache) { + if (!TargetJson.CACHED_MBOX_ACCEPTED_KEYS.contains(key)) { + mboxJson.remove(key); + } + } + + mboxResponses.put(mboxName, mboxJson); + } + + return mboxResponses; + } + + /** + * Get the tnt id from the {@code JSONObject} server response. + * + *

Returns null if there is no {@code TargetJson#ID} key found in the server response. Do not + * pass a null {@code JSONObject} serverResponseJson. + * + * @param serverResponseJson A {@link JSONObject} server response + * @return A {@link String} tntid + */ + @Nullable String getTntId(final JSONObject serverResponseJson) { + final JSONObject idJson = serverResponseJson.optJSONObject(TargetJson.ID); + + if (idJson == null) { + return null; + } + + return idJson.optString(TargetJson.ID_TNT_ID, ""); + } + + /** + * Get the edge host from the {@code JSONObject} server response + * + *

Returns an empty {@code String} if there is no {@code TargetJson#EDGE_HOST} key found in + * the server response. Do not pass a null {@code JSONObject} serverResponseJson. + * + * @param serverResponseJson A {@link JSONObject} server response + * @return A {@link String} edge host + */ + String getEdgeHost(final JSONObject serverResponseJson) { + return serverResponseJson.optString(TargetJson.EDGE_HOST, ""); + } + + /** + * Grabs the a4t payload from the target response and convert the keys to correct format + * + *

Returns null if there is no analytics payload that needs to be sent. + * + * @param mboxJson A prefetched mbox {@link JSONObject} + * @return A {@link Map} containing a4t payload + */ + @Nullable Map getAnalyticsForTargetPayload( + final JSONObject mboxJson, final String sessionId) { + final Map payload = getAnalyticsForTargetPayload(mboxJson); + return preprocessAnalyticsForTargetPayload(payload, sessionId); + } + + /** + * Converts the A4T params keys to correct format as required by the Analytics + * + *

Returns null if {@code payload} is null or empty + * + * @param payload {@code Map} with A4t params + * @param sessionId Target session id + * @return {@code Map} with processed keys + */ + @Nullable Map preprocessAnalyticsForTargetPayload( + final Map payload, final String sessionId) { + if (TargetUtils.isNullOrEmpty(payload)) { + return null; + } + + final Map modifiedPayload = new HashMap(); + + for (Map.Entry entry : payload.entrySet()) { + modifiedPayload.put("&&" + entry.getKey(), entry.getValue()); + } + + if (!StringUtils.isNullOrEmpty(sessionId)) { + modifiedPayload.put(TargetConstants.EventDataKeys.A4T_SESSION_ID, sessionId); + } + + return modifiedPayload; + } + + /** + * Parse the JSON object parameter to read A4T payload and returns it as a {@code Map}. Returns null if {@code json} doesn't have A4T payload. + * + * @param json {@link JSONObject} containing analytics payload + * @return {@code Map} containing A4T params + */ + @Nullable Map getAnalyticsForTargetPayload(final JSONObject json) { + if (json == null) { + return null; + } + + final JSONObject analyticsJson = json.optJSONObject(TargetJson.ANALYTICS_PARAMETERS); + + if (analyticsJson == null) { + return null; + } + + final JSONObject payloadJson = analyticsJson.optJSONObject(TargetJson.ANALYTICS_PAYLOAD); + + if (payloadJson == null) { + return null; + } + + return TargetUtils.toStringMap(payloadJson); + } + + /** + * Parse the Mbox JSON object to read Response Tokens from the Options. The data will be read + * from the first option in the options list. + * + * @param mboxJson Mbox {@link JSONObject} + * @return Response tokens from options payload as {@code Map}, or null if + * response tokens are not activated on Target. + */ + Map getResponseTokens(final JSONObject mboxJson) { + if (mboxJson == null) { + return null; + } + + final JSONArray optionsArray = mboxJson.optJSONArray(TargetJson.OPTIONS); + + if (JSONUtils.isNullOrEmpty(optionsArray)) { + return null; + } + + // Mbox payload will have a single option object in options array, which is accessed using + // the index 0 and + // further used to grab response tokens. + final JSONObject option = optionsArray.optJSONObject(0); + + if (option == null) { + return null; + } + + final JSONObject responseTokens = option.optJSONObject(TargetJson.Option.RESPONSE_TOKENS); + + if (responseTokens == null) { + return null; + } + + Map responseTokensMap = null; + try { + responseTokensMap = JSONUtils.toMap(responseTokens); + } catch (final JSONException e) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Exception (%s) is thrown when parsing response tokens to create an object" + + " Map.", + e); + } + return responseTokensMap; + } + + /** + * Extracts the click metric A4T params from the {@code mboxJson} and return them as a {@code + * Map}. + * + *

Returns null if click metric analytics payload is missing in the mbox payload or there is + * any error in parsing {@code mboxJson}. + * + * @param mboxJson {@link JSONObject} of a mbox + * @return {@code Map} containing click metric A4T params + */ + Map extractClickMetricAnalyticsPayload(final JSONObject mboxJson) { + final JSONObject clickMetric = getClickMetric(mboxJson); + return getAnalyticsForTargetPayload(clickMetric); + } + + /** + * Grab the click metric {@link JSONObject} and returns it + * + *

This method returns null if the input {@code mboxJson} is null, or if the metrics array is + * not present in the {@code mboxJson}, or if a valid click metric object is not found in the + * metrics array, or if the eventToken is not found in the click metric object + * + * @param mboxJson {@code JSONObject} for mbox + * @return {@code JSONObject} for click metric + */ + JSONObject getClickMetric(final JSONObject mboxJson) { + if (mboxJson == null) { + return null; + } + + final JSONArray metricsArray = mboxJson.optJSONArray(TargetJson.METRICS); + + if (JSONUtils.isNullOrEmpty(metricsArray)) { + return null; + } + + JSONObject clickMetric = null; + + for (int i = 0; i < metricsArray.length(); i++) { + final JSONObject metric = metricsArray.optJSONObject(i); + + if (metric == null + || !TargetJson.MetricType.CLICK.equals( + metric.optString(TargetJson.Metric.TYPE, null)) + || StringUtils.isNullOrEmpty( + metric.optString(TargetJson.Metric.EVENT_TOKEN, null))) { + continue; + } + + clickMetric = metric; + break; + } + + return clickMetric; + } + + /** + * Return the Target error message, if any + * + * @param responseJson {@link JSONObject} Target response JSON + * @return {@link String} response error, if any + */ + String getErrorMessage(final JSONObject responseJson) { + if (responseJson == null) { + return null; + } + + return responseJson.optString(TargetJson.MESSAGE, null); + } + + /** + * Return Mbox content from mboxJson, if any + * + * @param mboxJson {@link JSONObject} Target response JSON + * @return {@link String} mbox content, if any otherwise returns null + */ + String extractMboxContent(final JSONObject mboxJson) { + if (mboxJson == null) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "extractMboxContent - unable to extract mbox contents, mbox json is null"); + return null; + } + + final JSONArray optionsArray = mboxJson.optJSONArray(TargetJson.OPTIONS); + + if (optionsArray == null) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "extractMboxContent - unable to extract mbox contents, options array is null"); + return null; + } + + final StringBuilder contentBuilder = new StringBuilder(); + + for (int i = 0; i < optionsArray.length(); i++) { + final JSONObject option = optionsArray.optJSONObject(i); + + if (option == null + || StringUtils.isNullOrEmpty(option.optString(TargetJson.Option.CONTENT, ""))) { + continue; + } + + final String optionType = option.optString(TargetJson.Option.TYPE, ""); + String optionContent = ""; + + if (optionType.equals(TargetJson.HTML)) { + optionContent = option.optString(TargetJson.Option.CONTENT, ""); + } else if (optionType.equals(TargetJson.JSON)) { + final Object content = option.opt(TargetJson.Option.CONTENT); + if (content != null) { + optionContent = content.toString(); + } + } + + contentBuilder.append(optionContent); + } + + return contentBuilder.toString(); + } +} diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetState.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetState.java index e38439d..abf43d6 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetState.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetState.java @@ -1,5 +1,5 @@ /* - Copyright 2023 Adobe. All rights reserved. + Copyright 2022 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -7,11 +7,11 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ +*/ + package com.adobe.marketing.mobile.target; import androidx.annotation.NonNull; - import com.adobe.marketing.mobile.MobilePrivacyStatus; import com.adobe.marketing.mobile.services.Log; import com.adobe.marketing.mobile.services.NamedCollection; @@ -19,10 +19,6 @@ import com.adobe.marketing.mobile.util.JSONUtils; import com.adobe.marketing.mobile.util.StringUtils; import com.adobe.marketing.mobile.util.TimeUtils; - -import org.json.JSONException; -import org.json.JSONObject; - import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -30,6 +26,8 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import org.json.JSONException; +import org.json.JSONObject; class TargetState { @@ -47,26 +45,31 @@ class TargetState { private String sessionId = ""; private long sessionTimestampInSeconds = 0L; - private static final List LOADED_MBOX_ACCEPTED_KEYS = Arrays.asList(TargetJson.Mbox.NAME, - TargetJson.METRICS); + private static final List LOADED_MBOX_ACCEPTED_KEYS = + Arrays.asList(TargetJson.Mbox.NAME, TargetJson.METRICS); TargetState(final NamedCollection dataStore) { this.dataStore = dataStore; if (dataStore == null) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, "Unable to initialize TargetState, datastore is null"); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "Unable to initialize TargetState, datastore is null"); return; } tntId = dataStore.getString(TargetConstants.DataStoreKeys.TNT_ID, ""); thirdPartyId = dataStore.getString(TargetConstants.DataStoreKeys.THIRD_PARTY_ID, ""); edgeHost = dataStore.getString(TargetConstants.DataStoreKeys.EDGE_HOST, ""); sessionId = dataStore.getString(TargetConstants.DataStoreKeys.SESSION_ID, ""); - sessionTimestampInSeconds = dataStore.getLong(TargetConstants.DataStoreKeys.SESSION_TIMESTAMP, 0L); - + sessionTimestampInSeconds = + dataStore.getLong(TargetConstants.DataStoreKeys.SESSION_TIMESTAMP, 0L); } /** - * Updates the stored configuration shared state if the given one is not null. - * If the given configuration shared state contains a new client code, the stored `edge host` will be set with null. + * Updates the stored configuration shared state if the given one is not null. If the given + * configuration shared state contains a new client code, the stored `edge host` will be set + * with null. + * * @param configuration {@code Map configuration) { @@ -74,7 +77,9 @@ void updateConfigurationSharedState(final Map configuration) { return; } - final String newClientCode = DataReader.optString(configuration, TargetConstants.Configuration.TARGET_CLIENT_CODE, ""); + final String newClientCode = + DataReader.optString( + configuration, TargetConstants.Configuration.TARGET_CLIENT_CODE, ""); if (storedConfigurationSharedState != null && !newClientCode.equals(getClientCode())) { updateEdgeHost(null); } @@ -84,21 +89,28 @@ void updateConfigurationSharedState(final Map configuration) { /** * Get {@code MobilePrivacyStatus} for this Target extension. * - * @return {@link MobilePrivacyStatus} {@link TargetConstants.Configuration#GLOBAL_CONFIG_PRIVACY} value from the last known Configuration state + * @return {@link MobilePrivacyStatus} {@link + * TargetConstants.Configuration#GLOBAL_CONFIG_PRIVACY} value from the last known + * Configuration state */ MobilePrivacyStatus getMobilePrivacyStatus() { - final String privacyString = DataReader.optString(storedConfigurationSharedState, - TargetConstants.Configuration.GLOBAL_CONFIG_PRIVACY, MobilePrivacyStatus.UNKNOWN.getValue()); + final String privacyString = + DataReader.optString( + storedConfigurationSharedState, + TargetConstants.Configuration.GLOBAL_CONFIG_PRIVACY, + MobilePrivacyStatus.UNKNOWN.getValue()); return MobilePrivacyStatus.fromString(privacyString); } /** * Get the session timeout from config or default session timeout * - * @return {@code int} session timeout from config or default session timeout {@code int} TargetConstants#DEFAULT_TARGET_SESSION_TIMEOUT_SEC + * @return {@code int} session timeout from config or default session timeout {@code int} + * TargetConstants#DEFAULT_TARGET_SESSION_TIMEOUT_SEC */ int getSessionTimeout() { - return DataReader.optInt(storedConfigurationSharedState, + return DataReader.optInt( + storedConfigurationSharedState, TargetConstants.Configuration.TARGET_SESSION_TIMEOUT, TargetConstants.DEFAULT_TARGET_SESSION_TIMEOUT_SEC); } @@ -106,65 +118,79 @@ int getSessionTimeout() { /** * Get {@code String} client code for this Target extension. * - * @return {@link String} {@link TargetConstants.Configuration#TARGET_CLIENT_CODE} value from the last known Configuration state + * @return {@link String} {@link TargetConstants.Configuration#TARGET_CLIENT_CODE} value from + * the last known Configuration state */ String getClientCode() { - return DataReader.optString(storedConfigurationSharedState, - TargetConstants.Configuration.TARGET_CLIENT_CODE, ""); + return DataReader.optString( + storedConfigurationSharedState, + TargetConstants.Configuration.TARGET_CLIENT_CODE, + ""); } /** * Get {@code String} environmentId for this Target extension. * - * @return {@link String} {@link TargetConstants.Configuration#TARGET_ENVIRONMENT_ID} value from the last known Configuration state + * @return {@link String} {@link TargetConstants.Configuration#TARGET_ENVIRONMENT_ID} value from + * the last known Configuration state */ long getEnvironmentId() { - return DataReader.optLong(storedConfigurationSharedState, - TargetConstants.Configuration.TARGET_ENVIRONMENT_ID, 0L); + return DataReader.optLong( + storedConfigurationSharedState, + TargetConstants.Configuration.TARGET_ENVIRONMENT_ID, + 0L); } /** * Get {@code String} property token for this Target extension. * - * @return {@link String}{@link TargetConstants.Configuration#TARGET_PROPERTY_TOKEN} value from the last known Configuration state + * @return {@link String}{@link TargetConstants.Configuration#TARGET_PROPERTY_TOKEN} value from + * the last known Configuration state */ String getPropertyToken() { - return DataReader.optString(storedConfigurationSharedState, - TargetConstants.Configuration.TARGET_PROPERTY_TOKEN, ""); + return DataReader.optString( + storedConfigurationSharedState, + TargetConstants.Configuration.TARGET_PROPERTY_TOKEN, + ""); } /** * Get {@code String} target server for this Target extension. * - * @return {@link String}{@link TargetConstants.Configuration#TARGET_SERVER} value from the last known Configuration state + * @return {@link String}{@link TargetConstants.Configuration#TARGET_SERVER} value from the last + * known Configuration state */ String getTargetServer() { - return DataReader.optString(storedConfigurationSharedState, - TargetConstants.Configuration.TARGET_SERVER, ""); + return DataReader.optString( + storedConfigurationSharedState, TargetConstants.Configuration.TARGET_SERVER, ""); } /** * Get {@code String} network timeout for this Target extension. * - * @return {@link String}{@link TargetConstants.Configuration#TARGET_SERVER} value from the last known Configuration state + * @return {@link String}{@link TargetConstants.Configuration#TARGET_SERVER} value from the last + * known Configuration state */ int getNetworkTimeout() { - return DataReader.optInt(storedConfigurationSharedState, TargetConstants.Configuration.TARGET_NETWORK_TIMEOUT, TargetConstants.DEFAULT_NETWORK_TIMEOUT); + return DataReader.optInt( + storedConfigurationSharedState, + TargetConstants.Configuration.TARGET_NETWORK_TIMEOUT, + TargetConstants.DEFAULT_NETWORK_TIMEOUT); } /** * Get the sessionId either from memory or from the datastore if session is not expired. * - *

- * Context: AMSDK-8217 - * Retrieves the sessionId from memory. If no value in memory, it generates a random UUID, - * sets current timestamp for {@code long} sessionTimestampInSeconds and saves them in persistence. - * The sessionId is refreshed after - * {@link TargetConstants.Configuration#TARGET_SESSION_TIMEOUT} (secs) of inactivity - * (from the last successful target request). - *

- * The sessionId is sent in URL query parameters for each Target Network call; based on this Target will - * route all requests from a session to the same edge to prevent overwriting the profiles. + *

Context: AMSDK-8217 Retrieves the sessionId from memory. If no value in memory, it + * generates a random UUID, sets current timestamp for {@code long} sessionTimestampInSeconds + * and saves them in persistence. The sessionId is refreshed after {@link + * TargetConstants.Configuration#TARGET_SESSION_TIMEOUT} (secs) of inactivity (from the last + * successful target request). + * + *

The sessionId is sent in URL query parameters for each Target Network call; based on this + * Target will route all requests from a session to the same edge to prevent overwriting the + * profiles. + * *

* * @return the session ID value as {@link String} @@ -172,7 +198,8 @@ int getNetworkTimeout() { String getSessionId() { // if there is no session id persisted in local data store or if the session id is expired // because there was no activity for more than certain amount of time - // (from the last successful network request), then generate a new session id, save it in persistence storage + // (from the last successful network request), then generate a new session id, save it in + // persistence storage if (StringUtils.isNullOrEmpty(sessionId) || isSessionExpired()) { sessionId = UUID.randomUUID().toString(); @@ -189,9 +216,10 @@ String getSessionId() { /** * Returns edgeHost in memory. - *

- * If current session expired, the edge host is reset to null (in memory and persistence), so + * + *

If current session expired, the edge host is reset to null (in memory and persistence), so * the next network call will use the target client code. + * *

* * @return the edgeHost {@link String} value @@ -199,7 +227,10 @@ String getSessionId() { String getEdgeHost() { // If the session expired reset the edge host if (isSessionExpired()) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, "getEdgeHost - Resetting edge host to null as session id expired."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "getEdgeHost - Resetting edge host to null as session id expired."); updateEdgeHost(null); } else { if (StringUtils.isNullOrEmpty(edgeHost) && dataStore != null) { @@ -209,7 +240,6 @@ String getEdgeHost() { return edgeHost; } - /** * Get {@code String} tntId for this Target extension. * @@ -230,6 +260,7 @@ String getThirdPartyId() { /** * Get configuration shared state in memory + * * @return {@code Map getStoredConfigurationSharedState() { @@ -238,44 +269,58 @@ Map getStoredConfigurationSharedState() { /** * Returns Target Preview enabled status + * * @return {@code boolean} {@link TargetConstants.Configuration#TARGET_PREVIEW_ENABLED} value - * from the last known Configuration state if present, true otherwise + * from the last known Configuration state if present, true otherwise */ boolean isPreviewEnabled() { - return DataReader.optBoolean(storedConfigurationSharedState, TargetConstants.Configuration.TARGET_PREVIEW_ENABLED, true); + return DataReader.optBoolean( + storedConfigurationSharedState, + TargetConstants.Configuration.TARGET_PREVIEW_ENABLED, + true); } /** - * Updates {@code long} session timestamp in memory and in datastore. - * If session timestamp needs to be reset, locally stored session timestamp is set to 0 and the value is removed from persistence. - * If not, sets locally stored session timestamp to the current timestamp and stores it in persistence. + * Updates {@code long} session timestamp in memory and in datastore. If session timestamp needs + * to be reset, locally stored session timestamp is set to 0 and the value is removed from + * persistence. If not, sets locally stored session timestamp to the current timestamp and + * stores it in persistence. * - *

- * Note: this method needs to be called after each successful target network request in order + *

Note: this method needs to be called after each successful target network request in order * to compute the session id expiration date properly. + * *

- * @param resetSessionTimestamp {@link Boolean} representing if session timestamp needs to be reset + * + * @param resetSessionTimestamp {@link Boolean} representing if session timestamp needs to be + * reset */ void updateSessionTimestamp(final boolean resetSessionTimestamp) { - if(resetSessionTimestamp) { + if (resetSessionTimestamp) { sessionTimestampInSeconds = 0L; if (dataStore != null) { - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, "updateSessionTimestamp - Attempting to remove the session timestamp"); + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, + "updateSessionTimestamp - Attempting to remove the session timestamp"); dataStore.remove(TargetConstants.DataStoreKeys.SESSION_TIMESTAMP); } return; } sessionTimestampInSeconds = TimeUtils.getUnixTimeInSeconds(); if (dataStore != null) { - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, "updateSessionTimestamp - Attempting to update the session timestamp"); - dataStore.setLong(TargetConstants.DataStoreKeys.SESSION_TIMESTAMP, sessionTimestampInSeconds); + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, + "updateSessionTimestamp - Attempting to update the session timestamp"); + dataStore.setLong( + TargetConstants.DataStoreKeys.SESSION_TIMESTAMP, sessionTimestampInSeconds); } } /** - * Updates {@code String} sessionId in memory and in the datastore. - * If provided sessionId is null or empty, removes the value in persistence. - * If not, stores the new sessionId in persistence. + * Updates {@code String} sessionId in memory and in the datastore. If provided sessionId is + * null or empty, removes the value in persistence. If not, stores the new sessionId in + * persistence. * * @param updatedSessionId {@link String} containing the new sessionId to be set */ @@ -283,19 +328,24 @@ void updateSessionId(final String updatedSessionId) { sessionId = updatedSessionId; if (dataStore != null) { if (StringUtils.isNullOrEmpty(sessionId)) { - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, "updateSessionId - Attempting to remove the session id"); + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, + "updateSessionId - Attempting to remove the session id"); dataStore.remove(TargetConstants.DataStoreKeys.SESSION_ID); } else { - Log.trace(TargetConstants.LOG_TAG, CLASS_NAME, "updateSessionId - Attempting to update the session id"); + Log.trace( + TargetConstants.LOG_TAG, + CLASS_NAME, + "updateSessionId - Attempting to update the session id"); dataStore.setString(TargetConstants.DataStoreKeys.SESSION_ID, updatedSessionId); } } } /** - * Updates {@code String} tntId in memory and in the datastore. - * If provided tntId is null or empty value, removes the value in persistence. - * If not, stores the new tntId in persistence. + * Updates {@code String} tntId in memory and in the datastore. If provided tntId is null or + * empty value, removes the value in persistence. If not, stores the new tntId in persistence. * * @param updatedTntId {@link String} containing new tntId that needs to be set. */ @@ -304,23 +354,31 @@ void updateTntId(final String updatedTntId) { if (dataStore != null) { if (StringUtils.isNullOrEmpty(updatedTntId)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "setTntIdInternal - Removed tntId from the data store, provided tntId value is null or empty."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "setTntIdInternal - Removed tntId from the data store, provided tntId value" + + " is null or empty."); dataStore.remove(TargetConstants.DataStoreKeys.TNT_ID); } else { - Log.debug(TargetConstants.LOG_TAG, "setTntIdInternal - Persisted new tntId (%s) in the data store.", updatedTntId); + Log.debug( + TargetConstants.LOG_TAG, + "setTntIdInternal - Persisted new tntId (%s) in the data store.", + updatedTntId); dataStore.setString(TargetConstants.DataStoreKeys.TNT_ID, updatedTntId); } } else { - Log.debug(TargetConstants.LOG_TAG, "setTntIdInternal - " + TargetErrors.TARGET_TNT_ID_NOT_PERSISTED, + Log.debug( + TargetConstants.LOG_TAG, + "setTntIdInternal - " + TargetErrors.TARGET_TNT_ID_NOT_PERSISTED, "Data store is not available."); } } /** - * Updates {@code String} thirdPartyId in memory and in the datastore. - * If provided thirdPartyId is null or empty value, removes the value in persistence. - * If not, stores the new thirdPartyId in persistence. + * Updates {@code String} thirdPartyId in memory and in the datastore. If provided thirdPartyId + * is null or empty value, removes the value in persistence. If not, stores the new thirdPartyId + * in persistence. * * @param updatedThirdPartyId {@link String} containing new thirdPartyId that needs to be set. */ @@ -328,30 +386,43 @@ void updateThirdPartyId(final String updatedThirdPartyId) { thirdPartyId = updatedThirdPartyId; if (dataStore != null) { if (StringUtils.isNullOrEmpty(thirdPartyId)) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "setThirdPartyId - Removed thirdPartyId from the data store, provided thirdPartyId value is null or empty."); + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "setThirdPartyId - Removed thirdPartyId from the data store, provided" + + " thirdPartyId value is null or empty."); dataStore.remove(TargetConstants.DataStoreKeys.THIRD_PARTY_ID); } else { - Log.debug(TargetConstants.LOG_TAG, "setThirdPartyId - Persisted new thirdPartyId (%s) in the data store.", thirdPartyId); + Log.debug( + TargetConstants.LOG_TAG, + "setThirdPartyId - Persisted new thirdPartyId (%s) in the data store.", + thirdPartyId); dataStore.setString(TargetConstants.DataStoreKeys.THIRD_PARTY_ID, thirdPartyId); } } else { - Log.debug(TargetConstants.LOG_TAG, "setTntIsetThirdPartyIddInternal - " + TargetErrors.TARGET_THIRD_PARTY_ID_NOT_PERSISTED, + Log.debug( + TargetConstants.LOG_TAG, + "setTntIsetThirdPartyIddInternal - " + + TargetErrors.TARGET_THIRD_PARTY_ID_NOT_PERSISTED, "Data store is not available."); } } /** - * Updates {@code String} edge host in memory and in the datastore. - * If provided edge host is null or empty, removes the value in persistence. - * If not, stores the new edge host in persistence. + * Updates {@code String} edge host in memory and in the datastore. If provided edge host is + * null or empty, removes the value in persistence. If not, stores the new edge host in + * persistence. * * @param updatedEdgeHost {@link String} containing the new edge host to be set */ void updateEdgeHost(final String updatedEdgeHost) { - if ((edgeHost == null && updatedEdgeHost == null) || (edgeHost != null && edgeHost.equals(updatedEdgeHost))) { - Log.debug(TargetConstants.LOG_TAG, CLASS_NAME, - "updateEdgeHost - Data store is not updated as the provided edge host is same as the existing edgeHost"); + if ((edgeHost == null && updatedEdgeHost == null) + || (edgeHost != null && edgeHost.equals(updatedEdgeHost))) { + Log.debug( + TargetConstants.LOG_TAG, + CLASS_NAME, + "updateEdgeHost - Data store is not updated as the provided edge host is same" + + " as the existing edgeHost"); return; } @@ -366,9 +437,7 @@ void updateEdgeHost(final String updatedEdgeHost) { } } - /** - * Resets current sessionId and the sessionTimestampInSeconds - */ + /** Resets current sessionId and the sessionTimestampInSeconds */ void resetSession() { updateSessionId(""); updateSessionTimestamp(true); @@ -409,8 +478,8 @@ void clearPrefetchedMboxes() { } /** - * Extracts the supported mbox node parameters that will be stored in loaded mboxes cache and will be - * used later on for click notifications. + * Extracts the supported mbox node parameters that will be stored in loaded mboxes cache and + * will be used later on for click notifications. * * @param mBoxResponses the mbox responses list from the target response */ @@ -422,7 +491,9 @@ void saveLoadedMbox(@NonNull final Map mBoxResponses) { final String mboxName = mbox.getKey(); final JSONObject mboxNode = mbox.getValue(); - if (!StringUtils.isNullOrEmpty(mboxName) && !prefetchedMbox.containsKey(mboxName) && mboxNode != null) { + if (!StringUtils.isNullOrEmpty(mboxName) + && !prefetchedMbox.containsKey(mboxName) + && mboxNode != null) { final JSONObject clearedMboxNode; try { clearedMboxNode = new JSONObject(mboxNode.toString()); @@ -446,9 +517,7 @@ void saveLoadedMbox(@NonNull final Map mBoxResponses) { } } - /** - * Removes mboxes from loadedMboxes if they are also present in the prefetchedMboxes cache - */ + /** Removes mboxes from loadedMboxes if they are also present in the prefetchedMboxes cache */ void removeDuplicateLoadedMboxes() { for (String mboxName : prefetchedMbox.keySet()) { if (mboxName != null) { @@ -466,7 +535,7 @@ void clearNotifications() { } void addNotification(final JSONObject notification) { - if (JSONUtils.isNullOrEmpty(notification)){ + if (JSONUtils.isNullOrEmpty(notification)) { return; } notifications.add(notification); @@ -484,7 +553,7 @@ List getNotifications() { private boolean isSessionExpired() { final long currentTimeSeconds = TimeUtils.getUnixTimeInSeconds(); - return (sessionTimestampInSeconds > 0) && ((currentTimeSeconds - sessionTimestampInSeconds) > getSessionTimeout()); + return (sessionTimestampInSeconds > 0) + && ((currentTimeSeconds - sessionTimestampInSeconds) > getSessionTimeout()); } } - diff --git a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetUtils.java b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetUtils.java index 873a0e9..fb9d4e6 100644 --- a/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetUtils.java +++ b/code/target/src/main/java/com/adobe/marketing/mobile/target/TargetUtils.java @@ -1,31 +1,27 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; import androidx.annotation.Nullable; - import com.adobe.marketing.mobile.services.Log; import com.adobe.marketing.mobile.util.StringUtils; - -import org.json.JSONException; -import org.json.JSONObject; - import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.TimeZone; +import org.json.JSONException; +import org.json.JSONObject; class TargetUtils { private static final String CLASS_NAME = "TargetUtils"; @@ -36,7 +32,8 @@ class TargetUtils { * Checks if the given {@code collection} is null or empty. * * @param collection input {@code Collection} to be tested. - * @return {@code boolean} result indicating whether the provided {@code collection} is null or empty. + * @return {@code boolean} result indicating whether the provided {@code collection} is null or + * empty. */ static boolean isNullOrEmpty(final Collection collection) { return collection == null || collection.isEmpty(); @@ -64,13 +61,13 @@ static double getUTCTimeOffsetMinutes() { } /** - * Returns a {@code Map} instance from a {@code JSONObject} instance if valid, null otherwise + * Returns a {@code Map} instance from a {@code JSONObject} instance if valid, + * null otherwise * * @param jsonObject {@link JSONObject} instance to be converted * @return {@code Map toStringMap(@Nullable final JSONObject jsonObject) { + @Nullable static Map toStringMap(@Nullable final JSONObject jsonObject) { if (jsonObject == null) { return null; } @@ -84,16 +81,22 @@ static Map toStringMap(@Nullable final JSONObject jsonObject) { try { map.put(name, jsonObject.getString(name)); } catch (final JSONException e) { - Log.warning(TargetConstants.LOG_TAG, CLASS_NAME, "The value of [%s] is not a string: %s", name, e); + Log.warning( + TargetConstants.LOG_TAG, + CLASS_NAME, + "The value of [%s] is not a string: %s", + name, + e); } } - if(isNullOrEmpty(map)) { + if (isNullOrEmpty(map)) { return null; } return map; } + static Map extractQueryParameters(final String queryString) { if (StringUtils.isNullOrEmpty(queryString)) { return null; @@ -109,8 +112,8 @@ static Map extractQueryParameters(final String queryString) { final String[] currentParamArray = currentParam.split("=", 2); - if (currentParamArray.length != 2 || - (currentParamArray[0].isEmpty() || currentParamArray[1].isEmpty())) { + if (currentParamArray.length != 2 + || (currentParamArray[0].isEmpty() || currentParamArray[1].isEmpty())) { continue; } @@ -121,5 +124,4 @@ static Map extractQueryParameters(final String queryString) { return parameters; } - } diff --git a/code/target/src/phone/java/com/adobe/marketing/mobile/Target.java b/code/target/src/phone/java/com/adobe/marketing/mobile/Target.java index 04605db..b114200 100644 --- a/code/target/src/phone/java/com/adobe/marketing/mobile/Target.java +++ b/code/target/src/phone/java/com/adobe/marketing/mobile/Target.java @@ -1,17 +1,20 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile; +import android.net.Uri; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import com.adobe.marketing.mobile.services.Log; import com.adobe.marketing.mobile.target.AdobeTargetDetailedCallback; import com.adobe.marketing.mobile.target.TargetExtension; @@ -22,13 +25,6 @@ import com.adobe.marketing.mobile.util.DataReaderException; import com.adobe.marketing.mobile.util.MapUtils; import com.adobe.marketing.mobile.util.StringUtils; - -import android.net.Uri; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -36,15 +32,14 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -/** - * Public class containing APIs for the Target extension. - */ +/** Public class containing APIs for the Target extension. */ public class Target { + /** Target extension Class */ public static final Class EXTENSION = TargetExtension.class; static final String LOG_TAG = "Target"; private static final String CLASS_NAME = "Target"; - static final String EXTENSION_VERSION = "2.0.3"; + public static final String EXTENSION_VERSION = "3.0.0"; static final class EventName { static final String PREFETCH_REQUEST = "TargetPrefetchRequest"; @@ -73,7 +68,6 @@ static final class EventType { private EventType() {} } - static final class EventSource { static final String REQUEST_CONTENT = "com.adobe.eventSource.requestContent"; static final String RESPONSE_CONTENT = "com.adobe.eventSource.responseContent"; @@ -94,7 +88,7 @@ static final class EventDataKeys { static final String IS_LOCATION_DISPLAYED = "islocationdisplayed"; static final String IS_LOCATION_CLICKED = "islocationclicked"; static final String THIRD_PARTY_ID = "thirdpartyid"; - static final String TNT_ID = "tntid"; + static final String TNT_ID = "tntid"; static final String SESSION_ID = "sessionid"; static final String RESET_EXPERIENCE = "resetexperience"; static final String CLEAR_PREFETCH_CACHE = "clearcache"; @@ -114,14 +108,19 @@ private EventDataKeys() {} } private static final String NULL_MBOX_MESSAGE = "Mbox name must not be empty or null"; - private static final String NULL_MBOXES_MESSAGE = "List of Mbox names must not be empty or null"; - private static final String NULL_REQUEST_MESSAGE = "The provided request list for mboxes is empty or null"; - private static final String NO_VALID_REQUEST_MESSAGE = "The provided request list for mboxes does not contain valid requests"; - private static final String NULL_RAW_REQUEST_MESSAGE = "The provided request map is empty or null"; + private static final String NULL_MBOXES_MESSAGE = + "List of Mbox names must not be empty or null"; + private static final String NULL_REQUEST_MESSAGE = + "The provided request list for mboxes is empty or null"; + private static final String NO_VALID_REQUEST_MESSAGE = + "The provided request list for mboxes does not contain valid requests"; + private static final String NULL_RAW_REQUEST_MESSAGE = + "The provided request map is empty or null"; private static final long DEFAULT_TIMEOUT_MS = 5000L; private static boolean isResponseListenerRegistered = false; - private static final ConcurrentHashMap pendingTargetRequestsMap = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap pendingTargetRequestsMap = + new ConcurrentHashMap<>(); private Target() {} @@ -130,55 +129,45 @@ private Target() {} * * @return {@link String} containing the current installed version of this extension. */ - @NonNull - public static String extensionVersion() { + @NonNull public static String extensionVersion() { return EXTENSION_VERSION; } - /** - * Registers the extension with the Mobile Core. - *

- * Note: This method should be called only once in your application class. - */ - @Deprecated - public static void registerExtension() { - MobileCore.registerExtension(TargetExtension.class, extensionError -> { - if (extensionError == null) { - return; - } - - Log.warning(LOG_TAG, CLASS_NAME, - "An error occurred while registering the Target extension: (%s) ", extensionError.getErrorName()); - }); - } - /** * Prefetches multiple Target mboxes simultaneously. - *

- * Executes a prefetch request to the configured Target server with the TargetPrefetch list provided - * in the {@code mboxPrefetchList} parameter. This prefetch request will use the provided {@code parameters} for all of - * the prefetch made in this request. The {@code callback} will be executed when the prefetch has been completed, returning - * {@code null} if the prefetch was successful or will contain a {@code String} error message otherwise - *

- * The prefetched mboxes are cached in memory for the current application session and returned when requested. - * - * @param mboxPrefetchList a {@code List} representing the desired mboxes to prefetch - * @param parameters a {@code TargetParameters} object containing Target parameters for all mboxes in the request list - * @param callback an {@code AdobeCallback} which will be called after the prefetch is complete. The success parameter - * in the callback will be {@code null} if the prefetch completed successfully, or will contain a {@code String} error message otherwise. - * If an {@link AdobeCallbackWithError} is provided, an {@link AdobeError} can be returned in the - * eventuality of an unexpected error or if the timeout (5 seconds) is met before the content is prefetched. + * + *

Executes a prefetch request to the configured Target server with the TargetPrefetch list + * provided in the {@code mboxPrefetchList} parameter. This prefetch request will use the + * provided {@code parameters} for all of the prefetch made in this request. The {@code + * callback} will be executed when the prefetch has been completed, returning {@code null} if + * the prefetch was successful or will contain a {@code String} error message otherwise + * + *

The prefetched mboxes are cached in memory for the current application session and + * returned when requested. + * + * @param mboxPrefetchList a {@code List} representing the desired mboxes to + * prefetch + * @param parameters a {@code TargetParameters} object containing Target parameters for all + * mboxes in the request list + * @param callback an {@code AdobeCallback} which will be called after the prefetch is + * complete. The success parameter in the callback will be {@code null} if the prefetch + * completed successfully, or will contain a {@code String} error message otherwise. If an + * {@link AdobeCallbackWithError} is provided, an {@link AdobeError} can be returned in the + * eventuality of an unexpected error or if the timeout (5 seconds) is met before the + * content is prefetched. */ - public static void prefetchContent(@NonNull final List mboxPrefetchList, - @Nullable final TargetParameters parameters, - @Nullable final AdobeCallback callback) { - final AdobeCallbackWithError callbackWithError = callback instanceof AdobeCallbackWithError ? - (AdobeCallbackWithError)callback : null; + public static void prefetchContent( + @NonNull final List mboxPrefetchList, + @Nullable final TargetParameters parameters, + @Nullable final AdobeCallback callback) { + final AdobeCallbackWithError callbackWithError = + callback instanceof AdobeCallbackWithError + ? (AdobeCallbackWithError) callback + : null; final String error; if (mboxPrefetchList == null || mboxPrefetchList.isEmpty()) { - error = String.format("Failed to prefetch Target request (%s).", - NULL_REQUEST_MESSAGE); + error = String.format("Failed to prefetch Target request (%s).", NULL_REQUEST_MESSAGE); Log.warning(LOG_TAG, CLASS_NAME, error); if (callbackWithError != null) { @@ -190,7 +179,7 @@ public static void prefetchContent(@NonNull final List mboxPrefe } final List> flattenedPrefetchRequests = new ArrayList<>(); - for (final TargetPrefetch prefetch: mboxPrefetchList) { + for (final TargetPrefetch prefetch : mboxPrefetchList) { if (prefetch == null) { continue; } @@ -198,8 +187,9 @@ public static void prefetchContent(@NonNull final List mboxPrefe } if (flattenedPrefetchRequests.isEmpty()) { - error = String.format("Failed to prefetch Target request (%s).", - NO_VALID_REQUEST_MESSAGE); + error = + String.format( + "Failed to prefetch Target request (%s).", NO_VALID_REQUEST_MESSAGE); Log.warning(LOG_TAG, CLASS_NAME, error); if (callbackWithError != null) { callbackWithError.fail(AdobeError.UNEXPECTED_ERROR); @@ -214,54 +204,69 @@ public static void prefetchContent(@NonNull final List mboxPrefe eventData.put(EventDataKeys.TARGET_PARAMETERS, parameters.toEventData()); } - final Event event = new Event.Builder(EventName.PREFETCH_REQUEST, EventType.TARGET, EventSource.REQUEST_CONTENT) - .setEventData(eventData).build(); - - MobileCore.dispatchEventWithResponseCallback(event, DEFAULT_TIMEOUT_MS, new AdobeCallbackWithError() { - @Override - public void fail(final AdobeError adobeError) { - if (callbackWithError != null) { - callbackWithError.fail(adobeError); - } - } - - @Override - public void call(final Event event) { - final Map eventData = event.getEventData(); - if (MapUtils.isNullOrEmpty(eventData)) { - if (callbackWithError != null) { - callbackWithError.fail(AdobeError.UNEXPECTED_ERROR); + final Event event = + new Event.Builder( + EventName.PREFETCH_REQUEST, + EventType.TARGET, + EventSource.REQUEST_CONTENT) + .setEventData(eventData) + .build(); + + MobileCore.dispatchEventWithResponseCallback( + event, + DEFAULT_TIMEOUT_MS, + new AdobeCallbackWithError() { + @Override + public void fail(final AdobeError adobeError) { + if (callbackWithError != null) { + callbackWithError.fail(adobeError); + } } - return; - } - final String prefetchError = DataReader.optString(eventData, EventDataKeys.PREFETCH_ERROR, null); - callback.call(prefetchError); - } - }); + @Override + public void call(final Event event) { + final Map eventData = event.getEventData(); + if (MapUtils.isNullOrEmpty(eventData)) { + if (callbackWithError != null) { + callbackWithError.fail(AdobeError.UNEXPECTED_ERROR); + } + return; + } + + final String prefetchError = + DataReader.optString(eventData, EventDataKeys.PREFETCH_ERROR, null); + callback.call(prefetchError); + } + }); } /** * Retrieves content for multiple Target mbox locations at once. - *

- * Executes a batch request to the configured Target server for multiple mbox locations. Any prefetched content - * which matches a given mbox location is returned and not included in the batch request to the Target server. - * Each object in the list contains a callback function, which will be invoked when content is available for - * its given mbox location. - * If a {@code} TargetRequest within the {@code List} contains an {@link AdobeCallbackWithError}, - * an {@link AdobeError} can be returned in the eventuality of an unexpected error or if the timeout (5 seconds) is met - * before the location content is retrieved. - *

- * Note: If any mboxes have been prefetched before calling this method, please call one of the - * {@code displayedLocations()} methods after the content returned by this method has been displayed. + * + *

Executes a batch request to the configured Target server for multiple mbox locations. Any + * prefetched content which matches a given mbox location is returned and not included in the + * batch request to the Target server. Each object in the list contains a callback function, + * which will be invoked when content is available for its given mbox location. If a {@code} + * TargetRequest within the {@code List} contains an {@link + * AdobeCallbackWithError}, an {@link AdobeError} can be returned in the eventuality of an + * unexpected error or if the timeout (5 seconds) is met before the location content is + * retrieved. + * + *

Note: If any mboxes have been prefetched before calling this method, please call one of + * the {@code displayedLocations()} methods after the content returned by this method has been + * displayed. * * @param mboxRequestList a {@code List} to retrieve content for - * @param parameters a {@link TargetParameters} object containing parameters for all mboxes in the request list + * @param parameters a {@link TargetParameters} object containing parameters for all mboxes in + * the request list */ - public static void retrieveLocationContent(@NonNull final List mboxRequestList, - @Nullable final TargetParameters parameters) { + public static void retrieveLocationContent( + @NonNull final List mboxRequestList, + @Nullable final TargetParameters parameters) { if (mboxRequestList == null || mboxRequestList.isEmpty()) { - Log.warning(LOG_TAG, CLASS_NAME, + Log.warning( + LOG_TAG, + CLASS_NAME, "Failed to retrieve Target location content (%s).", NULL_REQUEST_MESSAGE); return; @@ -270,17 +275,22 @@ public static void retrieveLocationContent(@NonNull final List mb final List mboxRequestListCopy = new ArrayList<>(mboxRequestList); final List> flattenedLocationRequests = new ArrayList<>(); final Map tempIdToRequestMap = new HashMap<>(); - for (final TargetRequest request: mboxRequestListCopy) { + for (final TargetRequest request : mboxRequestListCopy) { if (request == null) { continue; } final AdobeCallback callback = request.getContentCallback(); - final AdobeTargetDetailedCallback contentWithDataCallback = request.getContentWithDataCallback(); + final AdobeTargetDetailedCallback contentWithDataCallback = + request.getContentWithDataCallback(); // Skip the target request objects with null/empty mbox names final String mboxName = request.getMboxName(); if (StringUtils.isNullOrEmpty(mboxName)) { - Log.warning(LOG_TAG, CLASS_NAME, "Failed to retrieve Target location content (%s), returning default content.", + Log.warning( + LOG_TAG, + CLASS_NAME, + "Failed to retrieve Target location content (%s), returning default" + + " content.", NULL_MBOX_MESSAGE); final String defaultContent = request.getDefaultContent(); if (contentWithDataCallback != null) { @@ -299,7 +309,10 @@ public static void retrieveLocationContent(@NonNull final List mb } if (flattenedLocationRequests.isEmpty()) { - Log.warning(LOG_TAG, CLASS_NAME, "Failed to retrieve Target location content (%s).", + Log.warning( + LOG_TAG, + CLASS_NAME, + "Failed to retrieve Target location content (%s).", NO_VALID_REQUEST_MESSAGE); return; } @@ -313,32 +326,40 @@ public static void retrieveLocationContent(@NonNull final List mb eventData.put(EventDataKeys.TARGET_PARAMETERS, parameters.toEventData()); } - final Event event = new Event.Builder(EventName.LOAD_REQUEST, - EventType.TARGET, - EventSource.REQUEST_CONTENT) - .setEventData(eventData) - .build(); - - for (final Map.Entry entry : tempIdToRequestMap.entrySet()) { - pendingTargetRequestsMap.put(event.getUniqueIdentifier()+ "-" +entry.getKey(), entry.getValue()); + final Event event = + new Event.Builder( + EventName.LOAD_REQUEST, + EventType.TARGET, + EventSource.REQUEST_CONTENT) + .setEventData(eventData) + .build(); + + for (final Map.Entry entry : tempIdToRequestMap.entrySet()) { + pendingTargetRequestsMap.put( + event.getUniqueIdentifier() + "-" + entry.getKey(), entry.getValue()); } MobileCore.dispatchEvent(event); } /** - * Sends a display notification to Target for a given prefetched mbox. This helps Target record location display events. - *

- * Note: if you're only using regular mboxes, and not prefetching any mbox content via {@code prefetchContent()} - * this method should not be called. + * Sends a display notification to Target for a given prefetched mbox. This helps Target record + * location display events. + * + *

Note: if you're only using regular mboxes, and not prefetching any mbox content via + * {@code prefetchContent()} this method should not be called. * * @param mboxNames (required) a list of displayed {@code String} location names * @param targetParameters {@link TargetParameters} for the displayed locations */ - public static void displayedLocations(@NonNull final List mboxNames, @Nullable final TargetParameters targetParameters) { + public static void displayedLocations( + @NonNull final List mboxNames, + @Nullable final TargetParameters targetParameters) { if (mboxNames == null || mboxNames.size() == 0) { - Log.warning(LOG_TAG, CLASS_NAME, + Log.warning( + LOG_TAG, + CLASS_NAME, "Failed to send display notification (%s).", NULL_MBOXES_MESSAGE); return; @@ -351,27 +372,34 @@ public static void displayedLocations(@NonNull final List mboxNames, @Nu eventData.put(EventDataKeys.TARGET_PARAMETERS, targetParameters.toEventData()); } - final Event event = new Event.Builder(EventName.LOCATIONS_DISPLAYED, - EventType.TARGET, - EventSource.REQUEST_CONTENT) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.LOCATIONS_DISPLAYED, + EventType.TARGET, + EventSource.REQUEST_CONTENT) + .setEventData(eventData) + .build(); MobileCore.dispatchEvent(event); } /** - * Sends a click notification to Target if click metrics are enabled for the provided location name. - *

- * Click notification can be sent for a location, provided a load request has been executed for that prefetched or regular mbox - * location before, indicating that the mbox was viewed. This request helps Target record the clicked event for the given location or mbox. + * Sends a click notification to Target if click metrics are enabled for the provided location + * name. * - * @param mboxName (required) a {@code String} representing the location name + *

Click notification can be sent for a location, provided a load request has been executed + * for that prefetched or regular mbox location before, indicating that the mbox was viewed. + * This request helps Target record the clicked event for the given location or mbox. + * + * @param mboxName (required) a {@code String} representing the location name * @param parameters {@link TargetParameters} object for the location clicked */ - public static void clickedLocation(@NonNull final String mboxName, @Nullable final TargetParameters parameters) { + public static void clickedLocation( + @NonNull final String mboxName, @Nullable final TargetParameters parameters) { if (StringUtils.isNullOrEmpty(mboxName)) { - Log.warning(LOG_TAG, CLASS_NAME, + Log.warning( + LOG_TAG, + CLASS_NAME, "Failed to send click notification (%s).", NULL_MBOX_MESSAGE); return; @@ -384,69 +412,83 @@ public static void clickedLocation(@NonNull final String mboxName, @Nullable fin eventData.put(EventDataKeys.TARGET_PARAMETERS, parameters.toEventData()); } - final Event event = new Event.Builder(EventName.LOCATION_CLICKED, - EventType.TARGET, - EventSource.REQUEST_CONTENT) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.LOCATION_CLICKED, + EventType.TARGET, + EventSource.REQUEST_CONTENT) + .setEventData(eventData) + .build(); MobileCore.dispatchEvent(event); } /** * Gets the custom visitor ID for Target. - *

- * This ID will be reset when the {@link #resetExperience()} API is called. * - * @param callback {@link AdobeCallback} the callback invoked with the third party id value {@code String}. The value will be null if no - * third-party ID was set. - * If an {@link AdobeCallbackWithError} is provided, an {@link AdobeError} can be returned in the - * eventuality of an unexpected error or if the timeout (5 seconds) is met before the third party id is retrieved. + *

This ID will be reset when the {@link #resetExperience()} API is called. + * + * @param callback {@link AdobeCallback} the callback invoked with the third party id value + * {@code String}. The value will be null if no third-party ID was set. If an {@link + * AdobeCallbackWithError} is provided, an {@link AdobeError} can be returned in the + * eventuality of an unexpected error or if the timeout (5 seconds) is met before the third + * party id is retrieved. * @see #setThirdPartyId(String) */ public static void getThirdPartyId(@NonNull final AdobeCallback callback) { if (callback == null) { - Log.warning(LOG_TAG, CLASS_NAME, + Log.warning( + LOG_TAG, + CLASS_NAME, "Failed to get Target session ID, provided AdobeCallback (callback) is null."); return; } - final Event event = new Event.Builder(EventName.GET_THIRD_PARTY_ID, - EventType.TARGET, - EventSource.REQUEST_IDENTITY) - .build(); - - final AdobeCallbackWithError callbackWithError = callback instanceof AdobeCallbackWithError ? - (AdobeCallbackWithError)callback : null; - - MobileCore.dispatchEventWithResponseCallback(event, DEFAULT_TIMEOUT_MS, new AdobeCallbackWithError() { - @Override - public void fail(final AdobeError adobeError) { - if (callbackWithError != null) { - callbackWithError.fail(adobeError); - } - } - - @Override - public void call(final Event event) { - final Map eventData = event.getEventData(); - if (MapUtils.isNullOrEmpty(eventData)) { - if (callbackWithError != null) { - callbackWithError.fail(AdobeError.UNEXPECTED_ERROR); + final Event event = + new Event.Builder( + EventName.GET_THIRD_PARTY_ID, + EventType.TARGET, + EventSource.REQUEST_IDENTITY) + .build(); + + final AdobeCallbackWithError callbackWithError = + callback instanceof AdobeCallbackWithError + ? (AdobeCallbackWithError) callback + : null; + + MobileCore.dispatchEventWithResponseCallback( + event, + DEFAULT_TIMEOUT_MS, + new AdobeCallbackWithError() { + @Override + public void fail(final AdobeError adobeError) { + if (callbackWithError != null) { + callbackWithError.fail(adobeError); + } } - return; - } - final String responseData = (String)eventData.get(EventDataKeys.THIRD_PARTY_ID); - callback.call(responseData); - } - }); + @Override + public void call(final Event event) { + final Map eventData = event.getEventData(); + if (MapUtils.isNullOrEmpty(eventData)) { + if (callbackWithError != null) { + callbackWithError.fail(AdobeError.UNEXPECTED_ERROR); + } + return; + } + + final String responseData = + (String) eventData.get(EventDataKeys.THIRD_PARTY_ID); + callback.call(responseData); + } + }); } /** * Sets the third party ID for Target. - *

- * This ID will be persisted until either {@link #resetExperience()} is called or the app is uninstalled. + * + *

This ID will be persisted until either {@link #resetExperience()} is called or the app is + * uninstalled. * * @param thirdPartyId {@code String} containing the third party Id value. */ @@ -454,77 +496,93 @@ public static void setThirdPartyId(@Nullable final String thirdPartyId) { final Map eventData = new HashMap<>(); eventData.put(EventDataKeys.THIRD_PARTY_ID, thirdPartyId); - final Event event = new Event.Builder(EventName.SET_THIRD_PARTY_ID, - EventType.TARGET, - EventSource.REQUEST_IDENTITY) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.SET_THIRD_PARTY_ID, + EventType.TARGET, + EventSource.REQUEST_IDENTITY) + .setEventData(eventData) + .build(); MobileCore.dispatchEvent(event); } /** * Gets the Target user identifier. - *

- * The tnt ID is returned in the network response from Target after a successful call to - * {@link #prefetchContent(List, TargetParameters, AdobeCallback)} API or {@link #retrieveLocationContent(List, TargetParameters)} API, - * which is then persisted in the SDK. The persisted tnt ID is used in subsequent Target requests until a different tnt ID is returned - * from Target, or a new tnt ID is set using {@link #setTntId(String)} API. - * - * @param callback {@link AdobeCallback} the callback invoked with the tnt ID value as {@code String} or null if not available. - * If an {@link AdobeCallbackWithError} is provided, an {@link AdobeError} can be returned in the - * eventuality of an unexpected error, or if the timeout (5 seconds) is met before the tnt ID is retrieved. + * + *

The tnt ID is returned in the network response from Target after a successful call to + * {@link #prefetchContent(List, TargetParameters, AdobeCallback)} API or {@link + * #retrieveLocationContent(List, TargetParameters)} API, which is then persisted in the SDK. + * The persisted tnt ID is used in subsequent Target requests until a different tnt ID is + * returned from Target, or a new tnt ID is set using {@link #setTntId(String)} API. + * + * @param callback {@link AdobeCallback} the callback invoked with the tnt ID value as {@code + * String} or null if not available. If an {@link AdobeCallbackWithError} is provided, an + * {@link AdobeError} can be returned in the eventuality of an unexpected error, or if the + * timeout (5 seconds) is met before the tnt ID is retrieved. * @see #setTntId(String) */ public static void getTntId(@NonNull final AdobeCallback callback) { if (callback == null) { - Log.warning(LOG_TAG, CLASS_NAME, + Log.warning( + LOG_TAG, + CLASS_NAME, "Failed to get Target session ID, provided AdobeCallback (callback) is null."); return; } - final Event event = new Event.Builder(EventName.GET_TNT_ID, - EventType.TARGET, - EventSource.REQUEST_IDENTITY) - .build(); - - final AdobeCallbackWithError callbackWithError = callback instanceof AdobeCallbackWithError ? - (AdobeCallbackWithError)callback : null; - - MobileCore.dispatchEventWithResponseCallback(event, DEFAULT_TIMEOUT_MS, new AdobeCallbackWithError() { - @Override - public void fail(final AdobeError adobeError) { - if (callbackWithError != null) { - callbackWithError.fail(adobeError); - } - } - - @Override - public void call(final Event event) { - final Map eventData = event.getEventData(); - if (MapUtils.isNullOrEmpty(eventData)) { - if (callbackWithError != null) { - callbackWithError.fail(AdobeError.UNEXPECTED_ERROR); + final Event event = + new Event.Builder( + EventName.GET_TNT_ID, + EventType.TARGET, + EventSource.REQUEST_IDENTITY) + .build(); + + final AdobeCallbackWithError callbackWithError = + callback instanceof AdobeCallbackWithError + ? (AdobeCallbackWithError) callback + : null; + + MobileCore.dispatchEventWithResponseCallback( + event, + DEFAULT_TIMEOUT_MS, + new AdobeCallbackWithError() { + @Override + public void fail(final AdobeError adobeError) { + if (callbackWithError != null) { + callbackWithError.fail(adobeError); + } } - return; - } - final String responseData = (String)eventData.get(EventDataKeys.TNT_ID); - callback.call(responseData); - } - }); + @Override + public void call(final Event event) { + final Map eventData = event.getEventData(); + if (MapUtils.isNullOrEmpty(eventData)) { + if (callbackWithError != null) { + callbackWithError.fail(AdobeError.UNEXPECTED_ERROR); + } + return; + } + + final String responseData = (String) eventData.get(EventDataKeys.TNT_ID); + callback.call(responseData); + } + }); } /** * Sets the Target user identifier. - *

- * The provided tnt ID is persisted in the SDK and attached to subsequent Target requests. It is used to - * derive the edge host value in the SDK, which is also persisted and used in future Target requests. - *

- * If the provided tnt ID is null or empty, or if the privacy status is opted out, the SDK will remove the tnt ID and edge host values from the persistence. - *

- * This ID is preserved between app upgrades, is saved and restored during the standard application backup process, - * and is removed at uninstall, upon privacy status update to opted out, or when the {@link #resetExperience()} API is called. + * + *

The provided tnt ID is persisted in the SDK and attached to subsequent Target requests. It + * is used to derive the edge host value in the SDK, which is also persisted and used in future + * Target requests. + * + *

If the provided tnt ID is null or empty, or if the privacy status is opted out, the SDK + * will remove the tnt ID and edge host values from the persistence. + * + *

This ID is preserved between app upgrades, is saved and restored during the standard + * application backup process, and is removed at uninstall, upon privacy status update to opted + * out, or when the {@link #resetExperience()} API is called. * * @param tntId {@link String} containing the tnt ID value to be set in the SDK. * @see #getTntId(AdobeCallback) @@ -533,75 +591,91 @@ public static void setTntId(@Nullable final String tntId) { final Map eventData = new HashMap<>(); eventData.put(EventDataKeys.TNT_ID, tntId); - final Event event = new Event.Builder(EventName.SET_TNT_ID, - EventType.TARGET, - EventSource.REQUEST_IDENTITY) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.SET_TNT_ID, + EventType.TARGET, + EventSource.REQUEST_IDENTITY) + .setEventData(eventData) + .build(); MobileCore.dispatchEvent(event); } /** * Gets the Target session identifier. - *

- * The session ID is generated locally in the SDK upon initial Target request and persisted for a period defined by - * {@code target.sessionTimeout} configuration setting. If the session timeout happens upon a subsequent Target request, - * a new session ID will be generated for use in the request and persisted in the SDK. - * - * @param callback {@link AdobeCallback} the callback invoked with the session ID value as {@code String}. - * If an {@link AdobeCallbackWithError} is provided, an {@link AdobeError} can be returned in the - * eventuality of an unexpected error, or if the timeout (5 seconds) is met before the session ID is retrieved. + * + *

The session ID is generated locally in the SDK upon initial Target request and persisted + * for a period defined by {@code target.sessionTimeout} configuration setting. If the session + * timeout happens upon a subsequent Target request, a new session ID will be generated for use + * in the request and persisted in the SDK. + * + * @param callback {@link AdobeCallback} the callback invoked with the session ID value as + * {@code String}. If an {@link AdobeCallbackWithError} is provided, an {@link AdobeError} + * can be returned in the eventuality of an unexpected error, or if the timeout (5 seconds) + * is met before the session ID is retrieved. * @see #setSessionId(String) */ public static void getSessionId(@NonNull final AdobeCallback callback) { if (callback == null) { - Log.warning(LOG_TAG, CLASS_NAME, + Log.warning( + LOG_TAG, + CLASS_NAME, "Failed to get Target session ID, provided AdobeCallback (callback) is null."); return; } - final Event event = new Event.Builder(EventName.GET_SESSION_ID, - EventType.TARGET, - EventSource.REQUEST_IDENTITY) - .build(); - - final AdobeCallbackWithError callbackWithError = callback instanceof AdobeCallbackWithError ? - (AdobeCallbackWithError)callback : null; - - MobileCore.dispatchEventWithResponseCallback(event, DEFAULT_TIMEOUT_MS, new AdobeCallbackWithError() { - @Override - public void fail(final AdobeError adobeError) { - if (callbackWithError != null) { - callbackWithError.fail(adobeError); - } - } - - @Override - public void call(final Event event) { - final Map eventData = event.getEventData(); - if (MapUtils.isNullOrEmpty(eventData)) { - if (callbackWithError != null) { - callbackWithError.fail(AdobeError.UNEXPECTED_ERROR); + final Event event = + new Event.Builder( + EventName.GET_SESSION_ID, + EventType.TARGET, + EventSource.REQUEST_IDENTITY) + .build(); + + final AdobeCallbackWithError callbackWithError = + callback instanceof AdobeCallbackWithError + ? (AdobeCallbackWithError) callback + : null; + + MobileCore.dispatchEventWithResponseCallback( + event, + DEFAULT_TIMEOUT_MS, + new AdobeCallbackWithError() { + @Override + public void fail(final AdobeError adobeError) { + if (callbackWithError != null) { + callbackWithError.fail(adobeError); + } } - return; - } - final String responseData = (String)eventData.get(EventDataKeys.SESSION_ID); - callback.call(responseData); - } - }); + @Override + public void call(final Event event) { + final Map eventData = event.getEventData(); + if (MapUtils.isNullOrEmpty(eventData)) { + if (callbackWithError != null) { + callbackWithError.fail(AdobeError.UNEXPECTED_ERROR); + } + return; + } + + final String responseData = + (String) eventData.get(EventDataKeys.SESSION_ID); + callback.call(responseData); + } + }); } /** * Sets the Target session identifier. - *

- * The provided session ID is persisted in the SDK for a period defined by {@code target.sessionTimeout} configuration setting. - * If the provided session ID is null or empty, or if the privacy status is opted out, the SDK will remove the session ID value - * from the persistence. - *

- * This ID is preserved between app upgrades, is saved and restored during the standard application backup process, - * and is removed at uninstall, upon privacy status update to opted out, or when the {@link #resetExperience()} API is called. + * + *

The provided session ID is persisted in the SDK for a period defined by {@code + * target.sessionTimeout} configuration setting. If the provided session ID is null or empty, or + * if the privacy status is opted out, the SDK will remove the session ID value from the + * persistence. + * + *

This ID is preserved between app upgrades, is saved and restored during the standard + * application backup process, and is removed at uninstall, upon privacy status update to opted + * out, or when the {@link #resetExperience()} API is called. * * @param sessionId {@link String} containing the Target session ID value to be set in the SDK. * @see #getSessionId(AdobeCallback) @@ -610,19 +684,22 @@ public static void setSessionId(@Nullable final String sessionId) { final Map eventData = new HashMap<>(); eventData.put(EventDataKeys.SESSION_ID, sessionId); - final Event event = new Event.Builder(EventName.SET_SESSION_ID, - EventType.TARGET, - EventSource.REQUEST_IDENTITY) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.SET_SESSION_ID, + EventType.TARGET, + EventSource.REQUEST_IDENTITY) + .setEventData(eventData) + .build(); MobileCore.dispatchEvent(event); } /** * Resets the user's experience - *

- * Resets the user's experience by removing the visitor identifiers. Removes previously set third-party and TnT IDs from persistent storage. + * + *

Resets the user's experience by removing the visitor identifiers. Removes previously set + * third-party and TnT IDs from persistent storage. * * @see #getThirdPartyId(AdobeCallback) * @see #getTntId(AdobeCallback) @@ -631,11 +708,13 @@ public static void resetExperience() { final Map eventData = new HashMap<>(); eventData.put(EventDataKeys.RESET_EXPERIENCE, true); - final Event event = new Event.Builder(EventName.REQUEST_RESET, - EventType.TARGET, - EventSource.REQUEST_RESET) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.REQUEST_RESET, + EventType.TARGET, + EventSource.REQUEST_RESET) + .setEventData(eventData) + .build(); MobileCore.dispatchEvent(event); } @@ -649,25 +728,29 @@ public static void clearPrefetchCache() { final Map eventData = new HashMap<>(); eventData.put(EventDataKeys.CLEAR_PREFETCH_CACHE, true); - final Event event = new Event.Builder(EventName.CLEAR_PREFETCH_CACHE, - EventType.TARGET, - EventSource.REQUEST_RESET) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.CLEAR_PREFETCH_CACHE, + EventType.TARGET, + EventSource.REQUEST_RESET) + .setEventData(eventData) + .build(); MobileCore.dispatchEvent(event); } /** * Sets the Target preview restart deep link. - *

- * Set the Target preview URL to be displayed when a new preview experience is loaded. * - * @param deepLink the {@link Uri} which will be set for preview restart + *

Set the Target preview URL to be displayed when a new preview experience is loaded. + * + * @param deepLink the {@link Uri} which will be set for preview restart */ public static void setPreviewRestartDeepLink(@NonNull final Uri deepLink) { if (deepLink == null) { - Log.warning(LOG_TAG, CLASS_NAME, + Log.warning( + LOG_TAG, + CLASS_NAME, "Failed to set preview restart deeplink as the provided value is null."); return; } @@ -675,33 +758,44 @@ public static void setPreviewRestartDeepLink(@NonNull final Uri deepLink) { final Map eventData = new HashMap<>(); eventData.put(EventDataKeys.PREVIEW_RESTART_DEEP_LINK, deepLink.toString()); - final Event event = new Event.Builder(EventName.SET_PREVIEW_DEEPLINK, - EventType.TARGET, - EventSource.REQUEST_CONTENT) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.SET_PREVIEW_DEEPLINK, + EventType.TARGET, + EventSource.REQUEST_CONTENT) + .setEventData(eventData) + .build(); MobileCore.dispatchEvent(event); } /** * Retrieves Target prefetch or execute response for a list of mbox locations. - *

- * It issues a request to the configured Target server for the provided mbox locations in the request. * - * @param request a {@code Map} containing prefetch or execute request data in the Target v1 delivery API format. - * @param callback an {@code AdobeCallback>} which will be called after the Target request is completed. The parameter - * in the callback will contain the response data if the execute request completed successfully, or it will contain null otherwise. + *

It issues a request to the configured Target server for the provided mbox locations in the + * request. + * + * @param request a {@code Map} containing prefetch or execute request data in + * the Target v1 delivery API format. + * @param callback an {@code AdobeCallback>} which will be called after the + * Target request is completed. The parameter in the callback will contain the response data + * if the execute request completed successfully, or it will contain null otherwise. */ - public static void executeRawRequest(@NonNull final Map request, - @NonNull final AdobeCallback> callback) { + public static void executeRawRequest( + @NonNull final Map request, + @NonNull final AdobeCallback> callback) { - final AdobeCallbackWithError callbackWithError = callback instanceof AdobeCallbackWithError ? - (AdobeCallbackWithError) callback : null; + final AdobeCallbackWithError callbackWithError = + callback instanceof AdobeCallbackWithError + ? (AdobeCallbackWithError) callback + : null; if (MapUtils.isNullOrEmpty(request)) { - Log.warning(LOG_TAG, CLASS_NAME, - "Failed to execute raw Target request (%s).", NULL_RAW_REQUEST_MESSAGE); + Log.warning( + LOG_TAG, + CLASS_NAME, + "Failed to execute raw Target request (%s).", + NULL_RAW_REQUEST_MESSAGE); if (callbackWithError != null) { callbackWithError.fail(AdobeError.UNEXPECTED_ERROR); @@ -713,8 +807,11 @@ public static void executeRawRequest(@NonNull final Map request, if (!request.containsKey(EventDataKeys.EXECUTE) && !request.containsKey(EventDataKeys.PREFETCH)) { - Log.warning(LOG_TAG,CLASS_NAME, - "Failed to execute raw Target request, provided request doesn't contain prefetch or execute data."); + Log.warning( + LOG_TAG, + CLASS_NAME, + "Failed to execute raw Target request, provided request doesn't contain" + + " prefetch or execute data."); if (callbackWithError != null) { callbackWithError.fail(AdobeError.UNEXPECTED_ERROR); @@ -727,184 +824,253 @@ public static void executeRawRequest(@NonNull final Map request, final Map eventData = new HashMap<>(request); eventData.put(EventDataKeys.IS_RAW_EVENT, true); - final Event event = new Event.Builder(EventName.TARGET_RAW_REQUEST, - EventType.TARGET, - EventSource.REQUEST_CONTENT) - .setEventData(eventData) - .build(); - - - MobileCore.dispatchEventWithResponseCallback(event, DEFAULT_TIMEOUT_MS, new AdobeCallbackWithError() { - @Override - public void fail(final AdobeError adobeError) { - if (callbackWithError != null) { - callbackWithError.fail(adobeError); - } - } - - @Override - public void call(final Event event) { - final Map eventData = event.getEventData(); - if (MapUtils.isNullOrEmpty(eventData)) { - if (callbackWithError != null) { - callbackWithError.fail(AdobeError.UNEXPECTED_ERROR); + final Event event = + new Event.Builder( + EventName.TARGET_RAW_REQUEST, + EventType.TARGET, + EventSource.REQUEST_CONTENT) + .setEventData(eventData) + .build(); + + MobileCore.dispatchEventWithResponseCallback( + event, + DEFAULT_TIMEOUT_MS, + new AdobeCallbackWithError() { + @Override + public void fail(final AdobeError adobeError) { + if (callbackWithError != null) { + callbackWithError.fail(adobeError); + } } - return; - } - final Map responseData = DataReader.optTypedMap(Object.class, - eventData, EventDataKeys.RESPONSE_DATA, null); - callback.call(responseData); - } - }); + @Override + public void call(final Event event) { + final Map eventData = event.getEventData(); + if (MapUtils.isNullOrEmpty(eventData)) { + if (callbackWithError != null) { + callbackWithError.fail(AdobeError.UNEXPECTED_ERROR); + } + return; + } + + final Map responseData = + DataReader.optTypedMap( + Object.class, eventData, EventDataKeys.RESPONSE_DATA, null); + callback.call(responseData); + } + }); } /** * Sends a notification request to Target using the provided notification data in the request. - *

- * The display or click tokens, required for the Target notifications, can be retrieved from the - * response of a previous `executeRawRequest` API call. * - * @param request (required) a {@code Map} containing notifications data in the Target v1 delivery API format. + *

The display or click tokens, required for the Target notifications, can be retrieved from + * the response of a previous `executeRawRequest` API call. + * + * @param request (required) a {@code Map} containing notifications data in the + * Target v1 delivery API format. * @see #executeRawRequest(Map, AdobeCallback) */ public static void sendRawNotifications(@NonNull final Map request) { if (MapUtils.isNullOrEmpty(request)) { - Log.warning(LOG_TAG, CLASS_NAME, - "Failed to send raw Target notification(s) (%s).", NULL_RAW_REQUEST_MESSAGE); + Log.warning( + LOG_TAG, + CLASS_NAME, + "Failed to send raw Target notification(s) (%s).", + NULL_RAW_REQUEST_MESSAGE); return; } if (!request.containsKey(EventDataKeys.NOTIFICATIONS)) { - Log.warning(LOG_TAG, CLASS_NAME, - "Failed to send raw Target notification(s), provided request doesn't contain notifications data."); + Log.warning( + LOG_TAG, + CLASS_NAME, + "Failed to send raw Target notification(s), provided request doesn't contain" + + " notifications data."); return; } final Map eventData = new HashMap<>(request); eventData.put(EventDataKeys.IS_RAW_EVENT, true); - final Event event = new Event.Builder(EventName.TARGET_RAW_NOTIFICATIONS, - EventType.TARGET, - EventSource.REQUEST_CONTENT) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.TARGET_RAW_NOTIFICATIONS, + EventType.TARGET, + EventSource.REQUEST_CONTENT) + .setEventData(eventData) + .build(); MobileCore.dispatchEvent(event); } - /** - * Registers the response content event listener - */ + /** Registers the response content event listener */ private static void registerResponseContentEventListener() { // Only register the listener once if (!isResponseListenerRegistered) { - MobileCore.registerEventListener(EventType.TARGET, EventSource.RESPONSE_CONTENT, event -> { - if (!event.getName().equals(EventName.TARGET_REQUEST_RESPONSE)) { - return; - } - - final Map eventData = event.getEventData(); - if (MapUtils.isNullOrEmpty(eventData)) { - Log.debug(LOG_TAG, CLASS_NAME, "Cannot find target request, response event data is null or empty."); - return; - } - - String id = null; - try { - id = DataReader.getString(eventData, EventDataKeys.TARGET_RESPONSE_EVENT_ID); - } catch (final DataReaderException e) { - Log.debug(LOG_TAG, CLASS_NAME, "Cannot find target request, responseEventId is invalid (%s).", e.getLocalizedMessage()); - } - if (StringUtils.isNullOrEmpty(id)) { - Log.debug(LOG_TAG, CLASS_NAME, "Cannot find target request, responseEventId is not available."); - return; - } - - String responsePairId = null; - try { - responsePairId = DataReader.getString(eventData, EventDataKeys.TARGET_RESPONSE_PAIR_ID); - } catch (final DataReaderException e) { - Log.debug(LOG_TAG, CLASS_NAME, "Cannot find target request, responsePairId is invalid (%s).", e.getLocalizedMessage()); - } - if (StringUtils.isNullOrEmpty(responsePairId)) { - Log.debug(LOG_TAG, CLASS_NAME, "Cannot find target request, responsePairId is not available."); - return; - } - - final String requestSearchId = id+"-"+responsePairId; - final TargetRequest request = pendingTargetRequestsMap.get(requestSearchId); - if (request == null) { - Log.warning(LOG_TAG, CLASS_NAME, "Missing target request for (%s)", requestSearchId); - return; - } - - final AdobeCallback callback = request.getContentCallback(); - final AdobeTargetDetailedCallback contentWithDataCallback = request.getContentWithDataCallback(); - - if (contentWithDataCallback != null) { - final Map mboxPayloadMap = createMboxPayloadMap(DataReader.optTypedMap(Object.class, - eventData, EventDataKeys.TARGET_DATA_PAYLOAD, null), request); - final String content = DataReader.optString(eventData, - EventDataKeys.TARGET_CONTENT, - request.getDefaultContent()); - contentWithDataCallback.call(content, mboxPayloadMap); - } else if (callback != null) { - callback.call(DataReader.optString(eventData, - EventDataKeys.TARGET_CONTENT, - request.getDefaultContent())); - } - }); + MobileCore.registerEventListener( + EventType.TARGET, + EventSource.RESPONSE_CONTENT, + event -> { + if (!event.getName().equals(EventName.TARGET_REQUEST_RESPONSE)) { + return; + } + + final Map eventData = event.getEventData(); + if (MapUtils.isNullOrEmpty(eventData)) { + Log.debug( + LOG_TAG, + CLASS_NAME, + "Cannot find target request, response event data is null or" + + " empty."); + return; + } + + String id = null; + try { + id = + DataReader.getString( + eventData, EventDataKeys.TARGET_RESPONSE_EVENT_ID); + } catch (final DataReaderException e) { + Log.debug( + LOG_TAG, + CLASS_NAME, + "Cannot find target request, responseEventId is invalid (%s).", + e.getLocalizedMessage()); + } + if (StringUtils.isNullOrEmpty(id)) { + Log.debug( + LOG_TAG, + CLASS_NAME, + "Cannot find target request, responseEventId is not" + + " available."); + return; + } + + String responsePairId = null; + try { + responsePairId = + DataReader.getString( + eventData, EventDataKeys.TARGET_RESPONSE_PAIR_ID); + } catch (final DataReaderException e) { + Log.debug( + LOG_TAG, + CLASS_NAME, + "Cannot find target request, responsePairId is invalid (%s).", + e.getLocalizedMessage()); + } + if (StringUtils.isNullOrEmpty(responsePairId)) { + Log.debug( + LOG_TAG, + CLASS_NAME, + "Cannot find target request, responsePairId is not available."); + return; + } + + final String requestSearchId = id + "-" + responsePairId; + final TargetRequest request = pendingTargetRequestsMap.get(requestSearchId); + if (request == null) { + Log.warning( + LOG_TAG, + CLASS_NAME, + "Missing target request for (%s)", + requestSearchId); + return; + } + + final AdobeCallback callback = request.getContentCallback(); + final AdobeTargetDetailedCallback contentWithDataCallback = + request.getContentWithDataCallback(); + + if (contentWithDataCallback != null) { + final Map mboxPayloadMap = + createMboxPayloadMap( + DataReader.optTypedMap( + Object.class, + eventData, + EventDataKeys.TARGET_DATA_PAYLOAD, + null), + request); + final String content = + DataReader.optString( + eventData, + EventDataKeys.TARGET_CONTENT, + request.getDefaultContent()); + contentWithDataCallback.call(content, mboxPayloadMap); + } else if (callback != null) { + callback.call( + DataReader.optString( + eventData, + EventDataKeys.TARGET_CONTENT, + request.getDefaultContent())); + } + }); isResponseListenerRegistered = true; } } /** - * Retrieves the mbox values like A4t payload, response tokens, and click metric A4t payload from the provided {@code data} and - * returns them as {@code Map}. - *

- * This method returns null if {@code data} map doesn't contain these values. + * Retrieves the mbox values like A4t payload, response tokens, and click metric A4t payload + * from the provided {@code data} and returns them as {@code Map}. + * + *

This method returns null if {@code data} map doesn't contain these values. * - * @param data a {@code Map} object. + * @param data a {@code Map} object. * @param request an object of {@link TargetRequest}. * @return a {@code Map} containing mbox values received in {@code data} map. */ - private static Map createMboxPayloadMap(final Map data, final TargetRequest request) { + private static Map createMboxPayloadMap( + final Map data, final TargetRequest request) { if (MapUtils.isNullOrEmpty(data)) { - Log.debug(LOG_TAG, CLASS_NAME, - "The data payload map containing response tokens and analytics payload is not present for the mbox location (%s)", request.getMboxName()); + Log.debug( + LOG_TAG, + CLASS_NAME, + "The data payload map containing response tokens and analytics payload is not" + + " present for the mbox location (%s)", + request.getMboxName()); return null; } final Map mboxPayload = new HashMap<>(); - final Map a4tParams = DataReader.optStringMap(data, - EventDataKeys.ANALYTICS_PAYLOAD, - null); + final Map a4tParams = + DataReader.optStringMap(data, EventDataKeys.ANALYTICS_PAYLOAD, null); if (a4tParams != null) { - Log.trace(LOG_TAG, CLASS_NAME, "A4t params map is present for mbox location (%s)", request.getMboxName()); + Log.trace( + LOG_TAG, + CLASS_NAME, + "A4t params map is present for mbox location (%s)", + request.getMboxName()); mboxPayload.put(EventDataKeys.ANALYTICS_PAYLOAD, a4tParams); } - final Map responseTokens = DataReader.optTypedMap(Object.class, - data, - EventDataKeys.RESPONSE_TOKENS, - null); + final Map responseTokens = + DataReader.optTypedMap(Object.class, data, EventDataKeys.RESPONSE_TOKENS, null); if (responseTokens != null) { - Log.trace(LOG_TAG, CLASS_NAME, "Response tokens map is present for mbox location (%s)", request.getMboxName()); + Log.trace( + LOG_TAG, + CLASS_NAME, + "Response tokens map is present for mbox location (%s)", + request.getMboxName()); mboxPayload.put(EventDataKeys.RESPONSE_TOKENS, responseTokens); } - final Map clickMetricA4TParams = DataReader.optStringMap(data, - EventDataKeys.CLICK_METRIC_ANALYTICS_PAYLOAD, - null); + final Map clickMetricA4TParams = + DataReader.optStringMap(data, EventDataKeys.CLICK_METRIC_ANALYTICS_PAYLOAD, null); if (clickMetricA4TParams != null) { - Log.trace(LOG_TAG, CLASS_NAME, "Click metrics map is present for mbox location (%s)", request.getMboxName()); + Log.trace( + LOG_TAG, + CLASS_NAME, + "Click metrics map is present for mbox location (%s)", + request.getMboxName()); mboxPayload.put(EventDataKeys.CLICK_METRIC_ANALYTICS_PAYLOAD, clickMetricA4TParams); } if (mboxPayload.isEmpty()) { - Log.debug(LOG_TAG, CLASS_NAME, - "Neither response tokens are activated on Target UI nor activity is A4T enabled, returning null data payload for mbox location (%s)", + Log.debug( + LOG_TAG, + CLASS_NAME, + "Neither response tokens are activated on Target UI nor activity is A4T" + + " enabled, returning null data payload for mbox location (%s)", request.getMboxName()); return null; } @@ -916,4 +1082,4 @@ private static Map createMboxPayloadMap(final Map targetParameters = new HashMap() { - { - put("paramKey", "paramValue"); - } - }; - - private static final HashMap targetSharedState = new HashMap() { - { - put("tntid", MOCK_TNT_ID); - put("sessionid", MOCK_SESSION_ID); - } - }; + private static final HashMap targetParameters = + new HashMap() { + { + put("paramKey", "paramValue"); + } + }; - private static final HashMap lifecycleSharedState = new HashMap() { - { - put("lifecycleKey", "lifecycleValue"); - } - }; + private static final HashMap targetSharedState = + new HashMap() { + { + put("tntid", MOCK_TNT_ID); + put("sessionid", MOCK_SESSION_ID); + } + }; - private static final HashMap identitySharedState = new HashMap() { - { - put("mid", "samplemid"); - put("blob", "sampleBlob"); - put("locationhint", "sampleLocationHint"); - } - }; + private static final HashMap lifecycleSharedState = + new HashMap() { + { + put("lifecycleKey", "lifecycleValue"); + } + }; - private static final HashMap eventHubSharedState = new HashMap() { - { - put("version", "x.y.z"); - put("wrapper", new HashMap() { + private static final HashMap identitySharedState = + new HashMap() { { - put("friendlyName", "None"); - put("type", "N"); + put("mid", "samplemid"); + put("blob", "sampleBlob"); + put("locationhint", "sampleLocationHint"); } - }); - } - }; + }; - private static final Map responseTokens = new HashMap() {{ - put("responseTokens.Key", "responseTokens.Value"); - put("profile.categoryAffinities", new ArrayList(){ - { - add("books"); - } - }); - put("someKey", new ArrayList(){ - { - add("someValue"); - add(true); - add(42); - } - }); - }}; + private static final HashMap eventHubSharedState = + new HashMap() { + { + put("version", "x.y.z"); + put( + "wrapper", + new HashMap() { + { + put("friendlyName", "None"); + put("type", "N"); + } + }); + } + }; + private static final Map responseTokens = + new HashMap() { + { + put("responseTokens.Key", "responseTokens.Value"); + put( + "profile.categoryAffinities", + new ArrayList() { + { + add("books"); + } + }); + put( + "someKey", + new ArrayList() { + { + add("someValue"); + add(true); + add(42); + } + }); + } + }; - private static final Map clickMetricA4TParams = new HashMap() {{ - put("pe", "tnt"); - put("tnta", "1234|1234"); - }}; + private static final Map clickMetricA4TParams = + new HashMap() { + { + put("pe", "tnt"); + put("tnta", "1234|1234"); + } + }; - private static final Map a4tParams = new HashMap() {{ - put("pe", "tnt"); - put("tnta", "1234|1234"); - }}; + private static final Map a4tParams = + new HashMap() { + { + put("pe", "tnt"); + put("tnta", "1234|1234"); + } + }; private TargetExtension extension; @@ -157,102 +181,172 @@ public class TargetExtensionTests { ArgumentCaptor networkCallbackCaptor; // Mocks - @Mock - Networking networkService; + @Mock ServiceProvider mockServiceProvider; + + @Mock Networking networkService; + + @Mock DeviceInforming deviceInforming; + + @Mock DataStoring dataStoring; - @Mock - DeviceInforming deviceInforming; + @Mock UIService uiService; - @Mock - UIService uiService; + @Mock UriOpening uriService; - @Mock - ExtensionApi mockExtensionApi; + @Mock AppContextService appContextService; - @Mock - TargetRequestBuilder requestBuilder; + @Mock Context context; - @Mock - TargetResponseParser responseParser; + @Mock ExtensionApi mockExtensionApi; - @Mock - TargetPreviewManager targetPreviewManager; + @Mock TargetRequestBuilder requestBuilder; - @Mock - TargetState targetState; + @Mock TargetResponseParser responseParser; - @Mock - HttpConnecting connecting; + @Mock TargetPreviewManager targetPreviewManager; - @Mock - NamedCollection datastore; + @Mock TargetState targetState; + + @Mock HttpConnecting connecting; + + @Mock NamedCollection datastore; @Before - public void setup() throws Exception { - extension = new TargetExtension(mockExtensionApi, deviceInforming, networkService, uiService, targetState, targetPreviewManager, requestBuilder, responseParser); - when(targetState.getClientCode()).thenReturn(MOCKED_CLIENT_CODE); - when(targetState.getNetworkTimeout()).thenReturn(MOCK_NETWORK_TIMEOUT); - when(targetState.getTargetServer()).thenReturn(MOCKED_TARGET_SERVER); - when(targetState.getTntId()).thenReturn(MOCK_TNT_ID); - when(targetState.getThirdPartyId()).thenReturn(MOCK_THIRD_PARTY_ID); - when(targetState.getSessionId()).thenReturn(MOCK_SESSION_ID); - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.OPT_IN); - when(targetState.generateSharedState()).thenReturn(targetSharedState); - - - eventArgumentCaptor = ArgumentCaptor.forClass(Event.class); - networkRequestCaptor = ArgumentCaptor.forClass(NetworkRequest.class); - networkCallbackCaptor = ArgumentCaptor.forClass(NetworkCallback.class); - - when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any(), any(), any())).thenReturn(validJSONObject()); - when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any())).thenReturn(validJSONObject()); - when(requestBuilder.getDisplayNotificationJsonObject(any(), any(), any(), anyLong(), any())).thenReturn(validJSONObject()); - - final JSONObject validMboxResponse = new JSONObject("{\"options\": [{\"content\": \"mbox0content\", \"type\": \"html\"}]}"); - when(responseParser.parseResponseToJson(any())).thenReturn(validJSONObject()); - when(responseParser.parseResponseToJson(any())).thenReturn(validJSONObject()); - when(responseParser.getTntId(any())).thenReturn(MOCK_TNT_ID); - when(responseParser.getEdgeHost(any())).thenReturn(MOCK_EDGE_HOST); - when(responseParser.extractBatchedMBoxes(any())).thenReturn(new HashMap() { - { - put("mbox0", validMboxResponse); - } - }); - when(responseParser.extractMboxContent(eq(validMboxResponse))).thenReturn("mbox0content"); - when(responseParser.getResponseTokens(eq(validMboxResponse))).thenReturn(responseTokens); - when(responseParser.extractClickMetricAnalyticsPayload(eq(validMboxResponse))).thenReturn(clickMetricA4TParams); - when(responseParser.getAnalyticsForTargetPayload(any())).thenReturn(a4tParams); - when(connecting.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); + public void setup() {} + + private void runWithMockedServiceProvider(final Runnable testRunnable) { + try (MockedStatic serviceProviderMockedStatic = + Mockito.mockStatic(ServiceProvider.class)) { + serviceProviderMockedStatic + .when(ServiceProvider::getInstance) + .thenReturn(mockServiceProvider); + when(mockServiceProvider.getDeviceInfoService()).thenReturn(deviceInforming); + when(mockServiceProvider.getDataStoreService()).thenReturn(dataStoring); + when(dataStoring.getNamedCollection(Mockito.anyString())).thenReturn(datastore); + when(mockServiceProvider.getNetworkService()).thenReturn(networkService); + when(mockServiceProvider.getUIService()).thenReturn(uiService); + when(mockServiceProvider.getUriService()).thenReturn(uriService); + when(mockServiceProvider.getAppContextService()).thenReturn(appContextService); + when(appContextService.getApplicationContext()).thenReturn(context); + + when(targetState.getClientCode()).thenReturn(MOCKED_CLIENT_CODE); + when(targetState.getNetworkTimeout()).thenReturn(MOCK_NETWORK_TIMEOUT); + when(targetState.getTargetServer()).thenReturn(MOCKED_TARGET_SERVER); + when(targetState.getTntId()).thenReturn(MOCK_TNT_ID); + when(targetState.getThirdPartyId()).thenReturn(MOCK_THIRD_PARTY_ID); + when(targetState.getSessionId()).thenReturn(MOCK_SESSION_ID); + when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.OPT_IN); + when(targetState.generateSharedState()).thenReturn(targetSharedState); + + eventArgumentCaptor = ArgumentCaptor.forClass(Event.class); + networkRequestCaptor = ArgumentCaptor.forClass(NetworkRequest.class); + networkCallbackCaptor = ArgumentCaptor.forClass(NetworkCallback.class); + + when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any(), any(), any())) + .thenReturn(validJSONObject()); + when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any())) + .thenReturn(validJSONObject()); + when(requestBuilder.getDisplayNotificationJsonObject( + any(), any(), any(), anyLong(), any())) + .thenReturn(validJSONObject()); + + final JSONObject validMboxResponse = + new JSONObject( + "{\"options\": [{\"content\": \"mbox0content\", \"type\": \"html\"}]}"); + when(responseParser.parseResponseToJson(any())).thenReturn(validJSONObject()); + when(responseParser.parseResponseToJson(any())).thenReturn(validJSONObject()); + when(responseParser.getTntId(any())).thenReturn(MOCK_TNT_ID); + when(responseParser.getEdgeHost(any())).thenReturn(MOCK_EDGE_HOST); + when(responseParser.extractBatchedMBoxes(any())) + .thenReturn( + new HashMap() { + { + put("mbox0", validMboxResponse); + } + }); + when(responseParser.extractMboxContent(eq(validMboxResponse))) + .thenReturn("mbox0content"); + when(responseParser.getResponseTokens(eq(validMboxResponse))) + .thenReturn(responseTokens); + when(responseParser.extractClickMetricAnalyticsPayload(eq(validMboxResponse))) + .thenReturn(clickMetricA4TParams); + when(responseParser.getAnalyticsForTargetPayload(any())).thenReturn(a4tParams); + when(connecting.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); + + extension = + new TargetExtension( + mockExtensionApi, + targetState, + targetPreviewManager, + requestBuilder, + responseParser); + testRunnable.run(); + } catch (JSONException e) { + throw new RuntimeException(e); + } } @After - public void teardown() { + public void tearDown() { + reset(mockServiceProvider); + reset(networkService); + reset(deviceInforming); + reset(dataStoring); + reset(uiService); + reset(uriService); + reset(appContextService); + reset(context); + reset(mockExtensionApi); + reset(requestBuilder); + reset(responseParser); + reset(targetPreviewManager); + reset(targetState); + reset(connecting); + reset(datastore); } @Test public void test_getName() { - // test - final String extensionName = extension.getName(); - assertEquals("getName should return the correct extension name.", "com.adobe.module.target", extensionName); + runWithMockedServiceProvider( + () -> { + // test + final String extensionName = extension.getName(); + assertEquals( + "getName should return the correct extension name.", + "com.adobe.module.target", + extensionName); + }); } @Test public void test_getFriendlyName() { - // test - final String extensionName = extension.getFriendlyName(); - assertEquals("getFriendlyName should return the correct extension friendly name.", "Target", extensionName); + runWithMockedServiceProvider( + () -> { + // test + final String extensionName = extension.getFriendlyName(); + assertEquals( + "getFriendlyName should return the correct extension friendly name.", + "Target", + extensionName); + }); } @Test public void test_getVersion() { - // test - final String extensionVersion = extension.getVersion(); - assertEquals("getVersion should return the correct extension version.", "2.0.3", extensionVersion); + runWithMockedServiceProvider( + () -> { + // test + final String extensionVersion = extension.getVersion(); + assertEquals( + "getVersion should return the correct extension version.", + Target.EXTENSION_VERSION, + extensionVersion); + }); } - //********************************************************************************************** + // ********************************************************************************************** // Constructor - //********************************************************************************************** + // ********************************************************************************************** @Test public void test_Constructor() { @@ -260,1058 +354,1556 @@ public void test_Constructor() { new TargetExtension(mockExtensionApi); } - //********************************************************************************************** + // ********************************************************************************************** // onRegister Tests - //********************************************************************************************** + // ********************************************************************************************** @Test public void test_onRegister() { - // test - extension.onRegistered(); + runWithMockedServiceProvider( + () -> { + // test + extension.onRegistered(); - // verify that five listeners are registered - verify(mockExtensionApi, times(5)).registerEventListener(any(), any(), any()); + // verify that five listeners are registered + verify(mockExtensionApi, times(5)).registerEventListener(any(), any(), any()); + }); } - //********************************************************************************************** + // ********************************************************************************************** // readyForEvent tests - //********************************************************************************************** + // ********************************************************************************************** @Test public void test_readyForEvent() { - // setup - setConfigurationSharedState(MOCKED_CLIENT_CODE, 5, "optedin", false, "targetserver"); + runWithMockedServiceProvider( + () -> { + // setup + setConfigurationSharedState( + MOCKED_CLIENT_CODE, 5, "optedin", false, "targetserver"); - // test - extension.readyForEvent(noEventDataEvent()); + // test + extension.readyForEvent(noEventDataEvent()); - // verify target state is not updated with correct configuration - verify(targetState).updateConfigurationSharedState(notNull()); + // verify target state is not updated with correct configuration + verify(targetState).updateConfigurationSharedState(notNull()); + }); } @Test public void test_readyForEvent_whenConfigurationIsNotSet() { - // test - extension.readyForEvent(noEventDataEvent()); + runWithMockedServiceProvider( + () -> { + // test + extension.readyForEvent(noEventDataEvent()); - // verify that the target state is not updated with latest configuration - verify(targetState).updateConfigurationSharedState(null); + // verify that the target state is not updated with latest configuration + verify(targetState).updateConfigurationSharedState(null); + }); } @Test public void test_readyForEvent_returnsTrueWhenConfigurationIsSet() { - // setup - setConfigurationSharedState(MOCKED_CLIENT_CODE, 5, "optedin", false, "targetServer"); - extension = new TargetExtension(mockExtensionApi, deviceInforming, networkService, uiService, new TargetState(datastore), targetPreviewManager, requestBuilder, responseParser); - - // test - assertTrue(extension.readyForEvent(noEventDataEvent())); + runWithMockedServiceProvider( + () -> { + // setup + setConfigurationSharedState( + MOCKED_CLIENT_CODE, 5, "optedin", false, "targetServer"); + extension = + new TargetExtension( + mockExtensionApi, + targetState, + targetPreviewManager, + requestBuilder, + responseParser); + + // test + assertTrue(extension.readyForEvent(noEventDataEvent())); + }); } - //********************************************************************************************** + // ********************************************************************************************** // LoadRequests tests - //********************************************************************************************** + // ********************************************************************************************** @Test public void testLoadRequests_NoRequest_When_OptOut() { - // setup - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.OPT_OUT); - final Event event = loadRequestEvent(getTargetRequestList(1), null); - - // test - extension.handleTargetRequestContentEvent(event); - - // verify - verifyNoInteractions(networkService); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getMobilePrivacyStatus()) + .thenReturn(MobilePrivacyStatus.OPT_OUT); + final Event event = loadRequestEvent(getTargetRequestList(1), null); + + // test + extension.handleTargetRequestContentEvent(event); + + // verify + verifyNoInteractions(networkService); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + }); } @Test public void testLoadRequests_NoRequest_When_ClientCodeIsEmpty() { - // setup - when(targetState.getClientCode()).thenReturn(""); - final Event event = loadRequestEvent(getTargetRequestList(1), null); - - // test - extension.handleTargetRequestContentEvent(event); - - // verify - verifyNoInteractions(networkService); - verifyNoInteractions(requestBuilder); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getClientCode()).thenReturn(""); + final Event event = loadRequestEvent(getTargetRequestList(1), null); + + // test + extension.handleTargetRequestContentEvent(event); + + // verify + verifyNoInteractions(networkService); + verifyNoInteractions(requestBuilder); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + }); } @Test public void testLoadRequests_NoRequest_When_TargetRequestListIsEmpty() { - // setup - final Event event = loadRequestEvent(getTargetRequestList(0), null); + runWithMockedServiceProvider( + () -> { + // setup + final Event event = loadRequestEvent(getTargetRequestList(0), null); - // test - extension.handleTargetRequestContentEvent(event); + // test + extension.handleTargetRequestContentEvent(event); - // verify - verifyNoInteractions(networkService); - verifyNoInteractions(requestBuilder); + // verify + verifyNoInteractions(networkService); + verifyNoInteractions(requestBuilder); + }); } @Test public void testLoadRequests_NoRequest_When_NetworkServiceIsNotAvailable() { - // setup - extension = new TargetExtension(mockExtensionApi, deviceInforming, null, uiService, targetState, targetPreviewManager, requestBuilder, responseParser); - final Event event = loadRequestEvent(getTargetRequestList(1), null); - - // test - extension.handleTargetRequestContentEvent(event); - - // verify - verifyNoInteractions(networkService); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + runWithMockedServiceProvider( + () -> { + // setup + when(mockServiceProvider.getNetworkService()).thenReturn(null); + extension = + new TargetExtension( + mockExtensionApi, + targetState, + targetPreviewManager, + requestBuilder, + responseParser); + final Event event = loadRequestEvent(getTargetRequestList(1), null); + + // test + extension.handleTargetRequestContentEvent(event); + + // verify + verifyNoInteractions(networkService); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + }); } @Test public void testLoadRequests_NoRequest_When_EventWithNoData() { - // test - extension.handleTargetRequestContentEvent(noEventDataEvent()); - - // verify - verifyNoInteractions(networkService); - verifyNoInteractions(requestBuilder); + runWithMockedServiceProvider( + () -> { + // test + extension.handleTargetRequestContentEvent(noEventDataEvent()); + + // verify + verifyNoInteractions(networkService); + verifyNoInteractions(requestBuilder); + }); } @Test public void testLoadRequests_when_invalidLoadRequestEventData() { - // test - extension.handleTargetRequestContentEvent(noEventDataEvent()); - - // verify - verifyNoInteractions(networkService); - verifyNoInteractions(requestBuilder); + runWithMockedServiceProvider( + () -> { + // test + extension.handleTargetRequestContentEvent(noEventDataEvent()); + + // verify + verifyNoInteractions(networkService); + verifyNoInteractions(requestBuilder); + }); } @Test - public void testLoadRequests_whenEmptyJSONObject() throws Exception { - final Event event = loadRequestEvent(getTargetRequestList(1), null); - when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any(), any(), any())).thenReturn(new JSONObject("{}")); - - // test - extension.handleTargetRequestContentEvent(event); + public void testLoadRequests_whenEmptyJSONObject() { + runWithMockedServiceProvider( + () -> { + final Event event = loadRequestEvent(getTargetRequestList(1), null); + try { + when(requestBuilder.getRequestPayload( + any(), any(), any(), any(), any(), any(), any())) + .thenReturn(new JSONObject("{}")); + } catch (JSONException e) { + throw new RuntimeException(e); + } - // verify - verifyNoInteractions(networkService); - verify(requestBuilder).getRequestPayload(eq(null), anyList(), eq(null), anyList(), eq(""), eq(null), eq(null)); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + // test + extension.handleTargetRequestContentEvent(event); + + // verify + verifyNoInteractions(networkService); + verify(requestBuilder) + .getRequestPayload( + eq(null), anyList(), eq(null), anyList(), eq(""), eq(null), + eq(null)); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + }); } @Test public void testLoadRequests_attachesLifecycleAndIdentityData() { - // setup - setLifecycleSharedState(); - setIdentitySharedState(); - - // test - final Event event = loadRequestEvent(getTargetRequestList(1), null); - extension.handleTargetRequestContentEvent(event); - - // verify - verify(requestBuilder).getRequestPayload(eq(null), anyList(), eq(null), anyList(), eq(""), eq(identitySharedState), eq(lifecycleSharedState)); - } - - @Test - public void testLoadRequests_makesCorrectNetworkRequest() throws Exception { - setEventHubSharedState(); - final JSONObject jsonObject = new JSONObject("{\n" + - "\"name\": \"mbox1\",\n" + - "\"options\": [{\"eventToken\":\"displayEventToken\"}]\n" + - "}\n"); - when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any(), any(), any())).thenReturn(jsonObject); - - // test - final Event event = loadRequestEvent(getTargetRequestList(1), null); - extension.handleTargetRequestContentEvent(event); - - // verify - verify(networkService).connectAsync(networkRequestCaptor.capture(), networkCallbackCaptor.capture()); - assertEquals("https://" + MOCKED_TARGET_SERVER + "/rest/v1/delivery/?client=" + MOCKED_CLIENT_CODE + "&sessionId=" + MOCK_SESSION_ID, networkRequestCaptor.getValue().getUrl()); - assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); - final Map headers = networkRequestCaptor.getValue().getHeaders(); - assertEquals(3, headers.size()); - assertEquals("application/json", headers.get("Content-Type")); - assertEquals("AdobeTargetMobile-Android", headers.get("X-EXC-SDK")); - assertEquals(String.format("%s+%s", "x.y.z", extension.getVersion()), headers.get("X-EXC-SDK-Version")); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getReadTimeout(), 0); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getConnectTimeout(), 0); - } - - @Test - public void testLoadRequests_makesNetworkRequest_wrapperInfoAvailable() throws Exception { - final Map eventHubState = new HashMap() { - { - put("version", "x.y.z"); - put("wrapper", new HashMap() { - { - put("friendlyName", "Flutter"); - put("type", "F"); + runWithMockedServiceProvider( + () -> { + // setup + setLifecycleSharedState(); + setIdentitySharedState(); + + // test + final Event event = loadRequestEvent(getTargetRequestList(1), null); + extension.handleTargetRequestContentEvent(event); + + // verify + verify(requestBuilder) + .getRequestPayload( + eq(null), + anyList(), + eq(null), + anyList(), + eq(""), + eq(identitySharedState), + eq(lifecycleSharedState)); + }); + } + + @Test + public void testLoadRequests_makesCorrectNetworkRequest() { + runWithMockedServiceProvider( + () -> { + setEventHubSharedState(); + final JSONObject jsonObject; + try { + jsonObject = + new JSONObject( + "{\n" + + "\"name\": \"mbox1\",\n" + + "\"options\":" + + " [{\"eventToken\":\"displayEventToken\"}]\n" + + "}\n"); + } catch (JSONException e) { + throw new RuntimeException(e); } + when(requestBuilder.getRequestPayload( + any(), any(), any(), any(), any(), any(), any())) + .thenReturn(jsonObject); + + // test + final Event event = loadRequestEvent(getTargetRequestList(1), null); + extension.handleTargetRequestContentEvent(event); + + // verify + verify(networkService) + .connectAsync( + networkRequestCaptor.capture(), + networkCallbackCaptor.capture()); + assertEquals( + "https://" + + MOCKED_TARGET_SERVER + + "/rest/v1/delivery/?client=" + + MOCKED_CLIENT_CODE + + "&sessionId=" + + MOCK_SESSION_ID, + networkRequestCaptor.getValue().getUrl()); + assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); + final Map headers = + networkRequestCaptor.getValue().getHeaders(); + assertEquals(3, headers.size()); + assertEquals("application/json", headers.get("Content-Type")); + assertEquals("AdobeTargetMobile-Android", headers.get("X-EXC-SDK")); + assertEquals( + String.format("%s+%s", "x.y.z", extension.getVersion()), + headers.get("X-EXC-SDK-Version")); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getReadTimeout(), + 0); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getConnectTimeout(), + 0); }); - } - }; - setEventHubSharedState(eventHubState); - final JSONObject jsonObject = new JSONObject("{\n" + - "\"name\": \"mbox1\",\n" + - "\"options\": [{\"eventToken\":\"displayEventToken\"}]\n" + - "}\n"); - when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any(), any(), any())).thenReturn(jsonObject); - - // test - final Event event = loadRequestEvent(getTargetRequestList(1), null); - extension.handleTargetRequestContentEvent(event); - - // verify - verify(networkService).connectAsync(networkRequestCaptor.capture(), networkCallbackCaptor.capture()); - assertEquals("https://" + MOCKED_TARGET_SERVER + "/rest/v1/delivery/?client=" + MOCKED_CLIENT_CODE + "&sessionId=" + MOCK_SESSION_ID, networkRequestCaptor.getValue().getUrl()); - assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); - final Map headers = networkRequestCaptor.getValue().getHeaders(); - assertEquals(3, headers.size()); - assertEquals("application/json", headers.get("Content-Type")); - assertEquals("AdobeTargetMobile-Android-Flutter", headers.get("X-EXC-SDK")); - assertEquals(String.format("%s+%s", "x.y.z", extension.getVersion()), headers.get("X-EXC-SDK-Version")); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getReadTimeout(), 0); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getConnectTimeout(), 0); - } - - @Test - public void testLoadRequests_makesNetworkRequest_eventHubSharedStateNotAvailable() throws Exception { - setEventHubSharedState(null); - final JSONObject jsonObject = new JSONObject("{\n" + - "\"name\": \"mbox1\",\n" + - "\"options\": [{\"eventToken\":\"displayEventToken\"}]\n" + - "}\n"); - when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any(), any(), any())).thenReturn(jsonObject); - - // test - final Event event = loadRequestEvent(getTargetRequestList(1), null); - extension.handleTargetRequestContentEvent(event); - - // verify - verify(networkService).connectAsync(networkRequestCaptor.capture(), networkCallbackCaptor.capture()); - assertEquals("https://" + MOCKED_TARGET_SERVER + "/rest/v1/delivery/?client=" + MOCKED_CLIENT_CODE + "&sessionId=" + MOCK_SESSION_ID, networkRequestCaptor.getValue().getUrl()); - assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); - final Map headers = networkRequestCaptor.getValue().getHeaders(); - assertEquals(3, headers.size()); - assertEquals("application/json", headers.get("Content-Type")); - assertEquals("AdobeTargetMobile-Android", headers.get("X-EXC-SDK")); - assertEquals("", headers.get("X-EXC-SDK-Version")); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getReadTimeout(), 0); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getConnectTimeout(), 0); } @Test - public void testLoadRequests_withTargetEdgeHost() { - when(targetState.getTargetServer()).thenReturn(""); - when(targetState.getEdgeHost()).thenReturn(MOCK_EDGE_HOST); + public void testLoadRequests_makesNetworkRequest_wrapperInfoAvailable() { + runWithMockedServiceProvider( + () -> { + final Map eventHubState = + new HashMap() { + { + put("version", "x.y.z"); + put( + "wrapper", + new HashMap() { + { + put("friendlyName", "Flutter"); + put("type", "F"); + } + }); + } + }; + setEventHubSharedState(eventHubState); + final JSONObject jsonObject; + try { + jsonObject = + new JSONObject( + "{\n" + + "\"name\": \"mbox1\",\n" + + "\"options\":" + + " [{\"eventToken\":\"displayEventToken\"}]\n" + + "}\n"); + } catch (JSONException e) { + throw new RuntimeException(e); + } + when(requestBuilder.getRequestPayload( + any(), any(), any(), any(), any(), any(), any())) + .thenReturn(jsonObject); + + // test + final Event event = loadRequestEvent(getTargetRequestList(1), null); + extension.handleTargetRequestContentEvent(event); + + // verify + verify(networkService) + .connectAsync( + networkRequestCaptor.capture(), + networkCallbackCaptor.capture()); + assertEquals( + "https://" + + MOCKED_TARGET_SERVER + + "/rest/v1/delivery/?client=" + + MOCKED_CLIENT_CODE + + "&sessionId=" + + MOCK_SESSION_ID, + networkRequestCaptor.getValue().getUrl()); + assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); + final Map headers = + networkRequestCaptor.getValue().getHeaders(); + assertEquals(3, headers.size()); + assertEquals("application/json", headers.get("Content-Type")); + assertEquals("AdobeTargetMobile-Android-Flutter", headers.get("X-EXC-SDK")); + assertEquals( + String.format("%s+%s", "x.y.z", extension.getVersion()), + headers.get("X-EXC-SDK-Version")); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getReadTimeout(), + 0); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getConnectTimeout(), + 0); + }); + } - // test - final Event event = loadRequestEvent(getTargetRequestList(1), null); - extension.handleTargetRequestContentEvent(event); + @Test + public void testLoadRequests_makesNetworkRequest_eventHubSharedStateNotAvailable() { + runWithMockedServiceProvider( + () -> { + setEventHubSharedState(null); + final JSONObject jsonObject; + try { + jsonObject = + new JSONObject( + "{\n" + + "\"name\": \"mbox1\",\n" + + "\"options\":" + + " [{\"eventToken\":\"displayEventToken\"}]\n" + + "}\n"); + } catch (JSONException e) { + throw new RuntimeException(e); + } + when(requestBuilder.getRequestPayload( + any(), any(), any(), any(), any(), any(), any())) + .thenReturn(jsonObject); + + // test + final Event event = loadRequestEvent(getTargetRequestList(1), null); + extension.handleTargetRequestContentEvent(event); + + // verify + verify(networkService) + .connectAsync( + networkRequestCaptor.capture(), + networkCallbackCaptor.capture()); + assertEquals( + "https://" + + MOCKED_TARGET_SERVER + + "/rest/v1/delivery/?client=" + + MOCKED_CLIENT_CODE + + "&sessionId=" + + MOCK_SESSION_ID, + networkRequestCaptor.getValue().getUrl()); + assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); + final Map headers = + networkRequestCaptor.getValue().getHeaders(); + assertEquals(3, headers.size()); + assertEquals("application/json", headers.get("Content-Type")); + assertEquals("AdobeTargetMobile-Android", headers.get("X-EXC-SDK")); + assertEquals("", headers.get("X-EXC-SDK-Version")); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getReadTimeout(), + 0); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getConnectTimeout(), + 0); + }); + } - // verify - verify(networkService).connectAsync(networkRequestCaptor.capture(), any()); - assertEquals("https://" + MOCK_EDGE_HOST + "/rest/v1/delivery/?client=" + MOCKED_CLIENT_CODE + "&sessionId=" + MOCK_SESSION_ID, networkRequestCaptor.getValue().getUrl()); + @Test + public void testLoadRequests_withTargetEdgeHost() { + runWithMockedServiceProvider( + () -> { + when(targetState.getTargetServer()).thenReturn(""); + when(targetState.getEdgeHost()).thenReturn(MOCK_EDGE_HOST); + + // test + final Event event = loadRequestEvent(getTargetRequestList(1), null); + extension.handleTargetRequestContentEvent(event); + + // verify + verify(networkService, times(1)) + .connectAsync(networkRequestCaptor.capture(), any()); + assertEquals( + "https://" + + MOCK_EDGE_HOST + + "/rest/v1/delivery/?client=" + + MOCKED_CLIENT_CODE + + "&sessionId=" + + MOCK_SESSION_ID, + networkRequestCaptor.getValue().getUrl()); + }); } @Test public void testLoadRequests_ResponseNotProcessed_When_ConnectionIsNull() { - // test - final Event event = loadRequestEvent(getTargetRequestList(1), null); - extension.handleTargetRequestContentEvent(event); - - // verify - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - - // test - networkCallbackCaptor.getValue().call(null); - - // verify the dispatched response event - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + runWithMockedServiceProvider( + () -> { + // test + final Event event = loadRequestEvent(getTargetRequestList(1), null); + extension.handleTargetRequestContentEvent(event); + + // verify + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + + // test + networkCallbackCaptor.getValue().call(null); + + // verify the dispatched response event + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + }); } @Test public void testLoadRequests_ReturnDefaultContent_When_ResponseJsonIsNull() { - // setup - when(responseParser.parseResponseToJson(any())).thenReturn(null); - - // test - final Event event = loadRequestEvent(getTargetRequestList(1), null); - extension.handleTargetRequestContentEvent(event); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify default response event dispatched - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + runWithMockedServiceProvider( + () -> { + // setup + when(responseParser.parseResponseToJson(any())).thenReturn(null); + + // test + final Event event = loadRequestEvent(getTargetRequestList(1), null); + extension.handleTargetRequestContentEvent(event); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify default response event dispatched + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + }); } @Test public void testLoadRequests_ReturnDefaultContent_When_ResponseNot200OK() { - // setup - when(connecting.getResponseCode()).thenReturn(HttpURLConnection.HTTP_BAD_REQUEST); - - // test - final Event event = loadRequestEvent(getTargetRequestList(1), null); - extension.handleTargetRequestContentEvent(event); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify default response event dispatched - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + runWithMockedServiceProvider( + () -> { + // setup + when(connecting.getResponseCode()) + .thenReturn(HttpURLConnection.HTTP_BAD_REQUEST); + + // test + final Event event = loadRequestEvent(getTargetRequestList(1), null); + extension.handleTargetRequestContentEvent(event); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify default response event dispatched + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + }); } @Test public void testLoadRequests_ReturnDefaultContent_When_ResponseError() { - // setup - when(responseParser.getErrorMessage(any())).thenReturn("anyError"); - - // test - final Event event = loadRequestEvent(getTargetRequestList(1), null); - extension.handleTargetRequestContentEvent(event); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify default response event dispatched - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); - } - - @Test - public void testLoadRequests_whenValidResponse() throws Exception { - // setup - final JSONObject validMboxResponse = new JSONObject("{\"options\": [{\"content\": \"mbox0content\", \"type\": \"html\"}]}"); - when(responseParser.parseResponseToJson(any())).thenReturn(validJSONObject()); - when(responseParser.getTntId(any())).thenReturn(MOCK_TNT_ID_1); - when(responseParser.getEdgeHost(any())).thenReturn(MOCK_EDGE_HOST); - when(responseParser.extractBatchedMBoxes(any())).thenReturn(new HashMap() { - { - put("mbox0", validMboxResponse); - } - }); - when(responseParser.extractMboxContent(eq(validMboxResponse))).thenReturn("mbox0content"); - when(responseParser.extractMboxContent(eq(validMboxResponse))).thenReturn("mbox0content"); - when(responseParser.getResponseTokens(eq(validMboxResponse))).thenReturn(responseTokens); - when(responseParser.extractClickMetricAnalyticsPayload(eq(validMboxResponse))).thenReturn(clickMetricA4TParams); - when(responseParser.getAnalyticsForTargetPayload(eq(validMboxResponse))).thenReturn(a4tParams); - when(responseParser.getAnalyticsForTargetPayload(any(), any())).thenReturn(a4tParams); - - // test - Event event = loadRequestEvent(getTargetRequestList(1), null); - extension.handleTargetRequestContentEvent(event); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify the target state are correctly set from response - verify(targetState).clearNotifications(); - verify(targetState).updateSessionTimestamp(eq(false)); - verify(targetState).updateEdgeHost(MOCK_EDGE_HOST); - verify(targetState).updateTntId(MOCK_TNT_ID_1); - verify(mockExtensionApi).createSharedState(eq(targetSharedState), eq(event)); - verify(mockExtensionApi, times(2)).dispatch(eventArgumentCaptor.capture()); - Event a4tEvent = eventArgumentCaptor.getAllValues().get(0); - Event mboxContentEvent = eventArgumentCaptor.getAllValues().get(1); - - // verify the a4t event - assertEquals(EventType.ANALYTICS, a4tEvent.getType()); - assertEquals(EventSource.REQUEST_CONTENT, a4tEvent.getSource()); - assertEquals(true, a4tEvent.getEventData().get("trackinternal")); - assertEquals("AnalyticsForTarget", a4tEvent.getEventData().get("action")); - assertEquals(a4tParams, a4tEvent.getEventData().get("contextdata")); - - // verify the dispatched mbox content event - assertEquals("mbox0content", extractMboxContentFromEvent(mboxContentEvent)); - final Map responseTokens = extractResponseToken(mboxContentEvent); - assertEquals(3, responseTokens.size()); - assertEquals("responseTokens.Value", responseTokens.get("responseTokens.Key")); - assertEquals(new ArrayList(Collections.singletonList("books")), responseTokens.get("profile.categoryAffinities")); - final List someList = (List)responseTokens.get("someKey"); - assertEquals(3, someList.size()); - assertEquals("someValue", someList.get(0)); - assertTrue((Boolean)someList.get(1)); - assertEquals(42, (int)someList.get(2)); - assertEquals(a4tParams, extractAnalyticsPayload(mboxContentEvent)); - assertEquals(clickMetricA4TParams, extractClickMetric(mboxContentEvent)); + runWithMockedServiceProvider( + () -> { + // setup + when(responseParser.getErrorMessage(any())).thenReturn("anyError"); + + // test + final Event event = loadRequestEvent(getTargetRequestList(1), null); + extension.handleTargetRequestContentEvent(event); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify default response event dispatched + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + }); } @Test - public void testLoadRequests_ReturnDefaultContent_When_ResponseJsonNotContainMbox() { - // setup - when(responseParser.extractMboxContent(any())).thenReturn(null); - - // test - extension.handleTargetRequestContentEvent(loadRequestEvent(getTargetRequestList(1), null)); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); + public void testLoadRequests_whenValidResponse() { + runWithMockedServiceProvider( + () -> { + try { + // setup + final JSONObject validMboxResponse = + new JSONObject( + "{\"options\": [{\"content\": \"mbox0content\", \"type\":" + + " \"html\"}]}"); + when(responseParser.parseResponseToJson(any())) + .thenReturn(validJSONObject()); + when(responseParser.getTntId(any())).thenReturn(MOCK_TNT_ID_1); + when(responseParser.getEdgeHost(any())).thenReturn(MOCK_EDGE_HOST); + when(responseParser.extractBatchedMBoxes(any())) + .thenReturn( + new HashMap() { + { + put("mbox0", validMboxResponse); + } + }); + when(responseParser.extractMboxContent(eq(validMboxResponse))) + .thenReturn("mbox0content"); + when(responseParser.extractMboxContent(eq(validMboxResponse))) + .thenReturn("mbox0content"); + when(responseParser.getResponseTokens(eq(validMboxResponse))) + .thenReturn(responseTokens); + when(responseParser.extractClickMetricAnalyticsPayload( + eq(validMboxResponse))) + .thenReturn(clickMetricA4TParams); + when(responseParser.getAnalyticsForTargetPayload(eq(validMboxResponse))) + .thenReturn(a4tParams); + when(responseParser.getAnalyticsForTargetPayload(any(), any())) + .thenReturn(a4tParams); + + // test + Event event = loadRequestEvent(getTargetRequestList(1), null); + extension.handleTargetRequestContentEvent(event); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify the target state are correctly set from response + verify(targetState).clearNotifications(); + verify(targetState).updateSessionTimestamp(eq(false)); + verify(targetState).updateEdgeHost(MOCK_EDGE_HOST); + verify(targetState).updateTntId(MOCK_TNT_ID_1); + verify(mockExtensionApi) + .createSharedState(eq(targetSharedState), eq(event)); + verify(mockExtensionApi, times(2)).dispatch(eventArgumentCaptor.capture()); + Event a4tEvent = eventArgumentCaptor.getAllValues().get(0); + Event mboxContentEvent = eventArgumentCaptor.getAllValues().get(1); + + // verify the a4t event + assertEquals(EventType.ANALYTICS, a4tEvent.getType()); + assertEquals(EventSource.REQUEST_CONTENT, a4tEvent.getSource()); + assertEquals(true, a4tEvent.getEventData().get("trackinternal")); + assertEquals("AnalyticsForTarget", a4tEvent.getEventData().get("action")); + assertEquals(a4tParams, a4tEvent.getEventData().get("contextdata")); + + // verify the dispatched mbox content event + assertEquals("mbox0content", extractMboxContentFromEvent(mboxContentEvent)); + final Map responseTokens = + extractResponseToken(mboxContentEvent); + assertEquals(3, responseTokens.size()); + assertEquals( + "responseTokens.Value", responseTokens.get("responseTokens.Key")); + assertEquals( + new ArrayList(Collections.singletonList("books")), + responseTokens.get("profile.categoryAffinities")); + final List someList = (List) responseTokens.get("someKey"); + assertEquals(3, someList.size()); + assertEquals("someValue", someList.get(0)); + assertTrue((Boolean) someList.get(1)); + assertEquals(42, (int) someList.get(2)); + assertEquals(a4tParams, extractAnalyticsPayload(mboxContentEvent)); + assertEquals(clickMetricA4TParams, extractClickMetric(mboxContentEvent)); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }); + } - // verify default response event dispatched - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + @Test + public void testLoadRequests_ReturnDefaultContent_When_ResponseJsonNotContainMbox() { + runWithMockedServiceProvider( + () -> { + // setup + when(responseParser.extractMboxContent(any())).thenReturn(null); + + // test + extension.handleTargetRequestContentEvent( + loadRequestEvent(getTargetRequestList(1), null)); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify default response event dispatched + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + }); } @Test - public void testLoadRequests_ReturnDefaultContent_When_ResponseJsonContainMboxWithEmptyContent() { - // setup - when(responseParser.extractMboxContent(any())).thenReturn(""); + public void + testLoadRequests_ReturnDefaultContent_When_ResponseJsonContainMboxWithEmptyContent() { + runWithMockedServiceProvider( + () -> { + // setup + when(responseParser.extractMboxContent(any())).thenReturn(""); - // test - extension.handleTargetRequestContentEvent(loadRequestEvent(getTargetRequestList(1), null)); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); + // test + extension.handleTargetRequestContentEvent( + loadRequestEvent(getTargetRequestList(1), null)); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); - // verify default response event dispatched - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + // verify default response event dispatched + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "default", extractMboxContentFromEvent(eventArgumentCaptor.getValue())); + }); } @Test - public void testLoadRequests_NotSendAnalyticsRequest_When_ResponseJsonDoesNotContainA4TPayload() { - // setup - when(responseParser.getAnalyticsForTargetPayload(any(), any())).thenReturn(null); + public void + testLoadRequests_NotSendAnalyticsRequest_When_ResponseJsonDoesNotContainA4TPayload() { + runWithMockedServiceProvider( + () -> { + // setup + when(responseParser.getAnalyticsForTargetPayload(any(), any())) + .thenReturn(null); - // test - extension.handleTargetRequestContentEvent(loadRequestEvent(getTargetRequestList(1), null)); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); + // test + extension.handleTargetRequestContentEvent( + loadRequestEvent(getTargetRequestList(1), null)); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); - // verify only target response event is dispatched - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals(EventType.TARGET, eventArgumentCaptor.getValue().getType()); + // verify only target response event is dispatched + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals(EventType.TARGET, eventArgumentCaptor.getValue().getType()); + }); } @Test - public void testLoadRequests_SetTntIdAndEdgeHostToNull_When_ResponseJsonNotContainTntIdAndEdgeHost() { - // setup - when(responseParser.getEdgeHost(any())).thenReturn(null); - when(responseParser.getTntId(any())).thenReturn(null); + public void + testLoadRequests_SetTntIdAndEdgeHostToNull_When_ResponseJsonNotContainTntIdAndEdgeHost() { + runWithMockedServiceProvider( + () -> { + // setup + when(responseParser.getEdgeHost(any())).thenReturn(null); + when(responseParser.getTntId(any())).thenReturn(null); - // test - extension.handleTargetRequestContentEvent(loadRequestEvent(getTargetRequestList(1), null)); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); + // test + extension.handleTargetRequestContentEvent( + loadRequestEvent(getTargetRequestList(1), null)); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); - // verify - verify(targetState).updateTntId(null); - verify(targetState, times(2)).updateEdgeHost(null); + // verify + verify(targetState).updateTntId(null); + verify(targetState, times(2)).updateEdgeHost(null); + }); } - //********************************************************************************************** + // ********************************************************************************************** // setThirdPartyId - //********************************************************************************************** + // ********************************************************************************************** @Test public void testSetThirdPartyId_validInput() { - // setup - when(targetState.getThirdPartyId()).thenReturn(null); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getThirdPartyId()).thenReturn(null); - // test - extension.handleTargetRequestIdentityEvent(setThirdPartyIdEvent(MOCK_THIRD_PARTY_ID)); + // test + extension.handleTargetRequestIdentityEvent( + setThirdPartyIdEvent(MOCK_THIRD_PARTY_ID)); - // validate - verify(targetState).updateThirdPartyId(MOCK_THIRD_PARTY_ID); + // validate + verify(targetState).updateThirdPartyId(MOCK_THIRD_PARTY_ID); + }); } @Test public void testSetThirdPartyId_NullInput() { - // setup - when(targetState.getThirdPartyId()).thenReturn(MOCK_THIRD_PARTY_ID); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getThirdPartyId()).thenReturn(MOCK_THIRD_PARTY_ID); - // test - extension.handleTargetRequestIdentityEvent(setThirdPartyIdEvent(null)); + // test + extension.handleTargetRequestIdentityEvent(setThirdPartyIdEvent(null)); - // validate - verify(targetState).updateThirdPartyId(null); + // validate + verify(targetState).updateThirdPartyId(null); + }); } @Test public void testSetThirdPartyId_NewID() { - // setup - when(targetState.getThirdPartyId()).thenReturn(MOCK_THIRD_PARTY_ID); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getThirdPartyId()).thenReturn(MOCK_THIRD_PARTY_ID); - // test - extension.handleTargetRequestIdentityEvent(setThirdPartyIdEvent(MOCK_THIRD_PARTY_ID_1)); + // test + extension.handleTargetRequestIdentityEvent( + setThirdPartyIdEvent(MOCK_THIRD_PARTY_ID_1)); - // validate - verify(targetState).updateThirdPartyId(MOCK_THIRD_PARTY_ID_1); + // validate + verify(targetState).updateThirdPartyId(MOCK_THIRD_PARTY_ID_1); + }); } @Test public void testSetThirdPartyId_sameID_Then_NoOp() { - // setup - when(targetState.getThirdPartyId()).thenReturn(MOCK_THIRD_PARTY_ID); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getThirdPartyId()).thenReturn(MOCK_THIRD_PARTY_ID); - // test - extension.handleTargetRequestIdentityEvent(setThirdPartyIdEvent(MOCK_THIRD_PARTY_ID)); + // test + extension.handleTargetRequestIdentityEvent( + setThirdPartyIdEvent(MOCK_THIRD_PARTY_ID)); - // validate - verify(targetState, times(0)).updateThirdPartyId(any()); + // validate + verify(targetState, times(0)).updateThirdPartyId(any()); + }); } @Test public void testSetThirdPartyId_Creates_SharedState_Privacy_OptIn() { - // set privacy status optedIn - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.OPT_IN); - - // test - final Event event = setThirdPartyIdEvent(MOCK_THIRD_PARTY_ID); - extension.handleTargetRequestIdentityEvent(event); - - // validate - verify(mockExtensionApi).createSharedState(targetSharedState, event); + runWithMockedServiceProvider( + () -> { + // set privacy status optedIn + when(targetState.getMobilePrivacyStatus()) + .thenReturn(MobilePrivacyStatus.OPT_IN); + + // test + final Event event = setThirdPartyIdEvent(MOCK_THIRD_PARTY_ID); + extension.handleTargetRequestIdentityEvent(event); + + // validate + verify(mockExtensionApi).createSharedState(targetSharedState, event); + }); } @Test public void testSetThirdPartyId_Creates_SharedState_Privacy_OptUnknown() { - // set privacy status optUnknown - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.UNKNOWN); - - // test - final Event event = setThirdPartyIdEvent(MOCK_THIRD_PARTY_ID); - extension.handleTargetRequestIdentityEvent(event); - - // validate - verify(mockExtensionApi).createSharedState(targetSharedState, event); + runWithMockedServiceProvider( + () -> { + // set privacy status optUnknown + when(targetState.getMobilePrivacyStatus()) + .thenReturn(MobilePrivacyStatus.UNKNOWN); + + // test + final Event event = setThirdPartyIdEvent(MOCK_THIRD_PARTY_ID); + extension.handleTargetRequestIdentityEvent(event); + + // validate + verify(mockExtensionApi).createSharedState(targetSharedState, event); + }); } @Test public void testSetThirdPartyId_On_Privacy_OptOut() { - // set privacy status optedOut - final HashMap emptySharedState = new HashMap(); - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.OPT_OUT); - when(targetState.generateSharedState()).thenReturn(emptySharedState); - - // test - final Event event = setThirdPartyIdEvent(MOCK_THIRD_PARTY_ID); - extension.handleTargetRequestIdentityEvent(event); - - // validate that the shared state is updated with empty map and the third party Id is not set - verify(mockExtensionApi).createSharedState(emptySharedState, event); - verify(targetState, times(0)).updateThirdPartyId(any()); + runWithMockedServiceProvider( + () -> { + // set privacy status optedOut + final HashMap emptySharedState = new HashMap(); + when(targetState.getMobilePrivacyStatus()) + .thenReturn(MobilePrivacyStatus.OPT_OUT); + when(targetState.generateSharedState()).thenReturn(emptySharedState); + + // test + final Event event = setThirdPartyIdEvent(MOCK_THIRD_PARTY_ID); + extension.handleTargetRequestIdentityEvent(event); + + // validate that the shared state is updated with empty map and the third party + // Id is not set + verify(mockExtensionApi).createSharedState(emptySharedState, event); + verify(targetState, times(0)).updateThirdPartyId(any()); + }); } - //********************************************************************************************** + // ********************************************************************************************** // setTntId - //********************************************************************************************** + // ********************************************************************************************** @Test public void testSetTntId_validInput() { - // setup - when(targetState.getTntId()).thenReturn(null); - - // test - final Event event = setTntIdEvent(MOCK_TNT_ID); - extension.handleTargetRequestIdentityEvent(event); - - // validate - verify(targetState).updateTntId(MOCK_TNT_ID); - verify(targetState).updateEdgeHost("mboxedge35.tt.omtrdc.net"); - // verify that a new shared state is generated - verify(mockExtensionApi).createSharedState(any(), eq(event)); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getTntId()).thenReturn(null); + + // test + final Event event = setTntIdEvent(MOCK_TNT_ID); + extension.handleTargetRequestIdentityEvent(event); + + // validate + verify(targetState).updateTntId(MOCK_TNT_ID); + verify(targetState).updateEdgeHost("mboxedge35.tt.omtrdc.net"); + // verify that a new shared state is generated + verify(mockExtensionApi).createSharedState(any(), eq(event)); + }); } @Test public void testSetTntId_null_whenAlreadySet() { - // setup - when(targetState.getTntId()).thenReturn(MOCK_TNT_ID); - - // test - final Event event = setTntIdEvent(null); - extension.handleTargetRequestIdentityEvent(event); - - // validate - verify(targetState).updateTntId(null); - verify(targetState).updateEdgeHost(null); - // verify that a new shared state is generated - verify(mockExtensionApi).createSharedState(any(), eq(event)); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getTntId()).thenReturn(MOCK_TNT_ID); + + // test + final Event event = setTntIdEvent(null); + extension.handleTargetRequestIdentityEvent(event); + + // validate + verify(targetState).updateTntId(null); + verify(targetState).updateEdgeHost(null); + // verify that a new shared state is generated + verify(mockExtensionApi).createSharedState(any(), eq(event)); + }); } @Test public void testSetTntId_null_whenAlreadyNull() { - // setup - when(targetState.getTntId()).thenReturn(null); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getTntId()).thenReturn(null); - // test - extension.handleTargetRequestIdentityEvent(setTntIdEvent(null)); + // test + extension.handleTargetRequestIdentityEvent(setTntIdEvent(null)); - // validate that the state is not updated - verify(targetState, times(0)).updateTntId(any()); - verify(targetState, times(0)).updateEdgeHost(any()); + // validate that the state is not updated + verify(targetState, times(0)).updateTntId(any()); + verify(targetState, times(0)).updateEdgeHost(any()); + }); } @Test public void testSetTntId_EmptyInput() { - // setup - when(targetState.getTntId()).thenReturn(MOCK_TNT_ID); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getTntId()).thenReturn(MOCK_TNT_ID); - // test - extension.handleTargetRequestIdentityEvent(setTntIdEvent("")); + // test + extension.handleTargetRequestIdentityEvent(setTntIdEvent("")); - // validate that the state is not updated - verify(targetState).updateTntId(eq("")); - verify(targetState).updateEdgeHost(null); + // validate that the state is not updated + verify(targetState).updateTntId(eq("")); + verify(targetState).updateEdgeHost(null); + }); } @Test public void testSetTntId_newIdHasDifferentHint() { - // setup - // MOCK_TNT_ID = 66E5C681-4F70-41A2-86AE-F1E151443B10.35_0 - // MOCK_TNT_ID1 = 66E5C681-4F70-41A2-86AE-F1E151443B10.32_0 - when(targetState.getTntId()).thenReturn(MOCK_TNT_ID); - - // test - extension.handleTargetRequestIdentityEvent(setTntIdEvent(MOCK_TNT_ID_1)); - - // verify - verify(targetState).updateTntId(MOCK_TNT_ID_1); - verify(targetState).updateEdgeHost("mboxedge32.tt.omtrdc.net"); + runWithMockedServiceProvider( + () -> { + // setup + // MOCK_TNT_ID = 66E5C681-4F70-41A2-86AE-F1E151443B10.35_0 + // MOCK_TNT_ID1 = 66E5C681-4F70-41A2-86AE-F1E151443B10.32_0 + when(targetState.getTntId()).thenReturn(MOCK_TNT_ID); + + // test + extension.handleTargetRequestIdentityEvent(setTntIdEvent(MOCK_TNT_ID_1)); + + // verify + verify(targetState).updateTntId(MOCK_TNT_ID_1); + verify(targetState).updateEdgeHost("mboxedge32.tt.omtrdc.net"); + }); } @Test public void testSetTntId_newIdHasDifferentUUID() { - // setup - // MOCK_TNT_ID_1 = 66E5C681-4F70-41A2-86AE-F1E151443B10.32_0 - // MOCK_TNT_ID_2 = 4DBCC39D-4ACA-47D4-A7D2-A85C1C0CC382.32_0 - when(targetState.getTntId()).thenReturn(MOCK_TNT_ID_1); - - // test - extension.handleTargetRequestIdentityEvent(setTntIdEvent(MOCK_TNT_ID_2)); - - // verify - verify(targetState).updateTntId(MOCK_TNT_ID_2); - verify(targetState).updateEdgeHost("mboxedge32.tt.omtrdc.net"); + runWithMockedServiceProvider( + () -> { + // setup + // MOCK_TNT_ID_1 = 66E5C681-4F70-41A2-86AE-F1E151443B10.32_0 + // MOCK_TNT_ID_2 = 4DBCC39D-4ACA-47D4-A7D2-A85C1C0CC382.32_0 + when(targetState.getTntId()).thenReturn(MOCK_TNT_ID_1); + + // test + extension.handleTargetRequestIdentityEvent(setTntIdEvent(MOCK_TNT_ID_2)); + + // verify + verify(targetState).updateTntId(MOCK_TNT_ID_2); + verify(targetState).updateEdgeHost("mboxedge32.tt.omtrdc.net"); + }); } @Test public void testSetTntId_newIdHasDifferentUUIDAndHint() { - // setup - // MOCK_TNT_ID = 66E5C681-4F70-41A2-86AE-F1E151443B10.35_0 - // MOCK_TNT_ID_2 = 4DBCC39D-4ACA-47D4-A7D2-A85C1C0CC382.32_0 - when(targetState.getTntId()).thenReturn(MOCK_TNT_ID); - - // test - extension.handleTargetRequestIdentityEvent(setTntIdEvent(MOCK_TNT_ID_2)); - - // verify - verify(targetState).updateTntId(MOCK_TNT_ID_2); - verify(targetState).updateEdgeHost("mboxedge32.tt.omtrdc.net"); + runWithMockedServiceProvider( + () -> { + // setup + // MOCK_TNT_ID = 66E5C681-4F70-41A2-86AE-F1E151443B10.35_0 + // MOCK_TNT_ID_2 = 4DBCC39D-4ACA-47D4-A7D2-A85C1C0CC382.32_0 + when(targetState.getTntId()).thenReturn(MOCK_TNT_ID); + + // test + extension.handleTargetRequestIdentityEvent(setTntIdEvent(MOCK_TNT_ID_2)); + + // verify + verify(targetState).updateTntId(MOCK_TNT_ID_2); + verify(targetState).updateEdgeHost("mboxedge32.tt.omtrdc.net"); + }); } @Test public void testSetTntId_newIdHasInvalidHint() { - // test - extension.handleTargetRequestIdentityEvent(setTntIdEvent(MOCK_TNT_ID_INVALID)); - - // verify - verify(targetState).updateTntId(MOCK_TNT_ID_INVALID); - verify(targetState).updateEdgeHost(null); + runWithMockedServiceProvider( + () -> { + // test + extension.handleTargetRequestIdentityEvent(setTntIdEvent(MOCK_TNT_ID_INVALID)); + + // verify + verify(targetState).updateTntId(MOCK_TNT_ID_INVALID); + verify(targetState).updateEdgeHost(null); + }); } @Test public void testSetTntId_Fails_Privacy_OptOut() { - // setup - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.OPT_OUT); - - // test - extension.handleTargetRequestIdentityEvent(setTntIdEvent(MOCK_TNT_ID_1)); - - // validate that the state is not updated - verify(targetState, times(0)).updateTntId(any()); - verify(targetState, times(0)).updateEdgeHost(any()); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getMobilePrivacyStatus()) + .thenReturn(MobilePrivacyStatus.OPT_OUT); + + // test + extension.handleTargetRequestIdentityEvent(setTntIdEvent(MOCK_TNT_ID_1)); + + // validate that the state is not updated + verify(targetState, times(0)).updateTntId(any()); + verify(targetState, times(0)).updateEdgeHost(any()); + }); } @Test public void testSetTntId_Succeeds_Privacy_Unknown() { - // setup - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.UNKNOWN); - - // test - extension.handleTargetRequestIdentityEvent(setTntIdEvent(MOCK_TNT_ID_1)); - - // validate that the state is updated - verify(targetState).updateTntId(any()); - verify(targetState).updateEdgeHost(any()); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getMobilePrivacyStatus()) + .thenReturn(MobilePrivacyStatus.UNKNOWN); + + // test + extension.handleTargetRequestIdentityEvent(setTntIdEvent(MOCK_TNT_ID_1)); + + // validate that the state is updated + verify(targetState).updateTntId(any()); + verify(targetState).updateEdgeHost(any()); + }); } - //********************************************************************************************** + // ********************************************************************************************** // setSessionId - //********************************************************************************************** + // ********************************************************************************************** @Test public void testSetSessionId_validInput() { - // setup - when(targetState.getSessionId()).thenReturn(null); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getSessionId()).thenReturn(null); - // test - extension.handleTargetRequestIdentityEvent(setSessionIdEvent(MOCK_SESSION_ID)); + // test + extension.handleTargetRequestIdentityEvent(setSessionIdEvent(MOCK_SESSION_ID)); - // validate - verify(targetState).updateSessionId(MOCK_SESSION_ID); - verify(targetState).updateSessionTimestamp(eq(false)); + // validate + verify(targetState).updateSessionId(MOCK_SESSION_ID); + verify(targetState).updateSessionTimestamp(eq(false)); + }); } @Test public void testSetSessionId_nullInput() { - // test - extension.handleTargetRequestIdentityEvent(setSessionIdEvent(null)); + runWithMockedServiceProvider( + () -> { + // test + extension.handleTargetRequestIdentityEvent(setSessionIdEvent(null)); - // verify - verify(targetState).resetSession(); + // verify + verify(targetState).resetSession(); + }); } @Test public void testSetSessionId_privacyOptedOut() { - // setup - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.OPT_OUT); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getMobilePrivacyStatus()) + .thenReturn(MobilePrivacyStatus.OPT_OUT); - // test - extension.handleTargetRequestIdentityEvent(setSessionIdEvent(MOCK_SESSION_ID)); + // test + extension.handleTargetRequestIdentityEvent(setSessionIdEvent(MOCK_SESSION_ID)); - // validate that the state is not updated - verify(targetState, times(0)).updateSessionId(any()); + // validate that the state is not updated + verify(targetState, times(0)).updateSessionId(any()); + }); } @Test public void testSetSessionId_newSessionIdValueIsUnchanged() { - // setup - // the setup step mocks with current session to value MOCK_SESSION_ID + runWithMockedServiceProvider( + () -> { + // setup + // the setup step mocks with current session to value MOCK_SESSION_ID - // test - extension.handleTargetRequestIdentityEvent(setSessionIdEvent(MOCK_SESSION_ID)); + // test + extension.handleTargetRequestIdentityEvent(setSessionIdEvent(MOCK_SESSION_ID)); - // validate - verify(targetState, times(0)).updateSessionId(any()); - verify(targetState).updateSessionTimestamp(eq(false)); + // validate + verify(targetState, times(0)).updateSessionId(any()); + verify(targetState).updateSessionTimestamp(eq(false)); + }); } - //********************************************************************************************** + // ********************************************************************************************** // ClearPrefetchCache - //********************************************************************************************** + // ********************************************************************************************** @Test public void test_onClearPrefetchCacheEvent() { - // test - extension.handleTargetRequestResetEvent(clearPrefetchCacheEvent()); + runWithMockedServiceProvider( + () -> { + // test + extension.handleTargetRequestResetEvent(clearPrefetchCacheEvent()); - // verify - verify(targetState).clearPrefetchedMboxes(); + // verify + verify(targetState).clearPrefetchedMboxes(); + }); } - //********************************************************************************************** + // ********************************************************************************************** // ResetExperience - //********************************************************************************************** + // ********************************************************************************************** @Test public void test_onResetExperienceEvent() { - when(targetState.generateSharedState()).thenReturn(null); - when(targetState.getEdgeHost()).thenReturn("hst"); - when(targetState.getTntId()).thenReturn("sampleId"); - when(targetState.getThirdPartyId()).thenReturn("sampleId"); - Event event = resetExperienceEvent(); - - // test - extension.handleTargetRequestResetEvent(event); - - // verify - verify(targetState).resetSession(); - verify(targetState).updateTntId(eq(null)); - verify(targetState).updateThirdPartyId(eq(null)); - verify(targetState, times(2)).updateEdgeHost(eq(null)); - verify(mockExtensionApi).createSharedState(eq(null), eq(event)); + runWithMockedServiceProvider( + () -> { + when(targetState.generateSharedState()).thenReturn(null); + when(targetState.getEdgeHost()).thenReturn("hst"); + when(targetState.getTntId()).thenReturn("sampleId"); + when(targetState.getThirdPartyId()).thenReturn("sampleId"); + Event event = resetExperienceEvent(); + + // test + extension.handleTargetRequestResetEvent(event); + + // verify + verify(targetState).resetSession(); + verify(targetState).updateTntId(eq(null)); + verify(targetState).updateThirdPartyId(eq(null)); + verify(targetState, times(2)).updateEdgeHost(eq(null)); + verify(mockExtensionApi).createSharedState(eq(null), eq(event)); + }); } @Test public void test_RequestResetEvent_when_noEventData() { - // test - HashMap eventData = new HashMap<>(); - eventData.put(TargetConstants.EventDataKeys.LOAD_REQUEST, "invalid"); - Event event = new Event.Builder("Test", EventType.TARGET, EventSource.NONE).setEventData(eventData).build(); - extension.handleTargetRequestResetEvent(event); - - // verify - verifyNoInteractions(targetState); - verifyNoInteractions(mockExtensionApi); + runWithMockedServiceProvider( + () -> { + // test + HashMap eventData = new HashMap<>(); + eventData.put(TargetConstants.EventDataKeys.LOAD_REQUEST, "invalid"); + Event event = + new Event.Builder("Test", EventType.TARGET, EventSource.NONE) + .setEventData(eventData) + .build(); + extension.handleTargetRequestResetEvent(event); + + // verify + verifyNoInteractions(targetState); + verifyNoInteractions(mockExtensionApi); + }); } - //********************************************************************************************** + // ********************************************************************************************** // HandleRawEvent - //********************************************************************************************** + // ********************************************************************************************** @Test public void testHandleRawRequest_NoRequest_When_NoConfiguration() { - // setup - when(targetState.getClientCode()).thenReturn(""); - - // test - extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); - - // verify - verifyNoInteractions(networkService); - verifyNoInteractions(requestBuilder); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertNull(eventArgumentCaptor.getValue().getEventData().get(EventDataKeys.RESPONSE_DATA)); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getClientCode()).thenReturn(""); + + // test + extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); + + // verify + verifyNoInteractions(networkService); + verifyNoInteractions(requestBuilder); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertNull( + eventArgumentCaptor + .getValue() + .getEventData() + .get(EventDataKeys.RESPONSE_DATA)); + }); } @Test public void testHandleRawRequest_NoRequest_When_OptOut() { - // setup - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.OPT_OUT); - - // test - extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); - - // verify - verifyNoInteractions(networkService); - verifyNoInteractions(requestBuilder); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertNull(eventArgumentCaptor.getValue().getEventData().get(EventDataKeys.RESPONSE_DATA)); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getMobilePrivacyStatus()) + .thenReturn(MobilePrivacyStatus.OPT_OUT); + + // test + extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); + + // verify + verifyNoInteractions(networkService); + verifyNoInteractions(requestBuilder); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertNull( + eventArgumentCaptor + .getValue() + .getEventData() + .get(EventDataKeys.RESPONSE_DATA)); + }); } @Test public void testHandleRawRequest_NoRequest_When_NetworkServiceIsNotAvailable() { - // setup - extension = new TargetExtension(mockExtensionApi, deviceInforming, null, uiService, targetState, targetPreviewManager, requestBuilder, responseParser); - - // test - extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); - - // verify - verifyNoInteractions(networkService); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertNull(eventArgumentCaptor.getValue().getEventData().get(EventDataKeys.RESPONSE_DATA)); + runWithMockedServiceProvider( + () -> { + // setup + when(mockServiceProvider.getNetworkService()).thenReturn(networkService); + when(mockServiceProvider.getNetworkService()).thenReturn(null); + extension = + new TargetExtension( + mockExtensionApi, + targetState, + targetPreviewManager, + requestBuilder, + responseParser); + + // test + extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); + + // verify + verifyNoInteractions(networkService); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertNull( + eventArgumentCaptor + .getValue() + .getEventData() + .get(EventDataKeys.RESPONSE_DATA)); + }); } @Test public void testHandleRawRequest_TargetRequestBuilder_isNull() { - // setup - extension = new TargetExtension(mockExtensionApi, deviceInforming, networkService, uiService, targetState, targetPreviewManager, null, responseParser); - - // test - extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); - - // verify - verifyNoInteractions(networkService); - verifyNoInteractions(requestBuilder); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertNull(eventArgumentCaptor.getValue().getEventData().get(EventDataKeys.RESPONSE_DATA)); + runWithMockedServiceProvider( + () -> { + // setup + when(mockServiceProvider.getDeviceInfoService()).thenReturn(null); + extension = + new TargetExtension( + mockExtensionApi, + targetState, + targetPreviewManager, + null, + responseParser); + + // test + extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); + + // verify + verifyNoInteractions(networkService); + verifyNoInteractions(requestBuilder); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertNull( + eventArgumentCaptor + .getValue() + .getEventData() + .get(EventDataKeys.RESPONSE_DATA)); + }); } @Test - public void testHandleRawRequest_NoRequest_When_RequestPayloadIsEmpty() throws JSONException { - // setup - JSONObject json = new JSONObject("{}"); - when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any())).thenReturn(json); - - // test - extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); - - // verify no network request is made - verifyNoInteractions(networkService); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertNull(eventArgumentCaptor.getValue().getEventData().get(EventDataKeys.RESPONSE_DATA)); + public void testHandleRawRequest_NoRequest_When_RequestPayloadIsEmpty() { + runWithMockedServiceProvider( + () -> { + // setup + JSONObject json = null; + try { + json = new JSONObject("{}"); + } catch (JSONException e) { + throw new RuntimeException(e); + } + when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any())) + .thenReturn(json); + + // test + extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); + + // verify no network request is made + verifyNoInteractions(networkService); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertNull( + eventArgumentCaptor + .getValue() + .getEventData() + .get(EventDataKeys.RESPONSE_DATA)); + }); } @Test - public void testHandleRawRequest_SendRequest_When_RequestPayloadIsValid_sendsCorrectNetworkRequest() throws Exception { - // setup - setEventHubSharedState(); - JSONObject json = new JSONObject("{\"test\":\"value\"}"); - when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any())).thenReturn(json); - - // test - extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); - - // verify - verify(networkService).connectAsync(networkRequestCaptor.capture(), networkCallbackCaptor.capture()); - assertEquals("https://" + MOCKED_TARGET_SERVER + "/rest/v1/delivery/?client=" + MOCKED_CLIENT_CODE + "&sessionId=" + MOCK_SESSION_ID, networkRequestCaptor.getValue().getUrl()); - assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); - final Map headers = networkRequestCaptor.getValue().getHeaders(); - assertEquals(3, headers.size()); - assertEquals("application/json", headers.get("Content-Type")); - assertEquals("AdobeTargetMobile-Android", headers.get("X-EXC-SDK")); - assertEquals(String.format("%s+%s", "x.y.z", extension.getVersion()), headers.get("X-EXC-SDK-Version")); - assertEquals(json.toString(), new String(networkRequestCaptor.getValue().getBody(), StandardCharsets.UTF_8)); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getReadTimeout(), 0); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getConnectTimeout(), 0); + public void + testHandleRawRequest_SendRequest_When_RequestPayloadIsValid_sendsCorrectNetworkRequest() + throws Exception { + runWithMockedServiceProvider( + () -> { + // setup + setEventHubSharedState(); + JSONObject json = null; + try { + json = new JSONObject("{\"test\":\"value\"}"); + } catch (JSONException e) { + throw new RuntimeException(e); + } + when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any())) + .thenReturn(json); + + // test + extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); + + // verify + verify(networkService) + .connectAsync( + networkRequestCaptor.capture(), + networkCallbackCaptor.capture()); + assertEquals( + "https://" + + MOCKED_TARGET_SERVER + + "/rest/v1/delivery/?client=" + + MOCKED_CLIENT_CODE + + "&sessionId=" + + MOCK_SESSION_ID, + networkRequestCaptor.getValue().getUrl()); + assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); + final Map headers = + networkRequestCaptor.getValue().getHeaders(); + assertEquals(3, headers.size()); + assertEquals("application/json", headers.get("Content-Type")); + assertEquals("AdobeTargetMobile-Android", headers.get("X-EXC-SDK")); + assertEquals( + String.format("%s+%s", "x.y.z", extension.getVersion()), + headers.get("X-EXC-SDK-Version")); + assertEquals( + json.toString(), + new String( + networkRequestCaptor.getValue().getBody(), + StandardCharsets.UTF_8)); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getReadTimeout(), + 0); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getConnectTimeout(), + 0); + }); } @Test public void testHandleRawRequest_ResponseNotProcessed_When_ConnectionIsNull() { - // test - extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); - - // verify and call callback - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(null); - - // verify the dispatched response event - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertNull(eventArgumentCaptor.getValue().getEventData().get(EventDataKeys.RESPONSE_DATA)); + runWithMockedServiceProvider( + () -> { + // test + extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); + + // verify and call callback + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(null); + + // verify the dispatched response event + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertNull( + eventArgumentCaptor + .getValue() + .getEventData() + .get(EventDataKeys.RESPONSE_DATA)); + }); } @Test public void testHandleRawRequest_DispatchRawResponse_When_ResponseJsonIsNull() { - // setup - when(responseParser.parseResponseToJson(any())).thenReturn(null); - - // test - extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); - - // verify and call callback - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - - // verify the dispatched response event - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertNull(eventArgumentCaptor.getValue().getEventData().get(EventDataKeys.RESPONSE_DATA)); + runWithMockedServiceProvider( + () -> { + // setup + when(responseParser.parseResponseToJson(any())).thenReturn(null); + + // test + extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); + + // verify and call callback + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify the dispatched response event + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertNull( + eventArgumentCaptor + .getValue() + .getEventData() + .get(EventDataKeys.RESPONSE_DATA)); + }); } @Test public void testHandleRawRequest_DispatchRawResponse_When_NetworkResponseNot200() { - // setup - when(connecting.getResponseCode()).thenReturn(HttpURLConnection.HTTP_BAD_REQUEST); - when(responseParser.getErrorMessage(any())).thenReturn("SomeErrorMessage"); - - // test - extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); - - // verify and call callback - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify the dispatched response event - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertNull(eventArgumentCaptor.getValue().getEventData().get(EventDataKeys.RESPONSE_DATA)); + runWithMockedServiceProvider( + () -> { + // setup + when(connecting.getResponseCode()) + .thenReturn(HttpURLConnection.HTTP_BAD_REQUEST); + when(responseParser.getErrorMessage(any())).thenReturn("SomeErrorMessage"); + + // test + extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); + + // verify and call callback + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify the dispatched response event + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertNull( + eventArgumentCaptor + .getValue() + .getEventData() + .get(EventDataKeys.RESPONSE_DATA)); + }); } @Test - public void testHandleRawRequest_SetTntIdAndEdgeHost_When_ResponseJsonContainValidTntIdAndEdgeHost() { - // setup - when(responseParser.getTntId(any())).thenReturn(MOCK_TNT_ID_1); - when(responseParser.getEdgeHost(any())).thenReturn(MOCK_EDGE_HOST); + public void + testHandleRawRequest_SetTntIdAndEdgeHost_When_ResponseJsonContainValidTntIdAndEdgeHost() { + runWithMockedServiceProvider( + () -> { + // setup + when(responseParser.getTntId(any())).thenReturn(MOCK_TNT_ID_1); + when(responseParser.getEdgeHost(any())).thenReturn(MOCK_EDGE_HOST); - // test - extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); + // test + extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); - // verify and call callback - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); + // verify and call callback + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); - // verify - verify(targetState).updateSessionTimestamp(eq(false)); - verify(targetState).updateEdgeHost(eq(MOCK_EDGE_HOST)); - verify(targetState).updateTntId(eq(MOCK_TNT_ID_1)); + // verify + verify(targetState).updateSessionTimestamp(eq(false)); + verify(targetState).updateEdgeHost(eq(MOCK_EDGE_HOST)); + verify(targetState).updateTntId(eq(MOCK_TNT_ID_1)); + }); } @Test - public void testHandleRawRequest_SetTntIdAndEdgeHostToNull_When_ResponseJsonNotContainTntIdAndEdgeHost() { - // setup - when(responseParser.getTntId(any())).thenReturn(null); - when(responseParser.getEdgeHost(any())).thenReturn(null); + public void + testHandleRawRequest_SetTntIdAndEdgeHostToNull_When_ResponseJsonNotContainTntIdAndEdgeHost() { + runWithMockedServiceProvider( + () -> { + // setup + when(responseParser.getTntId(any())).thenReturn(null); + when(responseParser.getEdgeHost(any())).thenReturn(null); - // test - extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); + // test + extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); - // verify and call callback - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); + // verify and call callback + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); - // verify - verify(targetState).updateSessionTimestamp(eq(false)); - verify(targetState, times(2)).updateEdgeHost(eq(null)); - verify(targetState).updateTntId(eq(null)); + // verify + verify(targetState).updateSessionTimestamp(eq(false)); + verify(targetState, times(2)).updateEdgeHost(eq(null)); + verify(targetState).updateTntId(eq(null)); + }); } @Test - public void testHandleRawRequest_DispatchExecuteResponse_When_ResponseJsonContainsMboxWithValidContent() { - // setup - Map executeMbox = new HashMap() { - { - put("name", "mbox0"); - put("options", new ArrayList>() { - { - add(new HashMap() { - { - put("type", "html"); - put("content", "Hello"); - } - }); - } - }); - put("metrics", new ArrayList>() { - { - add(new HashMap() { - { - put("type", "click"); - put("eventToken", "LgG0+YDMHn4X5HqGJVoZ5g=="); - } - }); - } - }); - } - }; - - List> executeMboxes = new ArrayList>() { - { - add(executeMbox); - } - }; - - Map responseMap = new HashMap() { - { - put("status", 200); - put("requestId", "01d4a408-6978-48f7-95c6-03f04160b257"); - put("client", "adobe"); - put("edgeHost", "mboxedge35.tt.omtrdc.net"); - put("id", new HashMap() { - { - put("tntId", "DE03D4AD-1FFE-421F-B2F2-303BF26822C1.35_0"); - put("marketingCloudVisitorId", "61055260263379929267175387965071996926"); - } - }); - put("execute", new HashMap() { - { - put("mboxes", executeMboxes); - } + public void + testHandleRawRequest_DispatchExecuteResponse_When_ResponseJsonContainsMboxWithValidContent() { + runWithMockedServiceProvider( + () -> { + // setup + Map executeMbox = + new HashMap() { + { + put("name", "mbox0"); + put( + "options", + new ArrayList>() { + { + add( + new HashMap() { + { + put("type", "html"); + put( + "content", + "Hello"); + } + }); + } + }); + put( + "metrics", + new ArrayList>() { + { + add( + new HashMap() { + { + put("type", "click"); + put( + "eventToken", + "LgG0+YDMHn4X5HqGJVoZ5g=="); + } + }); + } + }); + } + }; + + List> executeMboxes = + new ArrayList>() { + { + add(executeMbox); + } + }; + + Map responseMap = + new HashMap() { + { + put("status", 200); + put("requestId", "01d4a408-6978-48f7-95c6-03f04160b257"); + put("client", "adobe"); + put("edgeHost", "mboxedge35.tt.omtrdc.net"); + put( + "id", + new HashMap() { + { + put( + "tntId", + "DE03D4AD-1FFE-421F-B2F2-303BF26822C1.35_0"); + put( + "marketingCloudVisitorId", + "61055260263379929267175387965071996926"); + } + }); + put( + "execute", + new HashMap() { + { + put("mboxes", executeMboxes); + } + }); + } + }; + when(responseParser.parseResponseToJson(any())) + .thenReturn(new JSONObject(responseMap)); + + // test + extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); + + // verify and call callback + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify the dispatched response event contains the response data parsed by + // responseParser + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + responseMap, + eventArgumentCaptor + .getValue() + .getEventData() + .get(EventDataKeys.RESPONSE_DATA)); }); - } - }; - when(responseParser.parseResponseToJson(any())).thenReturn(new JSONObject(responseMap)); - - // test - extension.handleTargetRequestContentEvent(rawRequestExecuteEvent(1)); - - // verify and call callback - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify the dispatched response event contains the response data parsed by responseParser - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals(responseMap, eventArgumentCaptor.getValue().getEventData().get(EventDataKeys.RESPONSE_DATA)); } @Test - public void testHandleRawRequest_SendNotification_When_RequestPayloadIsValid() throws Exception { - // setup - JSONObject json = new JSONObject("{\"mbox\": {\"name\": \"mbox1\"}, \"tokens\":[\"someToken\"]}"); - when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any())).thenReturn(json); - - // test - extension.handleTargetRequestContentEvent(getTargetRawRequestForNotificationsEvent(1)); - - // verify - verify(networkService).connectAsync(networkRequestCaptor.capture(), networkCallbackCaptor.capture()); + public void testHandleRawRequest_SendNotification_When_RequestPayloadIsValid() { + runWithMockedServiceProvider( + () -> { + // setup + JSONObject json = null; + try { + json = + new JSONObject( + "{\"mbox\": {\"name\": \"mbox1\"}," + + " \"tokens\":[\"someToken\"]}"); + } catch (JSONException e) { + throw new RuntimeException(e); + } + when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any())) + .thenReturn(json); + + // test + extension.handleTargetRequestContentEvent( + getTargetRawRequestForNotificationsEvent(1)); + + // verify + verify(networkService) + .connectAsync( + networkRequestCaptor.capture(), + networkCallbackCaptor.capture()); + }); } // ======================================================================================== @@ -1320,77 +1912,97 @@ public void testHandleRawRequest_SendNotification_When_RequestPayloadIsValid() t @Test public void testHandleGenericDataOSEvent_withValidDeeplink() { - // setup - final String deeplink = "deeplink://something"; - when(targetState.isPreviewEnabled()).thenReturn(true); - - // test - extension.handleGenericDataOSEvent(previewDeeplinkEvent(deeplink)); - - // verify - verify(targetPreviewManager).enterPreviewModeWithDeepLinkParams(eq(MOCKED_CLIENT_CODE), eq(deeplink)); + runWithMockedServiceProvider( + () -> { + // setup + final String deeplink = "deeplink://something"; + when(targetState.isPreviewEnabled()).thenReturn(true); + + // test + extension.handleGenericDataOSEvent(previewDeeplinkEvent(deeplink)); + + // verify + verify(targetPreviewManager) + .enterPreviewModeWithDeepLinkParams( + eq(MOCKED_CLIENT_CODE), eq(deeplink)); + }); } @Test public void testHandleGenericDataOSEvent_whenPreviewNotEnabledInConfiguration() { - // setup - final String deeplink = "deeplink://something"; - when(targetState.isPreviewEnabled()).thenReturn(false); + runWithMockedServiceProvider( + () -> { + // setup + final String deeplink = "deeplink://something"; + when(targetState.isPreviewEnabled()).thenReturn(false); - // test - extension.handleGenericDataOSEvent(previewDeeplinkEvent(deeplink)); + // test + extension.handleGenericDataOSEvent(previewDeeplinkEvent(deeplink)); - // verify - verifyNoInteractions(targetPreviewManager); + // verify + verifyNoInteractions(targetPreviewManager); + }); } @Test public void testHandleGenericDataOSEvent_whenNullDeeplink() { - // setup - when(targetState.isPreviewEnabled()).thenReturn(true); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.isPreviewEnabled()).thenReturn(true); - // test - extension.handleGenericDataOSEvent(previewDeeplinkEvent(null)); + // test + extension.handleGenericDataOSEvent(previewDeeplinkEvent(null)); - // verify - verifyNoInteractions(targetPreviewManager); + // verify + verifyNoInteractions(targetPreviewManager); + }); } @Test public void testHandleGenericDataOSEvent_whenEmptyDeeplink() { - // setup - when(targetState.isPreviewEnabled()).thenReturn(true); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.isPreviewEnabled()).thenReturn(true); - // test - extension.handleGenericDataOSEvent(previewDeeplinkEvent("")); + // test + extension.handleGenericDataOSEvent(previewDeeplinkEvent("")); - // verify - verifyNoInteractions(targetPreviewManager); + // verify + verifyNoInteractions(targetPreviewManager); + }); } @Test public void testHandleGenericDataOSEvent_when_targetNotConfigured() { - // setup - when(targetState.getClientCode()).thenReturn(""); - when(targetState.isPreviewEnabled()).thenReturn(true); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getClientCode()).thenReturn(""); + when(targetState.isPreviewEnabled()).thenReturn(true); - // test - extension.handleGenericDataOSEvent(previewDeeplinkEvent("target:deeplink//")); + // test + extension.handleGenericDataOSEvent(previewDeeplinkEvent("target:deeplink//")); - // verify - verifyNoInteractions(targetPreviewManager); + // verify + verifyNoInteractions(targetPreviewManager); + }); } @Test public void testHandleGenericDataOSEvent_when_emptyEventData() { - // setup - when(targetState.isPreviewEnabled()).thenReturn(true); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.isPreviewEnabled()).thenReturn(true); - // test - extension.handleGenericDataOSEvent(noEventDataEvent()); + // test + extension.handleGenericDataOSEvent(noEventDataEvent()); - // verify - verifyNoInteractions(targetPreviewManager); + // verify + verifyNoInteractions(targetPreviewManager); + }); } // ======================================================================================== @@ -1399,666 +2011,1092 @@ public void testHandleGenericDataOSEvent_when_emptyEventData() { @Test public void testSetPreviewRestartDeepLink_when_emptyDeeplink() { - // test - extension.handleTargetRequestContentEvent(previewRestartDeeplinkEvent("")); + runWithMockedServiceProvider( + () -> { + // test + extension.handleTargetRequestContentEvent(previewRestartDeeplinkEvent("")); - // verify - verifyNoInteractions(targetPreviewManager); + // verify + verifyNoInteractions(targetPreviewManager); + }); } @Test public void testSetPreviewRestartDeepLink_when_nullDeeplink() { - // test - extension.handleTargetRequestContentEvent(previewRestartDeeplinkEvent(null)); + runWithMockedServiceProvider( + () -> { + // test + extension.handleTargetRequestContentEvent(previewRestartDeeplinkEvent(null)); - // verify - verifyNoInteractions(targetPreviewManager); + // verify + verifyNoInteractions(targetPreviewManager); + }); } @Test public void testSetPreviewRestartDeepLink_when_validDeeplink() { - // test - final String restartDeeplink = "deeplink://"; - extension.handleTargetRequestContentEvent(previewRestartDeeplinkEvent(restartDeeplink)); - - // verify - verify(targetPreviewManager).setRestartDeepLink(eq(restartDeeplink)); + runWithMockedServiceProvider( + () -> { + // test + final String restartDeeplink = "deeplink://"; + extension.handleTargetRequestContentEvent( + previewRestartDeeplinkEvent(restartDeeplink)); + + // verify + verify(targetPreviewManager).setRestartDeepLink(eq(restartDeeplink)); + }); } - //********************************************************************************************** + // ********************************************************************************************** // HandlePrefetchContent - //********************************************************************************************** + // ********************************************************************************************** @Test public void testHandlePrefetchContent_NoRequest_When_OptOut() { - // setup - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.OPT_OUT); - - // test - final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); - extension.handleTargetRequestContentEvent(event); - - // verify - verifyNoInteractions(networkService); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("Privacy status is not opted in", eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); - assertEquals(false, eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getMobilePrivacyStatus()) + .thenReturn(MobilePrivacyStatus.OPT_OUT); + + // test + final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); + extension.handleTargetRequestContentEvent(event); + + // verify + verifyNoInteractions(networkService); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "Privacy status is not opted in", + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); + assertEquals( + false, + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + }); } @Test public void testHandlePrefetchContent_NoRequest_When_ClientCodeIsEmpty() { - // setup - when(targetState.getClientCode()).thenReturn(""); - - // test - final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); - extension.handleTargetRequestContentEvent(event); - - // verify - verifyNoInteractions(networkService); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("Missing client code", eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); - assertEquals(false, eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getClientCode()).thenReturn(""); + + // test + final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); + extension.handleTargetRequestContentEvent(event); + + // verify + verifyNoInteractions(networkService); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "Missing client code", + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); + assertEquals( + false, + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + }); } @Test public void testHandlePrefetchContent_NoRequest_When_NoPrefetchList() { - // setup - when(targetState.getClientCode()).thenReturn(""); - - // test - final Event event = prefetchContentEvent(getTargetPrefetchList(0), null); - extension.handleTargetRequestContentEvent(event); - - // verify - verifyNoInteractions(networkService); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("Empty or null prefetch requests list", eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); - assertEquals(false, eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getClientCode()).thenReturn(""); + + // test + final Event event = prefetchContentEvent(getTargetPrefetchList(0), null); + extension.handleTargetRequestContentEvent(event); + + // verify + verifyNoInteractions(networkService); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "Empty or null prefetch requests list", + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); + assertEquals( + false, + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + }); } @Test public void testHandlePrefetchContent_NoRequest_When_PreviewModeInOn() { - // setup - when(targetPreviewManager.getPreviewParameters()).thenReturn("someParameter"); - - // test - final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); - extension.handleTargetRequestContentEvent(event); - - // verify - verifyNoInteractions(networkService); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("Target prefetch can't be used while in preview mode", eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); - assertEquals(false, eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + runWithMockedServiceProvider( + () -> { + // setup + when(targetPreviewManager.getPreviewParameters()).thenReturn("someParameter"); + + // test + final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); + extension.handleTargetRequestContentEvent(event); + + // verify + verifyNoInteractions(networkService); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "Target prefetch can't be used while in preview mode", + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); + assertEquals( + false, + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + }); } @Test public void testHandlePrefetchContent_NoRequest_When_NetworkServiceIsNotAvailable() { - // setup - extension = new TargetExtension(mockExtensionApi, deviceInforming, null, uiService, targetState, targetPreviewManager, requestBuilder, responseParser); - - // test - final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); - extension.handleTargetRequestContentEvent(event); - - // verify - verifyNoInteractions(networkService); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("Unable to send target request, Network service is not available", eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); - assertEquals(false, eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + runWithMockedServiceProvider( + () -> { + // setup + when(mockServiceProvider.getNetworkService()).thenReturn(null); + extension = + new TargetExtension( + mockExtensionApi, + targetState, + targetPreviewManager, + requestBuilder, + responseParser); + + // test + final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); + extension.handleTargetRequestContentEvent(event); + + // verify + verifyNoInteractions(networkService); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "Unable to send target request, Network service is not available", + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); + assertEquals( + false, + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + }); } @Test public void testHandlePrefetchContent_NoRequest_When_TargetRequestBuilderIsNotAvailable() { - // setup - extension = new TargetExtension(mockExtensionApi, deviceInforming, networkService, uiService, targetState, targetPreviewManager, null, responseParser); - - // test - final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); - extension.handleTargetRequestContentEvent(event); - - // verify - verifyNoInteractions(networkService); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("Couldn't initialize the target request builder for this request", eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); - assertEquals(false, eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + runWithMockedServiceProvider( + () -> { + // setup + when(mockServiceProvider.getDeviceInfoService()).thenReturn(null); + extension = + new TargetExtension( + mockExtensionApi, + targetState, + targetPreviewManager, + null, + responseParser); + + // test + final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); + extension.handleTargetRequestContentEvent(event); + + // verify + verifyNoInteractions(networkService); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "Couldn't initialize the target request builder for this request", + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); + assertEquals( + false, + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + }); } @Test public void testHandlePrefetchContent_NoRequest_When_RequestPayloadIsNotGenerated() { - // setup - when(requestBuilder.getRequestPayload(any(), any(), any(), any(), any(), any(), any())).thenReturn(null); - - // test - final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); - extension.handleTargetRequestContentEvent(event); - - // verify - verifyNoInteractions(networkService); - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("Failed to generate the Target request payload", eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); - assertEquals(false, eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + runWithMockedServiceProvider( + () -> { + // setup + when(requestBuilder.getRequestPayload( + any(), any(), any(), any(), any(), any(), any())) + .thenReturn(null); + + // test + final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); + extension.handleTargetRequestContentEvent(event); + + // verify + verifyNoInteractions(networkService); + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "Failed to generate the Target request payload", + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); + assertEquals( + false, + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + }); } @Test public void testHandlePrefetchContent_attachesLifecycleAndIdentityData() { - // setup - setLifecycleSharedState(); - setIdentitySharedState(); - - // test - extension.handleTargetRequestContentEvent(prefetchContentEvent(getTargetPrefetchList(1), null)); - - // verify - verify(requestBuilder).getRequestPayload(anyList(), eq(null), eq(null), anyList(), eq(""), eq(identitySharedState), eq(lifecycleSharedState)); + runWithMockedServiceProvider( + () -> { + // setup + setLifecycleSharedState(); + setIdentitySharedState(); + + // test + extension.handleTargetRequestContentEvent( + prefetchContentEvent(getTargetPrefetchList(1), null)); + + // verify + verify(requestBuilder) + .getRequestPayload( + anyList(), + eq(null), + eq(null), + anyList(), + eq(""), + eq(identitySharedState), + eq(lifecycleSharedState)); + }); } @Test public void testHandlePrefetchContent_when_ConnectionIsNull() { - // test - extension.handleTargetRequestContentEvent(prefetchContentEvent(getTargetPrefetchList(1), null)); - - // verify - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - - // test - networkCallbackCaptor.getValue().call(null); - - // verify - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("Unable to open connection", eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); - assertEquals(false, eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + runWithMockedServiceProvider( + () -> { + // test + extension.handleTargetRequestContentEvent( + prefetchContentEvent(getTargetPrefetchList(1), null)); + + // verify + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + + // test + networkCallbackCaptor.getValue().call(null); + + // verify + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "Unable to open connection", + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); + assertEquals( + false, + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + }); } @Test public void testHandlePrefetchContent_makesCorrectNetworkRequest() { - //setup - setEventHubSharedState(); - - // test - extension.handleTargetRequestContentEvent(prefetchContentEvent(getTargetPrefetchList(1), null)); - - // verify - verify(networkService).connectAsync(networkRequestCaptor.capture(), networkCallbackCaptor.capture()); - assertEquals("https://" + MOCKED_TARGET_SERVER + "/rest/v1/delivery/?client=" + MOCKED_CLIENT_CODE + "&sessionId=" + MOCK_SESSION_ID, networkRequestCaptor.getValue().getUrl()); - assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); - final Map headers = networkRequestCaptor.getValue().getHeaders(); - assertEquals(3, headers.size()); - assertEquals("application/json", headers.get("Content-Type")); - assertEquals("AdobeTargetMobile-Android", headers.get("X-EXC-SDK")); - assertEquals(String.format("%s+%s", "x.y.z", extension.getVersion()), headers.get("X-EXC-SDK-Version")); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getReadTimeout(), 0); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getConnectTimeout(), 0); + runWithMockedServiceProvider( + () -> { + // setup + setEventHubSharedState(); + + // test + extension.handleTargetRequestContentEvent( + prefetchContentEvent(getTargetPrefetchList(1), null)); + + // verify + verify(networkService) + .connectAsync( + networkRequestCaptor.capture(), + networkCallbackCaptor.capture()); + assertEquals( + "https://" + + MOCKED_TARGET_SERVER + + "/rest/v1/delivery/?client=" + + MOCKED_CLIENT_CODE + + "&sessionId=" + + MOCK_SESSION_ID, + networkRequestCaptor.getValue().getUrl()); + assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); + final Map headers = + networkRequestCaptor.getValue().getHeaders(); + assertEquals(3, headers.size()); + assertEquals("application/json", headers.get("Content-Type")); + assertEquals("AdobeTargetMobile-Android", headers.get("X-EXC-SDK")); + assertEquals( + String.format("%s+%s", "x.y.z", extension.getVersion()), + headers.get("X-EXC-SDK-Version")); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getReadTimeout(), + 0); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getConnectTimeout(), + 0); + }); } @Test public void testHandlePrefetchContent_ReturnDefaultContent_When_ResponseNot200OK() { - // setup - when(connecting.getResponseCode()).thenReturn(HttpURLConnection.HTTP_BAD_REQUEST); - - // test - extension.handleTargetRequestContentEvent(prefetchContentEvent(getTargetPrefetchList(1), null)); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify default response event dispatched - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("Errors returned in Target response: ", eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); - assertEquals(false, eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + runWithMockedServiceProvider( + () -> { + // setup + when(connecting.getResponseCode()) + .thenReturn(HttpURLConnection.HTTP_BAD_REQUEST); + + // test + extension.handleTargetRequestContentEvent( + prefetchContentEvent(getTargetPrefetchList(1), null)); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify default response event dispatched + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "Errors returned in Target response: ", + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); + assertEquals( + false, + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + }); } @Test public void testHandlePrefetchContent_ReturnError_when_ResponseJsonPrefetchError() { - // setup - when(responseParser.getErrorMessage(any())).thenReturn(""); - - // test - extension.handleTargetRequestContentEvent(prefetchContentEvent(getTargetPrefetchList(1), null)); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("Errors returned in Target response: ", eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); - assertEquals(false, eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + runWithMockedServiceProvider( + () -> { + // setup + when(responseParser.getErrorMessage(any())).thenReturn(""); + + // test + extension.handleTargetRequestContentEvent( + prefetchContentEvent(getTargetPrefetchList(1), null)); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "Errors returned in Target response: ", + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); + assertEquals( + false, + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + }); } @Test public void testHandlePrefetchContent_ReturnError_when_ResponseIsNull() { - // setup - when(responseParser.parseResponseToJson(any())).thenReturn(null); - when(responseParser.getErrorMessage(any())).thenReturn(""); - - // test - extension.handleTargetRequestContentEvent(prefetchContentEvent(getTargetPrefetchList(1), null)); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals("Null response Json ", eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); - assertEquals(false, eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + runWithMockedServiceProvider( + () -> { + // setup + when(responseParser.parseResponseToJson(any())).thenReturn(null); + when(responseParser.getErrorMessage(any())).thenReturn(""); + + // test + extension.handleTargetRequestContentEvent( + prefetchContentEvent(getTargetPrefetchList(1), null)); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + "Null response Json ", + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_ERROR)); + assertEquals( + false, + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + }); } @Test - public void testHandlePrefetchContent_ReturnTrue_When_ValidResponse() throws Exception { - final JSONObject validMboxResponse = new JSONObject("{\"options\": [{\"content\": \"mbox0content\", \"type\": \"html\"}]}"); - when(responseParser.extractPrefetchedMboxes(any())).thenReturn(new HashMap() { - { - put("mbox0", validMboxResponse); - } - }); - String serverResponse = "{\n" + - " \"prefetch\" : {\n" + - " \"views\" : [{\n" + - " \"options\" : [{\n" + - " \"content\" : [{\n" + - " \"id\" : \"1\" , \n" + - " \"type\" : \"setHtml\" , \n" + - " \"selector\" : \"toolBar\", \n" + - " \"content\" : \"AAA\"" + - " }], \n" + - " \"type\" : \"actions\" , \n" + - " \"eventToken\" : \"1zIHw4w+hPht4NV5MyssK4usK1YQ\" \n" + - " }]\n" + - " }]\n" + " }\n" + - "}"; - when(responseParser.parseResponseToJson(any())).thenReturn(new JSONObject(serverResponse)); - - // test - final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); - extension.handleTargetRequestContentEvent(event); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify - verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); - assertEquals(true, eventArgumentCaptor.getValue().getEventData().get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); - - // verify other interaction with targetState - verify(targetState).clearNotifications(); - verify(targetState).updateSessionTimestamp(eq(false)); - verify(targetState).updateEdgeHost(MOCK_EDGE_HOST); - verify(mockExtensionApi).createSharedState(eq(targetSharedState), eq(event)); - } - - //********************************************************************************************** + public void testHandlePrefetchContent_ReturnTrue_When_ValidResponse() { + runWithMockedServiceProvider( + () -> { + final JSONObject validMboxResponse; + try { + validMboxResponse = + new JSONObject( + "{\"options\": [{\"content\": \"mbox0content\", \"type\":" + + " \"html\"}]}"); + when(responseParser.extractPrefetchedMboxes(any())) + .thenReturn( + new HashMap() { + { + put("mbox0", validMboxResponse); + } + }); + String serverResponse = + "{\n" + + " \"prefetch\" : {\n" + + " \"views\" : [{\n" + + " \"options\" : [{\n" + + " \"content\" : [{\n" + + " \"id\" : \"1\" , \n" + + " \"type\" : \"setHtml\" , \n" + + " \"selector\" : \"toolBar\", \n" + + " \"content\" : \"AAA\" }], \n" + + " \"type\" : \"actions\" , \n" + + " \"eventToken\" : \"1zIHw4w+hPht4NV5MyssK4usK1YQ\" \n" + + " }]\n" + + " }]\n" + + " }\n" + + "}"; + when(responseParser.parseResponseToJson(any())) + .thenReturn(new JSONObject(serverResponse)); + + // test + final Event event = prefetchContentEvent(getTargetPrefetchList(1), null); + extension.handleTargetRequestContentEvent(event); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify + verify(mockExtensionApi, times(1)).dispatch(eventArgumentCaptor.capture()); + assertEquals( + true, + eventArgumentCaptor + .getValue() + .getEventData() + .get(TargetConstants.EventDataKeys.PREFETCH_RESULT)); + + // verify other interaction with targetState + verify(targetState).clearNotifications(); + verify(targetState).updateSessionTimestamp(eq(false)); + verify(targetState).updateEdgeHost(MOCK_EDGE_HOST); + verify(mockExtensionApi) + .createSharedState(eq(targetSharedState), eq(event)); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }); + } + + // ********************************************************************************************** // handleLocationsDisplayed - //********************************************************************************************** + // ********************************************************************************************** @Test public void testHandleLocationsDisplayed_NoRequest_When_OptOut() { - // setup - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.OPT_OUT); - - // test - extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); - - // verify - verifyNoInteractions(networkService); - verifyNoInteractions(mockExtensionApi); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getMobilePrivacyStatus()) + .thenReturn(MobilePrivacyStatus.OPT_OUT); + + // test + extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); + + // verify + verifyNoInteractions(networkService); + verifyNoInteractions(mockExtensionApi); + }); } @Test public void testHandleLocationsDisplayed_NoRequest_When_ClientCodeIsEmpty() { - // setup - when(targetState.getClientCode()).thenReturn(""); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getClientCode()).thenReturn(""); - // test - extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); + // test + extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); - // verify - verifyNoInteractions(networkService); - verifyNoInteractions(mockExtensionApi); + // verify + verifyNoInteractions(networkService); + verifyNoInteractions(mockExtensionApi); + }); } @Test public void testHandleLocationsDisplayed_NoRequest_When_networkServicesIsNotAvailable() { - // setup - extension = new TargetExtension(mockExtensionApi, deviceInforming, null, uiService, targetState, targetPreviewManager, requestBuilder, responseParser); - - // test - extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); - - // verify - verifyNoInteractions(networkService); - verify(mockExtensionApi, never()).createSharedState(any(), any()); - verify(mockExtensionApi, never()).dispatch(any()); + runWithMockedServiceProvider( + () -> { + // setup + extension = + new TargetExtension( + mockExtensionApi, + targetState, + targetPreviewManager, + requestBuilder, + responseParser); + + // test + extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); + + // verify + verifyNoInteractions(networkService); + verify(mockExtensionApi, never()).createSharedState(any(), any()); + verify(mockExtensionApi, never()).dispatch(any()); + }); } @Test public void testHandleLocationsDisplayed_NoRequest_When_TargetRequestBuilderIsNotAvailable() { - // setup - extension = new TargetExtension(mockExtensionApi, deviceInforming, networkService, uiService, targetState, targetPreviewManager, null, responseParser); - - // test - extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); - - // verify - verifyNoInteractions(networkService); - verify(mockExtensionApi, never()).createSharedState(any(), any()); - verify(mockExtensionApi, never()).dispatch(any()); + runWithMockedServiceProvider( + () -> { + // setup + extension = + new TargetExtension( + mockExtensionApi, + targetState, + targetPreviewManager, + null, + responseParser); + + // test + extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); + + // verify + verifyNoInteractions(networkService); + verify(mockExtensionApi, never()).createSharedState(any(), any()); + verify(mockExtensionApi, never()).dispatch(any()); + }); } @Test public void testHandleLocationsDisplayed_NoRequest_When_NoMboxes() { - // test - extension.handleTargetRequestContentEvent(locationsDisplayedEvent(0)); - - // verify - verifyNoInteractions(networkService); - verifyNoInteractions(mockExtensionApi); + runWithMockedServiceProvider( + () -> { + // test + extension.handleTargetRequestContentEvent(locationsDisplayedEvent(0)); + + // verify + verifyNoInteractions(networkService); + verifyNoInteractions(mockExtensionApi); + }); } @Test public void testHandleLocationsDisplayed_sendsCorrectNetworkRequest() throws JSONException { - // setup - setEventHubSharedState(); - when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(3)); - when(targetState.getLoadedMbox()).thenReturn(getMboxData(1)); - when(responseParser.getAnalyticsForTargetPayload(any(), any())).thenReturn(a4tParams); - when(targetState.getNotifications()).thenReturn(new ArrayList() {{ - add(validJSONObject()); - }}); - - // test - extension.handleTargetRequestContentEvent(locationsDisplayedEvent(3)); - - // verify - verify(targetState, times(2)).addNotification(any()); - verify(mockExtensionApi, times(2)).dispatch(any()); - verify(networkService).connectAsync(networkRequestCaptor.capture(), networkCallbackCaptor.capture()); - assertEquals("https://" + MOCKED_TARGET_SERVER + "/rest/v1/delivery/?client=" + MOCKED_CLIENT_CODE + "&sessionId=" + MOCK_SESSION_ID, networkRequestCaptor.getValue().getUrl()); - assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); - final Map headers = networkRequestCaptor.getValue().getHeaders(); - assertEquals(3, headers.size()); - assertEquals("application/json", headers.get("Content-Type")); - assertEquals("AdobeTargetMobile-Android", headers.get("X-EXC-SDK")); - assertEquals(String.format("%s+%s", "x.y.z", extension.getVersion()), headers.get("X-EXC-SDK-Version")); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getReadTimeout(), 0); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getConnectTimeout(), 0); + runWithMockedServiceProvider( + () -> { + try { + // setup + setEventHubSharedState(); + when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(3)); + when(targetState.getLoadedMbox()).thenReturn(getMboxData(1)); + when(responseParser.getAnalyticsForTargetPayload(any(), any())) + .thenReturn(a4tParams); + when(targetState.getNotifications()) + .thenReturn( + new ArrayList() { + { + add(validJSONObject()); + } + }); + + // test + extension.handleTargetRequestContentEvent(locationsDisplayedEvent(3)); + + // verify + verify(targetState, times(2)).addNotification(any()); + verify(mockExtensionApi, times(2)).dispatch(any()); + verify(networkService) + .connectAsync( + networkRequestCaptor.capture(), + networkCallbackCaptor.capture()); + assertEquals( + "https://" + + MOCKED_TARGET_SERVER + + "/rest/v1/delivery/?client=" + + MOCKED_CLIENT_CODE + + "&sessionId=" + + MOCK_SESSION_ID, + networkRequestCaptor.getValue().getUrl()); + assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); + final Map headers = + networkRequestCaptor.getValue().getHeaders(); + assertEquals(3, headers.size()); + assertEquals("application/json", headers.get("Content-Type")); + assertEquals("AdobeTargetMobile-Android", headers.get("X-EXC-SDK")); + assertEquals( + String.format("%s+%s", "x.y.z", extension.getVersion()), + headers.get("X-EXC-SDK-Version")); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getReadTimeout(), + 0); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getConnectTimeout(), + 0); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }); } @Test - public void testHandleLocationsDisplayed_notificationsNotCleared_When_ConnectionIsNull() throws JSONException { - // test - when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); - when(targetState.getNotifications()).thenReturn(new ArrayList() {{ - add(validJSONObject()); - }}); - - // verify - extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(null); - - // verify that the notifications are not cleared - verify(targetState, never()).clearNotifications(); + public void testHandleLocationsDisplayed_notificationsNotCleared_When_ConnectionIsNull() + throws JSONException { + runWithMockedServiceProvider( + () -> { + try { + // test + when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); + when(targetState.getNotifications()) + .thenReturn( + new ArrayList() { + { + add(validJSONObject()); + } + }); + + // verify + extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(null); + + // verify that the notifications are not cleared + verify(targetState, never()).clearNotifications(); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }); } @Test - public void testHandleLocationsDisplayed_notificationsNotCleared_When_ResponseJsonIsNull() throws JSONException { - // test - when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); - when(targetState.getNotifications()).thenReturn(new ArrayList() {{ - add(validJSONObject()); - }}); - when(responseParser.parseResponseToJson(any())).thenReturn(null); - - // verify - extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify that the notifications are not cleared - verify(targetState, never()).clearNotifications(); + public void testHandleLocationsDisplayed_notificationsNotCleared_When_ResponseJsonIsNull() + throws JSONException { + runWithMockedServiceProvider( + () -> { + try { + // test + when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); + when(targetState.getNotifications()) + .thenReturn( + new ArrayList() { + { + add(validJSONObject()); + } + }); + when(responseParser.parseResponseToJson(any())).thenReturn(null); + + // verify + extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify that the notifications are not cleared + verify(targetState, never()).clearNotifications(); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }); } @Test - public void testHandleLocationsDisplayed_notificationsNotCleared_When_ResponseNot200OK() throws JSONException { - // test - when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); - when(targetState.getNotifications()).thenReturn(new ArrayList() {{ - add(validJSONObject()); - }}); - when(connecting.getResponseCode()).thenReturn(HttpURLConnection.HTTP_BAD_REQUEST); - - // verify - extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify that the notifications are not cleared - verify(targetState, never()).clearNotifications(); + public void testHandleLocationsDisplayed_notificationsNotCleared_When_ResponseNot200OK() + throws JSONException { + runWithMockedServiceProvider( + () -> { + try { + // test + when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); + when(targetState.getNotifications()) + .thenReturn( + new ArrayList() { + { + add(validJSONObject()); + } + }); + when(connecting.getResponseCode()) + .thenReturn(HttpURLConnection.HTTP_BAD_REQUEST); + + // verify + extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify that the notifications are not cleared + verify(targetState, never()).clearNotifications(); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }); } @Test - public void testHandleLocationsDisplayed_notificationsNotCleared_When_ResponseError() throws JSONException { - // test - when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); - when(targetState.getNotifications()).thenReturn(new ArrayList() {{ - add(validJSONObject()); - }}); - when(responseParser.getErrorMessage(any())).thenReturn("anyError"); - - // verify - extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify that the notifications are not cleared - verify(targetState, never()).clearNotifications(); + public void testHandleLocationsDisplayed_notificationsNotCleared_When_ResponseError() + throws JSONException { + runWithMockedServiceProvider( + () -> { + try { + // test + when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); + when(targetState.getNotifications()) + .thenReturn( + new ArrayList() { + { + add(validJSONObject()); + } + }); + when(responseParser.getErrorMessage(any())).thenReturn("anyError"); + + // verify + extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify that the notifications are not cleared + verify(targetState, never()).clearNotifications(); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }); } @Test - public void testHandleLocationsDisplayed_notificationsCleared_When_validResponse() throws JSONException { - // test - when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); - when(targetState.getNotifications()).thenReturn(new ArrayList() {{ - add(validJSONObject()); - }}); - - // verify - extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); - verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); - networkCallbackCaptor.getValue().call(connecting); - - // verify that the notifications are not cleared - verify(targetState).clearNotifications(); - verify(targetState).updateEdgeHost(any()); - verify(targetState).updateSessionTimestamp(eq(false)); - verify(mockExtensionApi).createSharedState(any(), any()); + public void testHandleLocationsDisplayed_notificationsCleared_When_validResponse() + throws JSONException { + runWithMockedServiceProvider( + () -> { + try { + // test + when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); + when(targetState.getNotifications()) + .thenReturn( + new ArrayList() { + { + add(validJSONObject()); + } + }); + + // verify + extension.handleTargetRequestContentEvent(locationsDisplayedEvent(1)); + verify(networkService).connectAsync(any(), networkCallbackCaptor.capture()); + networkCallbackCaptor.getValue().call(connecting); + + // verify that the notifications are not cleared + verify(targetState).clearNotifications(); + verify(targetState).updateEdgeHost(any()); + verify(targetState).updateSessionTimestamp(eq(false)); + verify(mockExtensionApi).createSharedState(any(), any()); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }); } - //********************************************************************************************** + // ********************************************************************************************** // handleLocationClicked - //********************************************************************************************** + // ********************************************************************************************** @Test public void testHandleLocationsClicked_NoRequest_When_OptOut() { - // test - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.OPT_OUT); + runWithMockedServiceProvider( + () -> { + // test + when(targetState.getMobilePrivacyStatus()) + .thenReturn(MobilePrivacyStatus.OPT_OUT); - // verify - extension.handleTargetRequestContentEvent(locationsClickedEvent("mbox1")); + // verify + extension.handleTargetRequestContentEvent(locationsClickedEvent("mbox1")); - // verify network call not made - verifyNoInteractions(networkService); + // verify network call not made + verifyNoInteractions(networkService); + }); } @Test public void testHandleLocationsClicked_NoRequest_When_ClientCodeIsEmpty() { - // test - when(targetState.getClientCode()).thenReturn(""); + runWithMockedServiceProvider( + () -> { + // test + when(targetState.getClientCode()).thenReturn(""); - // verify - extension.handleTargetRequestContentEvent(locationsClickedEvent("mbox1")); + // verify + extension.handleTargetRequestContentEvent(locationsClickedEvent("mbox1")); - // verify network call not made - verifyNoInteractions(networkService); + // verify network call not made + verifyNoInteractions(networkService); + }); } @Test public void testHandleLocationsClicked_NoRequest_When_mboxNull() { - // verify - extension.handleTargetRequestContentEvent(locationsClickedEvent(null)); + runWithMockedServiceProvider( + () -> { + // verify + extension.handleTargetRequestContentEvent(locationsClickedEvent(null)); - // verify network call not made - verifyNoInteractions(networkService); + // verify network call not made + verifyNoInteractions(networkService); + }); } @Test public void testHandleLocationsClicked_NoRequest_When_mboxNameEmpty() { - // verify - extension.handleTargetRequestContentEvent(locationsClickedEvent("")); + runWithMockedServiceProvider( + () -> { + // verify + extension.handleTargetRequestContentEvent(locationsClickedEvent("")); - // verify network call not made - verifyNoInteractions(networkService); + // verify network call not made + verifyNoInteractions(networkService); + }); } @Test public void testHandleLocationsClicked_NoRequest_When_mboxNotPresentInPrefetchedOrLoadedMbox() { - // verify - extension.handleTargetRequestContentEvent(locationsClickedEvent("mbox1")); + runWithMockedServiceProvider( + () -> { + // verify + extension.handleTargetRequestContentEvent(locationsClickedEvent("mbox1")); - // verify network call not made - verifyNoInteractions(networkService); + // verify network call not made + verifyNoInteractions(networkService); + }); } @Test - public void testHandleLocationsClicked_NoRequest_when_clickMetricNotAvailable() throws JSONException { - // setup - when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); - when(responseParser.getClickMetric(any())).thenReturn(null); + public void testHandleLocationsClicked_NoRequest_when_clickMetricNotAvailable() + throws JSONException { + runWithMockedServiceProvider( + () -> { + try { + // setup + when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); + when(responseParser.getClickMetric(any())).thenReturn(null); - // verify - extension.handleTargetRequestContentEvent(locationsClickedEvent("mbox1")); + // verify + extension.handleTargetRequestContentEvent(locationsClickedEvent("mbox1")); - // verify network call not made - verifyNoInteractions(networkService); + // verify network call not made + verifyNoInteractions(networkService); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }); } @Test public void testHandleLocationsClicked_sendsCorrectData() throws JSONException { - // setup - setEventHubSharedState(); - when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); - when(responseParser.getClickMetric(any())).thenReturn(validJSONObject()); - when(requestBuilder.getClickNotificationJsonObject(any(), any(), anyLong(), any())).thenReturn(validJSONObject()); - when(responseParser.getAnalyticsForTargetPayload(any(), any())).thenReturn(a4tParams); - when(responseParser.preprocessAnalyticsForTargetPayload(any(), any())).thenReturn(a4tParams); - - // verify - extension.handleTargetRequestContentEvent(locationsClickedEvent("mbox0")); - - // verify network - // verify notifications are added - // verify analytics4target event is dispatched - verify(targetState, times(1)).addNotification(any()); - verify(mockExtensionApi, times(1)).dispatch(any()); - verify(networkService).connectAsync(networkRequestCaptor.capture(), networkCallbackCaptor.capture()); - assertEquals("https://" + MOCKED_TARGET_SERVER + "/rest/v1/delivery/?client=" + MOCKED_CLIENT_CODE + "&sessionId=" + MOCK_SESSION_ID, networkRequestCaptor.getValue().getUrl()); - assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); - final Map headers = networkRequestCaptor.getValue().getHeaders(); - assertEquals(3, headers.size()); - assertEquals("application/json", headers.get("Content-Type")); - assertEquals("AdobeTargetMobile-Android", headers.get("X-EXC-SDK")); - assertEquals(String.format("%s+%s", "x.y.z", extension.getVersion()), headers.get("X-EXC-SDK-Version")); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getReadTimeout(), 0); - assertEquals(MOCK_NETWORK_TIMEOUT, networkRequestCaptor.getValue().getConnectTimeout(), 0); - } - - //********************************************************************************************** - // handleConfigurationResponseContentEvent - //********************************************************************************************** + runWithMockedServiceProvider( + () -> { + try { + // setup + setEventHubSharedState(); + when(targetState.getPrefetchedMbox()).thenReturn(getMboxData(1)); + when(responseParser.getClickMetric(any())).thenReturn(validJSONObject()); + when(requestBuilder.getClickNotificationJsonObject( + any(), any(), anyLong(), any())) + .thenReturn(validJSONObject()); + when(responseParser.getAnalyticsForTargetPayload(any(), any())) + .thenReturn(a4tParams); + when(responseParser.preprocessAnalyticsForTargetPayload(any(), any())) + .thenReturn(a4tParams); + + // verify + extension.handleTargetRequestContentEvent(locationsClickedEvent("mbox0")); + + // verify network + // verify notifications are added + // verify analytics4target event is dispatched + verify(targetState, times(1)).addNotification(any()); + verify(mockExtensionApi, times(1)).dispatch(any()); + verify(networkService) + .connectAsync( + networkRequestCaptor.capture(), + networkCallbackCaptor.capture()); + assertEquals( + "https://" + + MOCKED_TARGET_SERVER + + "/rest/v1/delivery/?client=" + + MOCKED_CLIENT_CODE + + "&sessionId=" + + MOCK_SESSION_ID, + networkRequestCaptor.getValue().getUrl()); + assertEquals(HttpMethod.POST, networkRequestCaptor.getValue().getMethod()); + final Map headers = + networkRequestCaptor.getValue().getHeaders(); + assertEquals(3, headers.size()); + assertEquals("application/json", headers.get("Content-Type")); + assertEquals("AdobeTargetMobile-Android", headers.get("X-EXC-SDK")); + assertEquals( + String.format("%s+%s", "x.y.z", extension.getVersion()), + headers.get("X-EXC-SDK-Version")); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getReadTimeout(), + 0); + assertEquals( + MOCK_NETWORK_TIMEOUT, + networkRequestCaptor.getValue().getConnectTimeout(), + 0); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }); + } + // ********************************************************************************************** + // handleConfigurationResponseContentEvent + // ********************************************************************************************** @Test public void testHandleConfigurationResponseContentEvent_whenPrivacyOptedOut() { - // setup - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.OPT_OUT); - - // test - final Event event = noEventDataEvent(); - extension.handleConfigurationResponseContentEvent(event); - - // verify - verify(targetState, times(2)).updateEdgeHost(null); - verify(targetState).resetSession(); - verify(targetState).updateTntId(null); - verify(targetState).updateThirdPartyId(null); - verify(mockExtensionApi).createSharedState(eq(targetSharedState), eq(event)); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getMobilePrivacyStatus()) + .thenReturn(MobilePrivacyStatus.OPT_OUT); + + // test + final Event event = noEventDataEvent(); + extension.handleConfigurationResponseContentEvent(event); + + // verify + verify(targetState, times(2)).updateEdgeHost(null); + verify(targetState).resetSession(); + verify(targetState).updateTntId(null); + verify(targetState).updateThirdPartyId(null); + verify(mockExtensionApi).createSharedState(eq(targetSharedState), eq(event)); + }); } @Test public void testHandleConfigurationResponseContentEvent_whenPrivacyOptedIn() { - // setup - when(targetState.getMobilePrivacyStatus()).thenReturn(MobilePrivacyStatus.OPT_IN); - - // test - extension.handleConfigurationResponseContentEvent(noEventDataEvent()); - - // verify - verify(targetState, never()).updateEdgeHost(any()); - verify(targetState, never()).resetSession(); - verify(targetState, never()).updateTntId(any()); - verify(targetState, never()).updateThirdPartyId(any()); - verify(mockExtensionApi, never()).createSharedState(any(), any()); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getMobilePrivacyStatus()) + .thenReturn(MobilePrivacyStatus.OPT_IN); + + // test + extension.handleConfigurationResponseContentEvent(noEventDataEvent()); + + // verify + verify(targetState, never()).updateEdgeHost(any()); + verify(targetState, never()).resetSession(); + verify(targetState, never()).updateTntId(any()); + verify(targetState, never()).updateThirdPartyId(any()); + verify(mockExtensionApi, never()).createSharedState(any(), any()); + }); } - //********************************************************************************************** + // ********************************************************************************************** // TargetIdentitiesGetter - //********************************************************************************************** + // ********************************************************************************************** @Test public void testGetTargetIdentities_whenAllIDPresent() { - // setup - when(targetState.getThirdPartyId()).thenReturn(MOCK_THIRD_PARTY_ID); - when(targetState.getTntId()).thenReturn(MOCK_TNT_ID); - when(targetState.getSessionId()).thenReturn(MOCK_SESSION_ID); - - // test - extension.handleTargetRequestIdentityEvent(noEventDataEvent()); - - // verify - verify(mockExtensionApi).dispatch(eventArgumentCaptor.capture()); - final Event capturedEvent = eventArgumentCaptor.getValue(); - assertEquals(EventType.TARGET, capturedEvent.getType()); - assertEquals(EventSource.RESPONSE_IDENTITY, capturedEvent.getSource()); - assertEquals(EventType.TARGET, capturedEvent.getType()); - assertEquals(MOCK_THIRD_PARTY_ID, capturedEvent.getEventData().get(EventDataKeys.THIRD_PARTY_ID)); - assertEquals(MOCK_TNT_ID, capturedEvent.getEventData().get(EventDataKeys.TNT_ID)); - assertEquals(MOCK_SESSION_ID, capturedEvent.getEventData().get(EventDataKeys.SESSION_ID)); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getThirdPartyId()).thenReturn(MOCK_THIRD_PARTY_ID); + when(targetState.getTntId()).thenReturn(MOCK_TNT_ID); + when(targetState.getSessionId()).thenReturn(MOCK_SESSION_ID); + + // test + extension.handleTargetRequestIdentityEvent(noEventDataEvent()); + + // verify + verify(mockExtensionApi).dispatch(eventArgumentCaptor.capture()); + final Event capturedEvent = eventArgumentCaptor.getValue(); + assertEquals(EventType.TARGET, capturedEvent.getType()); + assertEquals(EventSource.RESPONSE_IDENTITY, capturedEvent.getSource()); + assertEquals(EventType.TARGET, capturedEvent.getType()); + assertEquals( + MOCK_THIRD_PARTY_ID, + capturedEvent.getEventData().get(EventDataKeys.THIRD_PARTY_ID)); + assertEquals( + MOCK_TNT_ID, capturedEvent.getEventData().get(EventDataKeys.TNT_ID)); + assertEquals( + MOCK_SESSION_ID, + capturedEvent.getEventData().get(EventDataKeys.SESSION_ID)); + }); } - @Test public void testGetTargetIdentities_whenNullTntIDAndThirdPartyID() { - // setup - when(targetState.getThirdPartyId()).thenReturn(null); - when(targetState.getTntId()).thenReturn(null); - when(targetState.getSessionId()).thenReturn(null); - - // test - extension.handleTargetRequestIdentityEvent(noEventDataEvent()); - - // verify - verify(mockExtensionApi).dispatch(eventArgumentCaptor.capture()); - final Event capturedEvent = eventArgumentCaptor.getValue(); - assertEquals(EventType.TARGET, capturedEvent.getType()); - assertEquals(EventSource.RESPONSE_IDENTITY, capturedEvent.getSource()); - assertEquals(EventType.TARGET, capturedEvent.getType()); - assertFalse(capturedEvent.getEventData().containsKey(EventDataKeys.THIRD_PARTY_ID)); - assertFalse(capturedEvent.getEventData().containsKey(EventDataKeys.TNT_ID)); - assertEquals(targetState.getSessionId(), capturedEvent.getEventData().get(EventDataKeys.SESSION_ID)); + runWithMockedServiceProvider( + () -> { + // setup + when(targetState.getThirdPartyId()).thenReturn(null); + when(targetState.getTntId()).thenReturn(null); + when(targetState.getSessionId()).thenReturn(null); + + // test + extension.handleTargetRequestIdentityEvent(noEventDataEvent()); + + // verify + verify(mockExtensionApi).dispatch(eventArgumentCaptor.capture()); + final Event capturedEvent = eventArgumentCaptor.getValue(); + assertEquals(EventType.TARGET, capturedEvent.getType()); + assertEquals(EventSource.RESPONSE_IDENTITY, capturedEvent.getSource()); + assertEquals(EventType.TARGET, capturedEvent.getType()); + assertFalse( + capturedEvent.getEventData().containsKey(EventDataKeys.THIRD_PARTY_ID)); + assertFalse(capturedEvent.getEventData().containsKey(EventDataKeys.TNT_ID)); + assertEquals( + targetState.getSessionId(), + capturedEvent.getEventData().get(EventDataKeys.SESSION_ID)); + }); } // ======================================================================================== // Private Helper methods // ======================================================================================== - private void setConfigurationSharedState(final String clientCode, - final Integer timeout, - final String privacyStatus, - final boolean previewEnabled, - final String targetServer) { + private void setConfigurationSharedState( + final String clientCode, + final Integer timeout, + final String privacyStatus, + final boolean previewEnabled, + final String targetServer) { HashMap configData = new HashMap<>(); configData.put("target.clientCode", clientCode); configData.put("target.timeout", timeout); @@ -2066,19 +3104,22 @@ private void setConfigurationSharedState(final String clientCode, configData.put("target.previewEnabled", previewEnabled); configData.put("target.server", targetServer); - when(mockExtensionApi.getSharedState(eq("com.adobe.module.configuration"), any(), anyBoolean(), any())) + when(mockExtensionApi.getSharedState( + eq("com.adobe.module.configuration"), any(), anyBoolean(), any())) .thenReturn(new SharedStateResult(SharedStateStatus.SET, configData)); } private void setLifecycleSharedState() { HashMap lifecycleData = new HashMap<>(); lifecycleData.put("lifecyclecontextdata", lifecycleSharedState); - when(mockExtensionApi.getSharedState(eq("com.adobe.module.lifecycle"), any(), anyBoolean(), any())) + when(mockExtensionApi.getSharedState( + eq("com.adobe.module.lifecycle"), any(), anyBoolean(), any())) .thenReturn(new SharedStateResult(SharedStateStatus.SET, lifecycleData)); } private void setIdentitySharedState() { - when(mockExtensionApi.getSharedState(eq("com.adobe.module.identity"), any(), anyBoolean(), any())) + when(mockExtensionApi.getSharedState( + eq("com.adobe.module.identity"), any(), anyBoolean(), any())) .thenReturn(new SharedStateResult(SharedStateStatus.SET, identitySharedState)); } @@ -2087,7 +3128,8 @@ private void setEventHubSharedState() { } private void setEventHubSharedState(final Map sharedState) { - when(mockExtensionApi.getSharedState(eq("com.adobe.module.eventhub"), any(), anyBoolean(), any())) + when(mockExtensionApi.getSharedState( + eq("com.adobe.module.eventhub"), any(), anyBoolean(), any())) .thenReturn(new SharedStateResult(SharedStateStatus.SET, sharedState)); } @@ -2102,24 +3144,28 @@ Map getTargetRawRequestForExecute(final int count) { final int mboxIndex = i; final String mboxName = "mbox" + i; - final Map executeMbox = new HashMap() { - { - put("index", mboxIndex); - put("name", mboxName); - } - }; + final Map executeMbox = + new HashMap() { + { + put("index", mboxIndex); + put("name", mboxName); + } + }; executeMboxes.add(executeMbox); } - final Map request = new HashMap() { - { - put("execute", new HashMap() { + final Map request = + new HashMap() { { - put("mboxes", executeMboxes); + put( + "execute", + new HashMap() { + { + put("mboxes", executeMboxes); + } + }); } - }); - } - }; + }; return request; } @@ -2130,24 +3176,28 @@ Map getTargetRawRequestForPrefetch(int count) { final int mboxIndex = i; final String mboxName = "mbox" + i; - final Map executeMbox = new HashMap() { - { - put("index", mboxIndex); - put("name", mboxName); - } - }; + final Map executeMbox = + new HashMap() { + { + put("index", mboxIndex); + put("name", mboxName); + } + }; executeMboxes.add(executeMbox); } - final Map request = new HashMap() { - { - put("prefetch", new HashMap() { + final Map request = + new HashMap() { { - put("mboxes", executeMboxes); + put( + "prefetch", + new HashMap() { + { + put("mboxes", executeMboxes); + } + }); } - }); - } - }; + }; return request; } @@ -2157,31 +3207,37 @@ Map getTargetRawRequestForNotifications(int count) { for (int i = 0; i < count; i++) { final String notificationId = String.valueOf(i); final String mboxName = "mbox" + i; - final Map notification = new HashMap() { - { - put("id", notificationId); - put("timestamp", System.currentTimeMillis()); - put("type", "click"); - put("mbox", new HashMap() { - { - put("name", mboxName); - } - }); - put("tokens", new ArrayList() { + final Map notification = + new HashMap() { { - add("randomToken"); + put("id", notificationId); + put("timestamp", (long) (System.currentTimeMillis())); + put("type", "click"); + put( + "mbox", + new HashMap() { + { + put("name", mboxName); + } + }); + put( + "tokens", + new ArrayList() { + { + add("randomToken"); + } + }); } - }); - } - }; + }; notifications.add(notification); } - final Map request = new HashMap() { - { - put("notifications", notifications); - } - }; + final Map request = + new HashMap() { + { + put("notifications", notifications); + } + }; return request; } @@ -2190,11 +3246,15 @@ List getTargetRequestList(int count) { for (int i = 0; i < count; i++) { final String mboxName = "mbox" + i; - TargetRequest targetRequest = new TargetRequest(mboxName, null, "default", new AdobeCallback() { - @Override - public void call(String value) { - } - }); + TargetRequest targetRequest = + new TargetRequest( + mboxName, + null, + "default", + new AdobeCallback() { + @Override + public void call(String value) {} + }); targetRequestList.add(targetRequest); } @@ -2206,15 +3266,18 @@ List getTargetRequestListWithContentWithDataCallback(int count) { for (int i = 0; i < count; i++) { final String mboxName = "mbox" + i; - TargetRequest targetRequest = new TargetRequest(mboxName, null, "default", new AdobeTargetDetailedCallback() { - @Override - public void call(String content, Map data) { - } - - @Override - public void fail(AdobeError var1) { - } - }); + TargetRequest targetRequest = + new TargetRequest( + mboxName, + null, + "default", + new AdobeTargetDetailedCallback() { + @Override + public void call(String content, Map data) {} + + @Override + public void fail(AdobeError var1) {} + }); targetRequestList.add(targetRequest); } @@ -2242,7 +3305,8 @@ private Event noEventDataEvent() { return testEvent; } - private Event loadRequestEvent(final List targetRequestList, final TargetParameters parameters) { + private Event loadRequestEvent( + final List targetRequestList, final TargetParameters parameters) { final List mboxRequestListCopy = new ArrayList<>(targetRequestList); final List> flattenedLocationRequests = new ArrayList<>(); final Map tempIdToRequestMap = new HashMap<>(); @@ -2263,16 +3327,19 @@ private Event loadRequestEvent(final List targetRequestList, fina eventData.put(EventDataKeys.TARGET_PARAMETERS, parameters.toEventData()); } - final Event event = new Event.Builder(EventName.LOAD_REQUEST, - EventType.TARGET, - EventSource.REQUEST_CONTENT) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.LOAD_REQUEST, + EventType.TARGET, + EventSource.REQUEST_CONTENT) + .setEventData(eventData) + .build(); return event; } - private Event prefetchContentEvent(final List targetPrefetchList, final TargetParameters parameters) { + private Event prefetchContentEvent( + final List targetPrefetchList, final TargetParameters parameters) { final List prefetchRequestListCopy = new ArrayList<>(targetPrefetchList); final List> flattenedPrefetchRequests = new ArrayList<>(); for (final TargetPrefetch request : prefetchRequestListCopy) { @@ -2288,11 +3355,13 @@ private Event prefetchContentEvent(final List targetPrefetchList eventData.put(EventDataKeys.TARGET_PARAMETERS, parameters.toEventData()); } - final Event event = new Event.Builder(EventName.PREFETCH_REQUEST, - EventType.TARGET, - EventSource.REQUEST_CONTENT) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.PREFETCH_REQUEST, + EventType.TARGET, + EventSource.REQUEST_CONTENT) + .setEventData(eventData) + .build(); return event; } @@ -2301,24 +3370,29 @@ private Event rawRequestExecuteEvent(final int count) { final Map eventData = new HashMap<>(getTargetRawRequestForExecute(count)); eventData.put(EventDataKeys.IS_RAW_EVENT, true); - final Event event = new Event.Builder(EventName.TARGET_RAW_REQUEST, - EventType.TARGET, - EventSource.REQUEST_CONTENT) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.TARGET_RAW_REQUEST, + EventType.TARGET, + EventSource.REQUEST_CONTENT) + .setEventData(eventData) + .build(); return event; } private Event getTargetRawRequestForNotificationsEvent(final int count) { - final Map eventData = new HashMap<>(getTargetRawRequestForNotifications(count)); + final Map eventData = + new HashMap<>(getTargetRawRequestForNotifications(count)); eventData.put(EventDataKeys.IS_RAW_EVENT, true); - final Event event = new Event.Builder(EventName.TARGET_RAW_REQUEST, - EventType.TARGET, - EventSource.REQUEST_CONTENT) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.TARGET_RAW_REQUEST, + EventType.TARGET, + EventSource.REQUEST_CONTENT) + .setEventData(eventData) + .build(); return event; } @@ -2327,9 +3401,10 @@ private Event setThirdPartyIdEvent(final String thirdPartyId) { final Map eventData = new HashMap<>(); eventData.put(EventDataKeys.THIRD_PARTY_ID, thirdPartyId); - return new Event.Builder(EventName.SET_THIRD_PARTY_ID, - EventType.TARGET, - EventSource.REQUEST_IDENTITY) + return new Event.Builder( + EventName.SET_THIRD_PARTY_ID, + EventType.TARGET, + EventSource.REQUEST_IDENTITY) .setEventData(eventData) .build(); } @@ -2338,9 +3413,8 @@ private Event setTntIdEvent(final String tntId) { final Map eventData = new HashMap<>(); eventData.put(EventDataKeys.TNT_ID, tntId); - return new Event.Builder(EventName.SET_TNT_ID, - EventType.TARGET, - EventSource.REQUEST_IDENTITY) + return new Event.Builder( + EventName.SET_TNT_ID, EventType.TARGET, EventSource.REQUEST_IDENTITY) .setEventData(eventData) .build(); } @@ -2349,9 +3423,8 @@ private Event setSessionIdEvent(final String sessionId) { final Map eventData = new HashMap<>(); eventData.put(EventDataKeys.SESSION_ID, sessionId); - return new Event.Builder(EventName.SET_SESSION_ID, - EventType.TARGET, - EventSource.REQUEST_IDENTITY) + return new Event.Builder( + EventName.SET_SESSION_ID, EventType.TARGET, EventSource.REQUEST_IDENTITY) .setEventData(eventData) .build(); } @@ -2360,9 +3433,7 @@ private Event previewDeeplinkEvent(final String deeplink) { final Map eventData = new HashMap<>(); eventData.put(EventDataKeys.DEEPLINK, deeplink); - return new Event.Builder("OS Deeplink Event", - EventType.GENERIC_DATA, - EventSource.OS) + return new Event.Builder("OS Deeplink Event", EventType.GENERIC_DATA, EventSource.OS) .setEventData(eventData) .build(); } @@ -2371,9 +3442,10 @@ public static Event previewRestartDeeplinkEvent(final String deepLink) { final Map eventData = new HashMap<>(); eventData.put(EventDataKeys.PREVIEW_RESTART_DEEP_LINK, deepLink); - return new Event.Builder(EventName.SET_PREVIEW_DEEPLINK, - EventType.TARGET, - EventSource.REQUEST_CONTENT) + return new Event.Builder( + EventName.SET_PREVIEW_DEEPLINK, + EventType.TARGET, + EventSource.REQUEST_CONTENT) .setEventData(eventData) .build(); } @@ -2382,11 +3454,13 @@ private Event resetExperienceEvent() { final Map eventData = new HashMap<>(); eventData.put(EventDataKeys.RESET_EXPERIENCE, true); - final Event event = new Event.Builder(EventName.REQUEST_RESET, - EventType.TARGET, - EventSource.REQUEST_RESET) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.REQUEST_RESET, + EventType.TARGET, + EventSource.REQUEST_RESET) + .setEventData(eventData) + .build(); return event; } @@ -2394,11 +3468,13 @@ private Event clearPrefetchCacheEvent() { final Map eventData = new HashMap<>(); eventData.put(EventDataKeys.CLEAR_PREFETCH_CACHE, true); - final Event event = new Event.Builder(EventName.CLEAR_PREFETCH_CACHE, - EventType.TARGET, - EventSource.REQUEST_RESET) - .setEventData(eventData) - .build(); + final Event event = + new Event.Builder( + EventName.CLEAR_PREFETCH_CACHE, + EventType.TARGET, + EventSource.REQUEST_RESET) + .setEventData(eventData) + .build(); return event; } @@ -2413,9 +3489,10 @@ private Event locationsDisplayedEvent(final int mboxCount) { eventData.put(EventDataKeys.MBOX_NAMES, mboxes); eventData.put(EventDataKeys.TARGET_PARAMETERS, targetParameters); - return new Event.Builder(EventName.LOCATIONS_DISPLAYED, - EventType.TARGET, - EventSource.REQUEST_CONTENT) + return new Event.Builder( + EventName.LOCATIONS_DISPLAYED, + EventType.TARGET, + EventSource.REQUEST_CONTENT) .setEventData(eventData) .build(); } @@ -2426,10 +3503,8 @@ private Event locationsClickedEvent(final String mboxName) { eventData.put(EventDataKeys.MBOX_NAME, mboxName); eventData.put(EventDataKeys.TARGET_PARAMETERS, targetParameters); - - return new Event.Builder(EventName.LOCATION_CLICKED, - EventType.TARGET, - EventSource.REQUEST_CONTENT) + return new Event.Builder( + EventName.LOCATION_CLICKED, EventType.TARGET, EventSource.REQUEST_CONTENT) .setEventData(eventData) .build(); } @@ -2439,23 +3514,27 @@ private Event locationsClickedEvent(final String mboxName) { // ======================================================================================== private String extractMboxContentFromEvent(final Event event) { - return DataReader.optString(event.getEventData(), - EventDataKeys.TARGET_CONTENT, - ""); + return DataReader.optString(event.getEventData(), EventDataKeys.TARGET_CONTENT, ""); } private Map extractResponseToken(final Event event) { - Map data = DataReader.optTypedMap(Map.class, event.getEventData(), EventDataKeys.TARGET_DATA_PAYLOAD, null); + Map data = + DataReader.optTypedMap( + Map.class, event.getEventData(), EventDataKeys.TARGET_DATA_PAYLOAD, null); return data.get(EventDataKeys.RESPONSE_TOKENS); } private Map extractAnalyticsPayload(final Event event) { - Map data = DataReader.optTypedMap(Map.class, event.getEventData(), EventDataKeys.TARGET_DATA_PAYLOAD, null); + Map data = + DataReader.optTypedMap( + Map.class, event.getEventData(), EventDataKeys.TARGET_DATA_PAYLOAD, null); return data.get(EventDataKeys.ANALYTICS_PAYLOAD); } private Map extractClickMetric(final Event event) { - Map data = DataReader.optTypedMap(Map.class, event.getEventData(), EventDataKeys.TARGET_DATA_PAYLOAD, null); + Map data = + DataReader.optTypedMap( + Map.class, event.getEventData(), EventDataKeys.TARGET_DATA_PAYLOAD, null); return data.get(EventDataKeys.CLICK_METRIC_ANALYTICS_PAYLOAD); } @@ -2499,8 +3578,7 @@ static final class EventDataKeys { static final String TARGET_CONTENT = "content"; static final String TARGET_DATA_PAYLOAD = "data"; - private EventDataKeys() { - } + private EventDataKeys() {} } static final class EventName { @@ -2521,7 +3599,6 @@ static final class EventName { static final String TARGET_RAW_REQUEST = "TargetRawRequest"; static final String TARGET_RAW_NOTIFICATIONS = "TargetRawNotifications"; - private EventName() { - } + private EventName() {} } -} \ No newline at end of file +} diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetOrderTests.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetOrderTests.java index 8061be0..a226dca 100644 --- a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetOrderTests.java +++ b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetOrderTests.java @@ -1,14 +1,13 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; @@ -16,38 +15,45 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import org.junit.Test; - import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +import org.junit.Test; public class TargetOrderTests { - final static String ORDER_ID_HAPPY_PATH = "orderId"; - final static double ORDER_TOTAL_HAPPY_PATH = 100.34; - protected final ArrayList PURCHASED_PRODUCT_IDS_HAPPY_PATH = new ArrayList() { - { - add("ppId"); - } - }; - - protected final TargetOrder ORDER_PARAMETERS_HAPPY_PATH = new TargetOrder("orderId", 100.34, new ArrayList() { - { - add("ppId"); - } - }); - - protected final Map ORDER_PARAMETERS_HAPPY_PATH_MAP = new HashMap() { - { - put("id", "orderId"); - put("purchasedProductIds", new ArrayList() { + static final String ORDER_ID_HAPPY_PATH = "orderId"; + static final double ORDER_TOTAL_HAPPY_PATH = 100.34; + protected final ArrayList PURCHASED_PRODUCT_IDS_HAPPY_PATH = + new ArrayList() { { add("ppId"); } - }); - put("total", 100.34); - } - }; + }; + + protected final TargetOrder ORDER_PARAMETERS_HAPPY_PATH = + new TargetOrder( + "orderId", + 100.34, + new ArrayList() { + { + add("ppId"); + } + }); + + protected final Map ORDER_PARAMETERS_HAPPY_PATH_MAP = + new HashMap() { + { + put("id", "orderId"); + put( + "purchasedProductIds", + new ArrayList() { + { + add("ppId"); + } + }); + put("total", 100.34); + } + }; @Test public void testTargetOrder_happy() { @@ -83,50 +89,59 @@ public void testFromEventData_emptyOrder() throws Exception { @Test public void testFromEventData_invalidOrderNullId() throws Exception { - final Map orderMap = new HashMap() { - { - put("id", null); - put("purchasedProductIds", new ArrayList() { + final Map orderMap = + new HashMap() { { - add("ppId"); + put("id", null); + put( + "purchasedProductIds", + new ArrayList() { + { + add("ppId"); + } + }); + put("total", 100.34); } - }); - put("total", 100.34); - } - }; + }; TargetOrder targetOrder = TargetOrder.fromEventData(orderMap); assertNull(targetOrder); } @Test public void testFromEventData_invalidOrderEmptyId() throws Exception { - final Map orderMap = new HashMap() { - { - put("id", ""); - put("purchasedProductIds", new ArrayList() { + final Map orderMap = + new HashMap() { { - add("ppId"); + put("id", ""); + put( + "purchasedProductIds", + new ArrayList() { + { + add("ppId"); + } + }); + put("total", 100.34); } - }); - put("total", 100.34); - } - }; + }; TargetOrder targetOrder = TargetOrder.fromEventData(orderMap); assertNull(targetOrder); } @Test public void testFromEventData_invalidOrderMissingId() throws Exception { - final Map orderMap = new HashMap() { - { - put("purchasedProductIds", new ArrayList() { + final Map orderMap = + new HashMap() { { - add("ppId"); + put( + "purchasedProductIds", + new ArrayList() { + { + add("ppId"); + } + }); + put("total", 100.34); } - }); - put("total", 100.34); - } - }; + }; TargetOrder targetOrder = TargetOrder.fromEventData(orderMap); assertNull(targetOrder); } diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetParametersTests.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetParametersTests.java index 7381cf8..6b3adee 100644 --- a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetParametersTests.java +++ b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetParametersTests.java @@ -1,14 +1,13 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; @@ -17,64 +16,74 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import org.junit.Test; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.junit.Test; public class TargetParametersTests { - protected final Map MBOX_PARAMETERS_HAPPY_PATH = new HashMap() { - { - put("one", "uno"); - put("two", "dos"); - put("three", "tres"); - } - }; + protected final Map MBOX_PARAMETERS_HAPPY_PATH = + new HashMap() { + { + put("one", "uno"); + put("two", "dos"); + put("three", "tres"); + } + }; protected final TargetProduct PRODUCT_PARAMETERS_HAPPY_PATH = new TargetProduct("pId", "cId"); - protected final Map PRODUCT_PARAMETERS_HAPPY_PATH_MAP = new HashMap() { - { - put("id", "pId"); - put("categoryId", "cId"); - } - }; - - protected final TargetOrder ORDER_PARAMETERS_HAPPY_PATH = new TargetOrder("orderId", 100.34, new ArrayList() { - { - add("ppId"); - } - }); - - protected final Map ORDER_PARAMETERS_HAPPY_PATH_MAP = new HashMap() { - { - put("id", "orderId"); - put("purchasedProductIds", new ArrayList() { + protected final Map PRODUCT_PARAMETERS_HAPPY_PATH_MAP = + new HashMap() { + { + put("id", "pId"); + put("categoryId", "cId"); + } + }; + + protected final TargetOrder ORDER_PARAMETERS_HAPPY_PATH = + new TargetOrder( + "orderId", + 100.34, + new ArrayList() { + { + add("ppId"); + } + }); + + protected final Map ORDER_PARAMETERS_HAPPY_PATH_MAP = + new HashMap() { { - add("ppId"); + put("id", "orderId"); + put( + "purchasedProductIds", + new ArrayList() { + { + add("ppId"); + } + }); + put("total", 100.34); } - }); - put("total", 100.34); - } - }; + }; - protected final Map PROFILE_PARAMETERS_HAPPY_PATH = new HashMap() { - { - put("profileKey1", "profileValue1"); - put("profileKey2", "profileValue2"); - } - }; + protected final Map PROFILE_PARAMETERS_HAPPY_PATH = + new HashMap() { + { + put("profileKey1", "profileValue1"); + put("profileKey2", "profileValue2"); + } + }; @Test public void testTargetParametersBuilder_happy() { - final TargetParameters targetParameters = new TargetParameters.Builder() - .product(PRODUCT_PARAMETERS_HAPPY_PATH) - .order(ORDER_PARAMETERS_HAPPY_PATH) - .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) - .parameters(MBOX_PARAMETERS_HAPPY_PATH) - .build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .product(PRODUCT_PARAMETERS_HAPPY_PATH) + .order(ORDER_PARAMETERS_HAPPY_PATH) + .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) + .parameters(MBOX_PARAMETERS_HAPPY_PATH) + .build(); assertNotNull(targetParameters); assertEquals(PROFILE_PARAMETERS_HAPPY_PATH, targetParameters.getProfileParameters()); assertEquals(MBOX_PARAMETERS_HAPPY_PATH, targetParameters.getParameters()); @@ -84,11 +93,12 @@ public void testTargetParametersBuilder_happy() { @Test public void testTargetParametersBuilder_noMboxParameters() { - final TargetParameters targetParameters = new TargetParameters.Builder() - .product(PRODUCT_PARAMETERS_HAPPY_PATH) - .order(ORDER_PARAMETERS_HAPPY_PATH) - .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) - .build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .product(PRODUCT_PARAMETERS_HAPPY_PATH) + .order(ORDER_PARAMETERS_HAPPY_PATH) + .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) + .build(); assertNotNull(targetParameters); assertEquals(0, targetParameters.getParameters().size()); assertEquals(PROFILE_PARAMETERS_HAPPY_PATH, targetParameters.getProfileParameters()); @@ -98,11 +108,12 @@ public void testTargetParametersBuilder_noMboxParameters() { @Test public void testTargetParametersBuilder_noProfileParameters() { - final TargetParameters targetParameters = new TargetParameters.Builder() - .product(PRODUCT_PARAMETERS_HAPPY_PATH) - .order(ORDER_PARAMETERS_HAPPY_PATH) - .parameters(MBOX_PARAMETERS_HAPPY_PATH) - .build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .product(PRODUCT_PARAMETERS_HAPPY_PATH) + .order(ORDER_PARAMETERS_HAPPY_PATH) + .parameters(MBOX_PARAMETERS_HAPPY_PATH) + .build(); assertNotNull(targetParameters); assertEquals(0, targetParameters.getProfileParameters().size()); assertEquals(MBOX_PARAMETERS_HAPPY_PATH, targetParameters.getParameters()); @@ -112,26 +123,27 @@ public void testTargetParametersBuilder_noProfileParameters() { @Test public void testTargetParametersBuilder_noOrderParameters() { - final TargetParameters targetParameters = new TargetParameters.Builder() - .product(PRODUCT_PARAMETERS_HAPPY_PATH) - .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) - .parameters(MBOX_PARAMETERS_HAPPY_PATH) - .build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .product(PRODUCT_PARAMETERS_HAPPY_PATH) + .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) + .parameters(MBOX_PARAMETERS_HAPPY_PATH) + .build(); assertNotNull(targetParameters); assertNull(targetParameters.getOrder()); assertEquals(PROFILE_PARAMETERS_HAPPY_PATH, targetParameters.getProfileParameters()); assertEquals(MBOX_PARAMETERS_HAPPY_PATH, targetParameters.getParameters()); assertEquals(PRODUCT_PARAMETERS_HAPPY_PATH, targetParameters.getProduct()); - } @Test public void testTargetParametersBuilder_noProductParameters() { - final TargetParameters targetParameters = new TargetParameters.Builder() - .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) - .order(ORDER_PARAMETERS_HAPPY_PATH) - .parameters(MBOX_PARAMETERS_HAPPY_PATH) - .build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) + .order(ORDER_PARAMETERS_HAPPY_PATH) + .parameters(MBOX_PARAMETERS_HAPPY_PATH) + .build(); assertNotNull(targetParameters); assertNull(targetParameters.getProduct()); assertEquals(PROFILE_PARAMETERS_HAPPY_PATH, targetParameters.getProfileParameters()); @@ -141,8 +153,7 @@ public void testTargetParametersBuilder_noProductParameters() { @Test public void testTargetParametersBuilder_default() { - final TargetParameters targetParameters = new TargetParameters.Builder() - .build(); + final TargetParameters targetParameters = new TargetParameters.Builder().build(); assertNotNull(targetParameters); assertNull(targetParameters.getProduct()); assertNull(targetParameters.getOrder()); @@ -152,12 +163,13 @@ public void testTargetParametersBuilder_default() { @Test public void testToEventData_happy() { - final TargetParameters targetParameters = new TargetParameters.Builder() - .product(PRODUCT_PARAMETERS_HAPPY_PATH) - .order(ORDER_PARAMETERS_HAPPY_PATH) - .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) - .parameters(MBOX_PARAMETERS_HAPPY_PATH) - .build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .product(PRODUCT_PARAMETERS_HAPPY_PATH) + .order(ORDER_PARAMETERS_HAPPY_PATH) + .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) + .parameters(MBOX_PARAMETERS_HAPPY_PATH) + .build(); final Map targetParametersMap = targetParameters.toEventData(); assertNotNull(targetParametersMap); assertEquals(MBOX_PARAMETERS_HAPPY_PATH, targetParametersMap.get("parameters")); @@ -174,7 +186,8 @@ public void testFromEventData_happy() { targetParametersMap.put("order", ORDER_PARAMETERS_HAPPY_PATH_MAP); targetParametersMap.put("product", PRODUCT_PARAMETERS_HAPPY_PATH_MAP); - final TargetParameters targetParameters = TargetParameters.fromEventData(targetParametersMap); + final TargetParameters targetParameters = + TargetParameters.fromEventData(targetParametersMap); assertNotNull(targetParameters); assertEquals(MBOX_PARAMETERS_HAPPY_PATH, targetParameters.getParameters()); assertEquals(PROFILE_PARAMETERS_HAPPY_PATH, targetParameters.getProfileParameters()); @@ -192,21 +205,21 @@ public void testFromEventData_nullOrEmptyMap() { @Test public void testMerge_happy() { final List targetParametersList = new ArrayList<>(); - final TargetParameters targetParamsWithProduct = new TargetParameters.Builder() - .product(PRODUCT_PARAMETERS_HAPPY_PATH) - .build(); - final TargetParameters targetParamsWithOrder = new TargetParameters.Builder() - .order(ORDER_PARAMETERS_HAPPY_PATH) - .build(); - final TargetParameters targetParamsWithProfileAndMboxParameters = new TargetParameters.Builder() - .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) - .parameters(MBOX_PARAMETERS_HAPPY_PATH) - .build(); + final TargetParameters targetParamsWithProduct = + new TargetParameters.Builder().product(PRODUCT_PARAMETERS_HAPPY_PATH).build(); + final TargetParameters targetParamsWithOrder = + new TargetParameters.Builder().order(ORDER_PARAMETERS_HAPPY_PATH).build(); + final TargetParameters targetParamsWithProfileAndMboxParameters = + new TargetParameters.Builder() + .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) + .parameters(MBOX_PARAMETERS_HAPPY_PATH) + .build(); targetParametersList.add(targetParamsWithProduct); targetParametersList.add(targetParamsWithOrder); targetParametersList.add(targetParamsWithProfileAndMboxParameters); - final TargetParameters mergedTargetParameters = TargetParameters.merge(targetParametersList); + final TargetParameters mergedTargetParameters = + TargetParameters.merge(targetParametersList); assertNotNull(mergedTargetParameters); assertEquals(PROFILE_PARAMETERS_HAPPY_PATH, mergedTargetParameters.getProfileParameters()); assertEquals(MBOX_PARAMETERS_HAPPY_PATH, mergedTargetParameters.getParameters()); @@ -217,27 +230,33 @@ public void testMerge_happy() { @Test public void testMerge_differentMboxParametersInList() { final List targetParametersList = new ArrayList<>(); - final TargetParameters targetParamsWithProfileAndMboxParameters = new TargetParameters.Builder() - .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) - .parameters(MBOX_PARAMETERS_HAPPY_PATH) - .build(); + final TargetParameters targetParamsWithProfileAndMboxParameters = + new TargetParameters.Builder() + .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) + .parameters(MBOX_PARAMETERS_HAPPY_PATH) + .build(); targetParametersList.add(targetParamsWithProfileAndMboxParameters); - final TargetParameters mergedTargetParameters = TargetParameters.merge(targetParametersList); + final TargetParameters mergedTargetParameters = + TargetParameters.merge(targetParametersList); assertNotNull(mergedTargetParameters); assertEquals(PROFILE_PARAMETERS_HAPPY_PATH, mergedTargetParameters.getProfileParameters()); assertEquals(MBOX_PARAMETERS_HAPPY_PATH, mergedTargetParameters.getParameters()); - final TargetParameters targetParametersWithMboxParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mboxkey", "mboxvalue"); - put("mboxkey2", "mboxvalue2"); - } - }).build(); + final TargetParameters targetParametersWithMboxParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mboxkey", "mboxvalue"); + put("mboxkey2", "mboxvalue2"); + } + }) + .build(); targetParametersList.add(targetParametersWithMboxParameters); - final TargetParameters mergedTargetParameters1 = TargetParameters.merge(targetParametersList); + final TargetParameters mergedTargetParameters1 = + TargetParameters.merge(targetParametersList); assertNotEquals(MBOX_PARAMETERS_HAPPY_PATH, mergedTargetParameters1.getParameters()); assertEquals(5, mergedTargetParameters1.getParameters().size()); diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPrefetchTests.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPrefetchTests.java index d95001e..d869dbf 100644 --- a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPrefetchTests.java +++ b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPrefetchTests.java @@ -1,14 +1,13 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; @@ -16,76 +15,88 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import org.junit.Test; - import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +import org.junit.Test; public class TargetPrefetchTests { protected final String MBOX_NAME_HAPPY_PATH = "name"; - protected final Map MBOX_PARAMETERS_HAPPY_PATH = new HashMap() { - { - put("one", "uno"); - put("two", "dos"); - put("three", "tres"); - } - }; - - protected final Map PROFILE_PARAMETERS_HAPPY_PATH = new HashMap() { - { - put("profileKey1", "profileValue1"); - put("profileKey2", "profileValue2"); - } - }; + protected final Map MBOX_PARAMETERS_HAPPY_PATH = + new HashMap() { + { + put("one", "uno"); + put("two", "dos"); + put("three", "tres"); + } + }; + + protected final Map PROFILE_PARAMETERS_HAPPY_PATH = + new HashMap() { + { + put("profileKey1", "profileValue1"); + put("profileKey2", "profileValue2"); + } + }; protected final TargetProduct PRODUCT_PARAMETERS_HAPPY_PATH = new TargetProduct("pId", "cId"); - protected final Map PRODUCT_PARAMETERS_HAPPY_PATH_MAP = new HashMap() { - { - put("id", "pId"); - put("categoryId", "cId"); - } - }; - - protected final TargetOrder ORDER_PARAMETERS_HAPPY_PATH = new TargetOrder("orderId", 100.34, new ArrayList() { - { - add("ppId"); - } - }); - - protected final Map ORDER_PARAMETERS_HAPPY_PATH_MAP = new HashMap() { - { - put("id", "orderId"); - put("purchasedProductIds", new ArrayList() { + protected final Map PRODUCT_PARAMETERS_HAPPY_PATH_MAP = + new HashMap() { + { + put("id", "pId"); + put("categoryId", "cId"); + } + }; + + protected final TargetOrder ORDER_PARAMETERS_HAPPY_PATH = + new TargetOrder( + "orderId", + 100.34, + new ArrayList() { + { + add("ppId"); + } + }); + + protected final Map ORDER_PARAMETERS_HAPPY_PATH_MAP = + new HashMap() { + { + put("id", "orderId"); + put( + "purchasedProductIds", + new ArrayList() { + { + add("ppId"); + } + }); + put("total", 100.34); + } + }; + + protected final TargetParameters TARGET_PARAMETERS_HAPPY_PATH = + new TargetParameters.Builder() + .parameters(MBOX_PARAMETERS_HAPPY_PATH) + .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) + .order(ORDER_PARAMETERS_HAPPY_PATH) + .product(PRODUCT_PARAMETERS_HAPPY_PATH) + .build(); + + protected final Map TARGET_PARAMETERS_HAPPY_PATH_MAP = + new HashMap() { { - add("ppId"); + put("parameters", MBOX_PARAMETERS_HAPPY_PATH); + put("profileParameters", PROFILE_PARAMETERS_HAPPY_PATH); + put("order", ORDER_PARAMETERS_HAPPY_PATH_MAP); + put("product", PRODUCT_PARAMETERS_HAPPY_PATH_MAP); } - }); - put("total", 100.34); - } - }; - - protected final TargetParameters TARGET_PARAMETERS_HAPPY_PATH = new TargetParameters.Builder() - .parameters(MBOX_PARAMETERS_HAPPY_PATH) - .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) - .order(ORDER_PARAMETERS_HAPPY_PATH) - .product(PRODUCT_PARAMETERS_HAPPY_PATH) - .build(); - - protected final Map TARGET_PARAMETERS_HAPPY_PATH_MAP = new HashMap() { - { - put("parameters", MBOX_PARAMETERS_HAPPY_PATH); - put("profileParameters", PROFILE_PARAMETERS_HAPPY_PATH); - put("order", ORDER_PARAMETERS_HAPPY_PATH_MAP); - put("product", PRODUCT_PARAMETERS_HAPPY_PATH_MAP); - } - }; + }; @Test public void testTargetPrefetch_happy() { - final TargetPrefetch targetPrefetch = new TargetPrefetch(MBOX_NAME_HAPPY_PATH, TARGET_PARAMETERS_HAPPY_PATH); + final TargetPrefetch targetPrefetch = + new TargetPrefetch(MBOX_NAME_HAPPY_PATH, TARGET_PARAMETERS_HAPPY_PATH); assertNotNull(targetPrefetch); assertEquals(MBOX_NAME_HAPPY_PATH, targetPrefetch.getMboxName()); assertEquals(TARGET_PARAMETERS_HAPPY_PATH, targetPrefetch.getTargetParameters()); @@ -93,7 +104,8 @@ public void testTargetPrefetch_happy() { @Test public void testToEventData_validTargetPrefetchMap() { - final TargetPrefetch targetPrefetch = new TargetPrefetch(MBOX_NAME_HAPPY_PATH, TARGET_PARAMETERS_HAPPY_PATH); + final TargetPrefetch targetPrefetch = + new TargetPrefetch(MBOX_NAME_HAPPY_PATH, TARGET_PARAMETERS_HAPPY_PATH); final Map targetPrefetchMap = targetPrefetch.toEventData(); assertNotNull(targetPrefetchMap); diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewButtonEventListenerTest.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewButtonEventListenerTest.java new file mode 100644 index 0000000..9268fc0 --- /dev/null +++ b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewButtonEventListenerTest.java @@ -0,0 +1,111 @@ +/* + Copyright 2023 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ + +package com.adobe.marketing.mobile.target; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import com.adobe.marketing.mobile.services.Log; +import com.adobe.marketing.mobile.services.ui.FloatingButton; +import com.adobe.marketing.mobile.services.ui.Presentable; +import com.adobe.marketing.mobile.services.ui.PresentationError; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.Silent.class) +public class TargetPreviewButtonEventListenerTest { + + @Mock private TargetPreviewManager mockTargetPreviewManager; + + @Mock private Presentable mockFloatingButton; + + @Mock private PresentationError mockPresentationError; + + TargetPreviewButtonEventListener previewButtonListener; + + @Before() + public void beforeEach() { + previewButtonListener = new TargetPreviewButtonEventListener(mockTargetPreviewManager); + } + + // =================================== + // Test OnTapDetected + // =================================== + @Test + public void test_OnTapDetected() { + // test + previewButtonListener.onTapDetected(mockFloatingButton); + + // verify + verify(mockTargetPreviewManager, times(1)).fetchWebView(); + } + + // =================================== + // Test onPanDetected + // =================================== + @Test + public void test_OnPanDetected() { + // test + previewButtonListener.onPanDetected(mockFloatingButton); + + // verify + // nothing to verify for now + } + + // =================================== + // Test onDismiss + // =================================== + @Test + public void test_OnDismiss() { + try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { + // test + previewButtonListener.onDismiss(mockFloatingButton); + + // verify + logMockedStatic.verify(() -> Log.debug(anyString(), anyString(), anyString())); + } + } + + // =================================== + // Test onError + // =================================== + @Test + public void test_OnError() { + try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { + // test + previewButtonListener.onError(mockFloatingButton, mockPresentationError); + + // verify + logMockedStatic.verify(() -> Log.debug(anyString(), anyString(), anyString())); + } + } + + // =================================== + // Test onShow + // =================================== + @Test + public void test_OnShow() { + try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { + // test + previewButtonListener.onShow(mockFloatingButton); + + // verify + logMockedStatic.verify(() -> Log.debug(anyString(), anyString(), anyString())); + } + } +} diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewButtonListenerTest.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewButtonListenerTest.java deleted file mode 100644 index 9a455fd..0000000 --- a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewButtonListenerTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright 2023 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ - -package com.adobe.marketing.mobile.target; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - - -@RunWith(MockitoJUnitRunner.Silent.class) -public class TargetPreviewButtonListenerTest { - - @Mock - private TargetPreviewManager mockTargetPreviewManager; - - TargetPreviewButtonListener previewButtonListener; - - - @Before() - public void beforeEach() { - previewButtonListener = new TargetPreviewButtonListener(mockTargetPreviewManager); - } - - // =================================== - // Test OnTapDetected - // =================================== - @Test - public void test_OnTapDetected() { - // test - previewButtonListener.onTapDetected(); - - // verify - verify(mockTargetPreviewManager, times(1)).fetchWebView(); - } - - // =================================== - // Test onPanDetected - // =================================== - @Test - public void test_OnPanDetected() { - // test - previewButtonListener.onPanDetected(); - - // verify - // nothing to verify for now - } - - - -} diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewFullScreenListenerTest.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewFullScreenListenerTest.java deleted file mode 100644 index 0ddac3e..0000000 --- a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewFullScreenListenerTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright 2023 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ - -package com.adobe.marketing.mobile.target; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.verify; - -import com.adobe.marketing.mobile.services.ui.FullscreenMessage; - -@RunWith(MockitoJUnitRunner.Silent.class) -public class TargetPreviewFullScreenListenerTest { - - TargetPreviewFullscreenDelegate fullscreenListener; - - @Mock - TargetPreviewManager mockTargetPreviewManager; - - @Mock - FullscreenMessage fullScreenMessage; - - @Before - public void beforeEach() { - fullscreenListener = new TargetPreviewFullscreenDelegate(mockTargetPreviewManager); - } - - // =================================== - // Test onShow - // =================================== - @Test - public void test_onShow() { - // test no_op - fullscreenListener.onShow(fullScreenMessage); - } - - // =================================== - // Test onDismiss - // =================================== - @Test - public void test_onDismiss() { - // test no op - fullscreenListener.onDismiss(fullScreenMessage); - } - - // =================================== - // Test overrideUrlLoad - // =================================== - @Test - public void test_overrideUrlLoad() { - // test - fullscreenListener.overrideUrlLoad(fullScreenMessage, "testdeeplink"); - - // verify - verify(mockTargetPreviewManager).previewConfirmedWithUrl(eq(fullScreenMessage), eq("testdeeplink")); - } -} \ No newline at end of file diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewFullscreenEventListenerTests.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewFullscreenEventListenerTests.java new file mode 100644 index 0000000..2bf44fa --- /dev/null +++ b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewFullscreenEventListenerTests.java @@ -0,0 +1,99 @@ +/* + Copyright 2023 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ + +package com.adobe.marketing.mobile.target; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; + +import com.adobe.marketing.mobile.services.Log; +import com.adobe.marketing.mobile.services.ui.InAppMessage; +import com.adobe.marketing.mobile.services.ui.Presentable; +import com.adobe.marketing.mobile.services.ui.PresentationError; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.Silent.class) +public class TargetPreviewFullscreenEventListenerTests { + + TargetPreviewFullscreenEventListener fullscreenListener; + + @Mock TargetPreviewManager mockTargetPreviewManager; + + @Mock Presentable fullScreenMessage; + + @Mock private PresentationError mockPresentationError; + + @Before + public void beforeEach() { + fullscreenListener = new TargetPreviewFullscreenEventListener(mockTargetPreviewManager); + } + + // =================================== + // Test onDismiss + // =================================== + @Test + public void test_OnDismiss() { + try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { + // test + fullscreenListener.onDismiss(fullScreenMessage); + + // verify + logMockedStatic.verify(() -> Log.debug(anyString(), anyString(), anyString())); + } + } + + // =================================== + // Test onError + // =================================== + @Test + public void test_OnError() { + try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { + // test + fullscreenListener.onError(fullScreenMessage, mockPresentationError); + + // verify + logMockedStatic.verify(() -> Log.debug(anyString(), anyString(), anyString())); + } + } + + // =================================== + // Test onShow + // =================================== + @Test + public void test_OnShow() { + try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { + // test + fullscreenListener.onShow(fullScreenMessage); + + // verify + logMockedStatic.verify(() -> Log.debug(anyString(), anyString(), anyString())); + } + } + // =================================== + // Test overrideUrlLoad + // =================================== + @Test + public void test_overrideUrlLoad() { + // test + fullscreenListener.onUrlLoading(fullScreenMessage, "testdeeplink"); + + // verify + verify(mockTargetPreviewManager) + .previewConfirmedWithUrl(eq(fullScreenMessage), eq("testdeeplink")); + } +} diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewManagerTest.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewManagerTest.java index 58d76fe..ef6b5ba 100644 --- a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewManagerTest.java +++ b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetPreviewManagerTest.java @@ -1,38 +1,30 @@ /* - Copyright 2023 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2023 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockedConstruction; -import org.mockito.junit.MockitoJUnitRunner; - -import java.io.ByteArrayInputStream; -import java.nio.charset.StandardCharsets; - import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; - +import android.content.Context; +import android.content.res.AssetManager; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.Base64; import com.adobe.marketing.mobile.Event; import com.adobe.marketing.mobile.services.HttpConnecting; import com.adobe.marketing.mobile.services.HttpMethod; @@ -40,565 +32,907 @@ import com.adobe.marketing.mobile.services.NetworkRequest; import com.adobe.marketing.mobile.services.Networking; import com.adobe.marketing.mobile.services.ui.FloatingButton; -import com.adobe.marketing.mobile.services.ui.FullscreenMessage; -import com.adobe.marketing.mobile.services.ui.MessageSettings; +import com.adobe.marketing.mobile.services.ui.InAppMessage; +import com.adobe.marketing.mobile.services.ui.Presentable; +import com.adobe.marketing.mobile.services.ui.PresentationUtilityProvider; import com.adobe.marketing.mobile.services.ui.UIService; +import com.adobe.marketing.mobile.services.uri.UriOpening; +import com.adobe.marketing.mobile.util.StreamUtils; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.stubbing.Answer; @RunWith(MockitoJUnitRunner.Silent.class) -public class TargetPreviewManagerTest { - - private static String PREVIEW_PARAMETERS = "at_preview_params"; - private static String PREVIEW_TOKEN = "at_preview_token"; - private static String PREVIEW_ENDPOINT = "at_preview_endpoint"; - private static String PREVIEW_DEFAULT_EP = "hal.testandtarget.omniture.com"; - private static String QA_MODE_NODE = "qaMode"; - private static String CLIENT_CODE = "test_client_code"; - - - String ENCODED_PREVIEW_PARAMS = - "%7B%22qaMode%22%3A%7B%0D%0A%22token%22%3A%22abcd%22%2C%0D%0A%22bypassEntryAudience%22%3Atrue%2C%0D%0A%22listedActivitiesOnly%22%3Atrue%2C%0D%0A%22evaluateAsTrueAudienceIds%22%3A%5B%22audienceId1%22%2C%22audienceId2%22%5D%2C%0D%0A%22evaluateAsFalseAudienceIds%22%3A%5B%22audienceId3%22%2C%22audienceId4%22%5D%2C%0D%0A%22previewIndexes%22%3A%5B%0D%0A%7B%0D%0A%22activityIndex%22%3A1%2C%0D%0A%22experienceIndex%22%3A1%0D%0A%7D%5D%7D%7D"; - - String JSON_PREVIEW_PARAMS = "{\"qaMode\":{\"token\":\"abcd\"," - + "\"bypassEntryAudience\":true," - + "\"listedActivitiesOnly\":true," - + "\"evaluateAsTrueAudienceIds\":[\"audienceId1\",\"audienceId2\"]," - + "\"evaluateAsFalseAudienceIds\":[\"audienceId3\",\"audienceId4\"]," - + "\"previewIndexes\":[" - + "{" - + "\"activityIndex\":1," - + "\"experienceIndex\":1" - + "}" - + "]" - + "}" - + "}"; - - String TEST_QUERY_PARAMS = "at_preview_params=" + ENCODED_PREVIEW_PARAMS + "&extraKey=extraValue"; - String TEST_CONFIRM_DEEPLINK = "adbinapp://confirm?" + TEST_QUERY_PARAMS; - String TEST_RESTART_URL = "adbinapp://somepage"; - - - @Mock - private Networking networkService; - - @Mock - private UIService uiService; - - @Mock - private FloatingButton floatingButton; - - @Mock - private FullscreenMessage fullscreenMessage; - - @Mock - private TargetPreviewFullscreenDelegate fullscreenDelegate; - - @Mock - private HttpConnecting connecting; - - @Mock - private TargetPreviewManager previewManager; - - private MockedConstruction buttonListenerMockedConstruction; - - @Before() - public void beforeEach() { - mockFullScreenAndFloatingButton(); - previewManager = new TargetPreviewManager(networkService, uiService); - } - - - void mockFullScreenAndFloatingButton() { - when(uiService.createFloatingButton(any(TargetPreviewButtonListener.class))).thenReturn(floatingButton); - when(uiService.createFullscreenMessage(any(String.class), any(TargetPreviewFullscreenDelegate.class), any(Boolean.class), any(MessageSettings.class))).thenReturn(fullscreenMessage); - } - - void setMockConnectionResponse(final String response, final int responseCode) { - when(connecting.getResponseCode()).thenReturn(responseCode); - when(connecting.getInputStream()).thenReturn(new ByteArrayInputStream(response.getBytes(StandardCharsets.UTF_8))); - doAnswer(invocation -> { - ((NetworkCallback) invocation.getArguments()[1]).call(connecting); - return null; - }).when(networkService).connectAsync(any(), any()); - } - - // =================================== - // Test enterPreviewModeWithDeepLinkParams - // =================================== - @Test - public void test_enterPreviewModeWithDeepLinkParams_ValidDeepLink() { - // setup - ArgumentCaptor networkResponseCapture = ArgumentCaptor.forClass(NetworkRequest.class); - String testDeeplink = "test://path?at_preview_token=abcd&key1=val1"; - String expectedUrl = "https://" + PREVIEW_DEFAULT_EP + "/ui/admin/" + CLIENT_CODE + "/preview?token=abcd"; - setMockConnectionResponse("TestHTML", 200); - - // test - previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); - - // verify floating button created and displayed - verifyFloatingButtonDisplayed(); - - // verify network call - verify(networkService, times(1)).connectAsync(networkResponseCapture.capture(), any()); - assertEquals("network request has the correct httpcommand", HttpMethod.GET, - networkResponseCapture.getValue().getMethod()); - assertEquals("network request has the correct read timeout", 2, - networkResponseCapture.getValue().getReadTimeout()); - assertEquals("network request has the correct URL", - expectedUrl, networkResponseCapture.getValue().getUrl()); - assertEquals("network request has the correct request property", 2, networkResponseCapture.getValue().getHeaders().size()); - assertEquals("network request has the correct request property", "text/html", networkResponseCapture.getValue().getHeaders().get("Accept")); - assertEquals("network request has the correct request property", "application/x-www-form-urlencoded", networkResponseCapture.getValue().getHeaders().get("Content-Type")); - - - // verify fullscreen message created and displayed - verifyFullScreenMessageDisplayed(); - - // verify local variables - assertEquals("abcd", previewManager.getPreviewToken()); - } - - @Test - public void test_EnterPreviewModeWithDeepLinkParams_NullDeepLink() { - // test - previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, null); - - // verify no FullScreenMessage or floating button is created - verifyNoInteractions(uiService); - - // verify no network call - verifyNoInteractions(networkService); - - // verify local variables - assertNull(previewManager.getPreviewToken()); - } - - - @Test - public void test_EnterPreviewModeWithDeepLinkParams_EmptyDeepLink() { - // test - previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, ""); - - // verify no fullScreenMessage or floating button is created - verifyNoInteractions(uiService); - - // verify no network call - verifyNoInteractions(networkService); - - // verify local variables - assertNull(previewManager.getPreviewToken()); - } - - @Test - public void test_EnterPreviewModeWithDeepLinkParams_ValidDeepLink_Without_Double_Decoding() { - // Validate fix for AMSDK-8272 Preview Link getting re-encoded from %2B to %20 - // setup - ArgumentCaptor networkResponseCapture = ArgumentCaptor.forClass(NetworkRequest.class); - String testDeeplink = "test://path?at_preview_token=olDho0%2Blkfr8LaHURjiCAnu1xIVRkvN3UqdXwawRz3E%3D&key1=val1"; - String expectedUrl = "https://" + PREVIEW_DEFAULT_EP + "/ui/admin/" + CLIENT_CODE + - "/preview?token=olDho0%2Blkfr8LaHURjiCAnu1xIVRkvN3UqdXwawRz3E%3D"; - setMockConnectionResponse("TestHTML", 200); - - // test - previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); - - // verify floating button - verifyFloatingButtonDisplayed(); - - // verify network call - verify(networkService, times(1)).connectAsync(networkResponseCapture.capture(), any()); - assertEquals("network request has the correct URL", - expectedUrl, networkResponseCapture.getValue().getUrl()); - - // verify fullscreen message created and displayed - verifyFullScreenMessageDisplayed(); - - // verify local variables - assertEquals("olDho0+lkfr8LaHURjiCAnu1xIVRkvN3UqdXwawRz3E=", previewManager.getPreviewToken()); - } - - @Test - public void test_EnterPreviewModeWithDeepLinkParams_DeepLinkMissingToken() { - // setup - String testDeeplink = "test://path?somethingelse=abcd&key1=val1"; - - // test - previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); - - // verify no fullScreenMessage or floating button is created - verifyNoInteractions(uiService); - - // verify no network call - verifyNoInteractions(networkService); - - // verify local variables - assertNull(previewManager.getPreviewToken()); - } - - @Test - public void test_EnterPreviewModeWithDeepLinkParams_InValidDeeplink() { - // setup - String testDeeplink = "NotAValidDeeplink"; - - // test - previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); - - // verify no fullScreenMessage or floating button is created - verifyNoInteractions(uiService); - - // verify no network call - verifyNoInteractions(networkService); - - // verify local variables - assertNull(previewManager.getPreviewToken()); - } - - @Test - public void test_EnterPreviewModeWithDeepLinkParams_NullUIService() { - // setup - String testDeeplink = "test://path?at_preview_token=abcd&key1=val1"; - previewManager = new TargetPreviewManager(networkService, null); - - // test - previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); - - // verify no fullScreenMessage or floating button is created - verifyNoInteractions(uiService); - - // verify no network call - verifyNoInteractions(networkService); - - // verify local variables - assertNull(previewManager.getPreviewToken()); - } - - @Test - public void test_EnterPreviewModeWithDeepLinkParams_NullNetworkService() { - // setup - String testDeeplink = "test://path?at_preview_token=abcd&key1=val1"; - previewManager = new TargetPreviewManager(null, uiService); - - // test - previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); - - // verify no fullScreenMessage or floating button is created - verifyNoInteractions(uiService); - - // verify no network call - verifyNoInteractions(networkService); - - // verify local variables - assertNull(previewManager.getPreviewToken()); - } - - @Test - public void test_EnterPreviewModeWithDeepLinkParams_DifferentEndpoint() { - // setup - ArgumentCaptor networkResponseCapture = ArgumentCaptor.forClass(NetworkRequest.class); - String testDeeplink = "test://path?at_preview_token=abcd&key1=val1&" + PREVIEW_ENDPOINT + "=newEndPoint"; - String expectedUrl = "https://newEndPoint/ui/admin/" + CLIENT_CODE + "/preview?token=abcd"; - setMockConnectionResponse("TestHTML", 200); - - // test - previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); - - // verify floating button - verifyFloatingButtonDisplayed(); - - // verify message displayed - verifyFullScreenMessageDisplayed(); - - // verify network call - verify(networkService, times(1)).connectAsync(networkResponseCapture.capture(), any()); - assertEquals("network request has the correct URL", - expectedUrl, networkResponseCapture.getValue().getUrl()); - } - - // =================================== - // Test resetTargetPreviewProperties - // =================================== - @Test - public void test_resetTargetPreviewProperties() { - // setup - previewManager.token = "token"; - previewManager.webViewHtml = "html"; - previewManager.previewParams = "params"; - previewManager.endPoint = "endPoint"; - previewManager.restartUrl = "restartURL"; - previewManager.floatingButton = floatingButton; - - // test - previewManager.resetTargetPreviewProperties(); - - //verify - assertNull(previewManager.token); - assertNull(previewManager.webViewHtml); - assertNull(previewManager.previewParams); - assertNull(previewManager.endPoint); - assertNull(previewManager.restartUrl); - assertNull(previewManager.floatingButton); - verify(floatingButton).remove(); - } - - // =================================== - // Test previewConfirmedWithUrl - // =================================== - @Test - public void test_previewConfirmedWithUrl_When_Confirm() { - // setup - ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(Event.class); - previewManager.floatingButton = floatingButton; - - // test - previewManager.previewConfirmedWithUrl(fullscreenMessage, TEST_CONFIRM_DEEPLINK); - - //verify - verify(fullscreenMessage).dismiss(); - assertEquals(JSON_PREVIEW_PARAMS, previewManager.getPreviewParameters().replaceAll("\\s+", "")); - } - - @Test - public void test_previewConfirmedWithUrl_When_Cancel() { - // setup - ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(Event.class); - previewManager.floatingButton = floatingButton; - - // test - previewManager.previewConfirmedWithUrl(fullscreenMessage, "adbinapp://cancel"); - - //verify - verify(fullscreenMessage).dismiss(); - assertNull(previewManager.getPreviewParameters()); - } - - @Test - public void test_previewConfirmedWithUrl_ConfirmPreviewParamsEmpty() { - // setup - previewManager.floatingButton = floatingButton; - - // test - previewManager.previewConfirmedWithUrl(fullscreenMessage, "adbinapp://confirm?abc=def"); - - //verify - verify(fullscreenMessage).dismiss(); - assertNull(previewManager.getPreviewParameters()); - } - - @Test - public void test_previewConfirmedWithUrl_InvalidURI() { - // setup - previewManager.floatingButton = floatingButton; - - // test - previewManager.previewConfirmedWithUrl(fullscreenMessage, "Invalid"); - - //verify - verify(fullscreenMessage).dismiss(); - assertNull(previewManager.getPreviewParameters()); - } - - @Test - public void test_previewConfirmedWithUrl_InvalidScheme() { - // setup - previewManager.floatingButton = floatingButton; - - // test - previewManager.previewConfirmedWithUrl(fullscreenMessage, "notAppScheme://confirm?abc=def"); - - //verify - verify(fullscreenMessage).dismiss(); - assertNull(previewManager.getPreviewParameters()); - } - - @Test - public void test_previewConfirmedWithUrl_When_RestartDeepLink() { - // setup - previewManager.floatingButton = floatingButton; - previewManager.restartUrl = "restartURL"; - - // test - previewManager.previewConfirmedWithUrl(fullscreenMessage, TEST_CONFIRM_DEEPLINK); - - //verify - verify(fullscreenMessage).dismiss(); - verify(uiService).showUrl("restartURL"); - } - - @Test - public void test_previewConfirmedWithUrl_When_RestartDeepLinkUnAvailable() { - // setup - previewManager.floatingButton = floatingButton; - previewManager.restartUrl = null; - - // test - previewManager.previewConfirmedWithUrl(fullscreenMessage, TEST_CONFIRM_DEEPLINK); - - //verify - verify(fullscreenMessage).dismiss(); - verify(uiService, times(0)).showUrl(any(String.class)); - } - - @Test - public void test_previewConfirmedWithUrl_ConfirmPreviewParamsEmpty_Should_Not_Dispatch_TargetResponseEvent() { - // setup - previewManager.floatingButton = floatingButton; - - // test - previewManager.previewConfirmedWithUrl(fullscreenMessage, "adbinapp://confirm?"); - - //verify - verify(fullscreenMessage).dismiss(); - assertNull(previewManager.getPreviewParameters()); - } - - - // =================================== - // Test fetchWebView - // =================================== - @Test - public void test_fetchWebView_Works() { - // setup - ArgumentCaptor networkResponseCapture = ArgumentCaptor.forClass(NetworkRequest.class); - previewManager.endPoint = "someEndpoint"; - setMockConnectionResponse("TestHTML", 200); - - // test - previewManager.fetchWebView(); - - // verify network call - verify(networkService, times(1)).connectAsync(networkResponseCapture.capture(), any()); - assertEquals("network request has the correct httpcommand", HttpMethod.GET, - networkResponseCapture.getValue().getMethod()); - assertEquals("network request has the correct read timeout", 2, - networkResponseCapture.getValue().getReadTimeout()); - assertEquals("network request has the correct URL", - "https://someEndpoint/ui/admin/preview", networkResponseCapture.getValue().getUrl()); - assertEquals("network request has the correct request property", 2, networkResponseCapture.getValue().getHeaders().size()); - assertEquals("network request has the correct request property", "text/html", networkResponseCapture.getValue().getHeaders().get("Accept")); - assertEquals("network request has the correct request property", "application/x-www-form-urlencoded", networkResponseCapture.getValue().getHeaders().get("Content-Type")); - - - // verify fullscreen message created and displayed - verifyFullScreenMessageDisplayed(); - } - - @Test - public void test_fetchWebView_EmptyServerResponse() { - // setup - ArgumentCaptor networkResponseCapture = ArgumentCaptor.forClass(NetworkRequest.class); - previewManager.endPoint = "someEndpoint"; - setMockConnectionResponse("", 200); - - // test - previewManager.fetchWebView(); - - // verify network call - verify(networkService, times(1)).connectAsync(networkResponseCapture.capture(), any()); - assertEquals("network request has the correct URL", - "https://someEndpoint/ui/admin/preview", networkResponseCapture.getValue().getUrl()); - - // verify message not displayed - verifyNoInteractions(uiService); - } - - @Test - public void test_fetchWebView_WhenConnectionNull() { - // setup - ArgumentCaptor networkResponseCapture = ArgumentCaptor.forClass(NetworkRequest.class); - previewManager.endPoint = "someEndpoint"; - doAnswer(invocation -> { - ((NetworkCallback) invocation.getArguments()[1]).call(null); - return null; - }).when(networkService).connectAsync(any(), any()); - - // test - previewManager.fetchWebView(); - - // verify network call - verify(networkService, times(1)).connectAsync(networkResponseCapture.capture(), any()); - assertEquals("network request has the correct URL", - "https://someEndpoint/ui/admin/preview", networkResponseCapture.getValue().getUrl()); - - // verify message not displayed - verifyNoInteractions(uiService); - } - - @Test - public void test_fetchWebView_ResponseCodeNot200() { - // setup - ArgumentCaptor networkResponseCapture = ArgumentCaptor.forClass(NetworkRequest.class); - previewManager.endPoint = "someEndpoint"; - setMockConnectionResponse("TestHTML", 202); - - // test - previewManager.fetchWebView(); - - // verify network call - verify(networkService, times(1)).connectAsync(networkResponseCapture.capture(), any()); - assertEquals("network request has the correct URL", - "https://someEndpoint/ui/admin/preview", networkResponseCapture.getValue().getUrl()); - - // verify message not displayed - verifyNoInteractions(uiService); - } - - @Test - public void test_fetchWebView_WhenCreateFullScreenFails() { - // setup - previewManager.endPoint = "someEndpoint"; - when(uiService.createFullscreenMessage(any(String.class), any(TargetPreviewFullscreenDelegate.class), any(Boolean.class), any(MessageSettings.class))).thenReturn(null); - setMockConnectionResponse("TestHTML", 200); - - // test - previewManager.fetchWebView(); - - // verify message not displayed - verify(networkService, times(1)).connectAsync(any(), any()); - verifyNoInteractions(fullscreenMessage); - } - - // =================================== - // Test setRestartDeepLink - // =================================== - @Test - public void test_setRestartDeepLink() { - // test - previewManager.setRestartDeepLink("restartURL"); - - //verify - assertEquals("restartURL", previewManager.restartUrl); - } - - @Test - public void test_setRestartDeepLink_Null() { - // test - previewManager.setRestartDeepLink(null); - - //verify - assertNull(previewManager.restartUrl); - } - - // =================================== - // Test getPreviewParameters - // =================================== - @Test - public void test_getPreviewParameters() { - // setup - previewManager.previewParams = "params"; - - // test - assertEquals("params", previewManager.getPreviewParameters()); - } - - - private void verifyFullScreenMessageDisplayed() { - verify(uiService,times(1)).createFullscreenMessage(eq("TestHTML"), any(TargetPreviewFullscreenDelegate.class), eq(false), any(MessageSettings.class)); - verify(fullscreenMessage).show(); - } - - private void verifyFloatingButtonDisplayed() { - verify(uiService,times(1)).createFloatingButton(any(TargetPreviewButtonListener.class)); - verify(floatingButton).display(); - } - -} \ No newline at end of file +public class TargetPreviewManagerTest { + + private static String PREVIEW_PARAMETERS = "at_preview_params"; + private static String PREVIEW_TOKEN = "at_preview_token"; + private static String PREVIEW_ENDPOINT = "at_preview_endpoint"; + private static String PREVIEW_DEFAULT_EP = "hal.testandtarget.omniture.com"; + private static String QA_MODE_NODE = "qaMode"; + private static String CLIENT_CODE = "test_client_code"; + + String ENCODED_PREVIEW_PARAMS = + "%7B%22qaMode%22%3A%7B%0D%0A%22token%22%3A%22abcd%22%2C%0D%0A%22bypassEntryAudience%22%3Atrue%2C%0D%0A%22listedActivitiesOnly%22%3Atrue%2C%0D%0A%22evaluateAsTrueAudienceIds%22%3A%5B%22audienceId1%22%2C%22audienceId2%22%5D%2C%0D%0A%22evaluateAsFalseAudienceIds%22%3A%5B%22audienceId3%22%2C%22audienceId4%22%5D%2C%0D%0A%22previewIndexes%22%3A%5B%0D%0A%7B%0D%0A%22activityIndex%22%3A1%2C%0D%0A%22experienceIndex%22%3A1%0D%0A%7D%5D%7D%7D"; + + String JSON_PREVIEW_PARAMS = + "{\"qaMode\":{\"token\":\"abcd\"," + + "\"bypassEntryAudience\":true," + + "\"listedActivitiesOnly\":true," + + "\"evaluateAsTrueAudienceIds\":[\"audienceId1\",\"audienceId2\"]," + + "\"evaluateAsFalseAudienceIds\":[\"audienceId3\",\"audienceId4\"]," + + "\"previewIndexes\":[" + + "{" + + "\"activityIndex\":1," + + "\"experienceIndex\":1" + + "}" + + "]" + + "}" + + "}"; + + String TEST_QUERY_PARAMS = + "at_preview_params=" + ENCODED_PREVIEW_PARAMS + "&extraKey=extraValue"; + String TEST_CONFIRM_DEEPLINK = "adbinapp://confirm?" + TEST_QUERY_PARAMS; + String TEST_RESTART_URL = "adbinapp://somepage"; + + @Mock private Networking networkService; + + @Mock private UIService uiService; + + @Mock private UriOpening uriService; + + @Mock private Context context; + + @Mock private AssetManager assetManager; + + @Mock private Bitmap floatingButtonImage; + + @Mock private Presentable floatingButton; + + @Mock private Presentable fullscreenMessage; + + @Mock private HttpConnecting connecting; + + @Mock private TargetPreviewManager previewManager; + + @Before() + public void beforeEach() { + mockFullScreenAndFloatingButton(); + previewManager = new TargetPreviewManager(networkService, uiService, uriService, context); + } + + void runUsingMockedServiceProvider(final Runnable runnable) { + try (MockedStatic base64MockedStatic = Mockito.mockStatic(Base64.class); + MockedStatic bitmapFactoryMockedStatic = + Mockito.mockStatic(BitmapFactory.class); + MockedStatic streamUtilsMockedStatic = + Mockito.mockStatic(StreamUtils.class)) { + base64MockedStatic + .when( + () -> + Base64.decode( + ArgumentMatchers.anyString(), + ArgumentMatchers.anyInt())) + .thenAnswer( + (Answer) + invocation -> + java.util.Base64.getDecoder() + .decode((String) invocation.getArguments()[0])); + bitmapFactoryMockedStatic + .when(() -> BitmapFactory.decodeStream(any(InputStream.class))) + .thenReturn(floatingButtonImage); + streamUtilsMockedStatic + .when(() -> StreamUtils.readAsString(any())) + .thenReturn(TargetTestConstants.ENCODED_BUTTON_BACKGROUND_PNG); + runnable.run(); + } + } + + void mockFullScreenAndFloatingButton() { + when(uiService.create(any(FloatingButton.class), any(PresentationUtilityProvider.class))) + .thenReturn(floatingButton); + when(uiService.create(any(InAppMessage.class), any(PresentationUtilityProvider.class))) + .thenReturn(fullscreenMessage); + when(context.getAssets()).thenReturn(assetManager); + } + + void setMockConnectionResponse(final String response, final int responseCode) { + when(connecting.getResponseCode()).thenReturn(responseCode); + when(connecting.getInputStream()) + .thenReturn(new ByteArrayInputStream(response.getBytes(StandardCharsets.UTF_8))); + doAnswer( + invocation -> { + ((NetworkCallback) invocation.getArguments()[1]).call(connecting); + return null; + }) + .when(networkService) + .connectAsync(any(), any()); + } + + // =================================== + // Test enterPreviewModeWithDeepLinkParams + // =================================== + @Test + public void test_enterPreviewModeWithDeepLinkParams_ValidDeepLink() { + runUsingMockedServiceProvider( + () -> { + // setup + ArgumentCaptor networkResponseCapture = + ArgumentCaptor.forClass(NetworkRequest.class); + String testDeeplink = "test://path?at_preview_token=abcd&key1=val1"; + String expectedUrl = + "https://" + + PREVIEW_DEFAULT_EP + + "/ui/admin/" + + CLIENT_CODE + + "/preview?token=abcd"; + setMockConnectionResponse("TestHTML", 200); + + // test + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); + + // verify floating button created and displayed + verifyFloatingButtonDisplayed(); + + // verify network call + verify(networkService, times(1)) + .connectAsync(networkResponseCapture.capture(), any()); + assertEquals( + "network request has the correct httpcommand", + HttpMethod.GET, + networkResponseCapture.getValue().getMethod()); + assertEquals( + "network request has the correct read timeout", + 2, + networkResponseCapture.getValue().getReadTimeout()); + assertEquals( + "network request has the correct URL", + expectedUrl, + networkResponseCapture.getValue().getUrl()); + assertEquals( + "network request has the correct request property", + 2, + networkResponseCapture.getValue().getHeaders().size()); + assertEquals( + "network request has the correct request property", + "text/html", + networkResponseCapture.getValue().getHeaders().get("Accept")); + assertEquals( + "network request has the correct request property", + "application/x-www-form-urlencoded", + networkResponseCapture.getValue().getHeaders().get("Content-Type")); + + // verify fullscreen message created and displayed + verifyFullScreenMessageDisplayed(); + + // verify local variables + assertEquals("abcd", previewManager.getPreviewToken()); + + // verify floating button not created again + }); + } + + @Test + public void test_EnterPreviewModeWithDeepLinkParams_NullDeepLink() { + runUsingMockedServiceProvider( + () -> { + // test + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, null); + + // verify no FullScreenMessage or floating button is created + verifyNoInteractions(uiService); + + // verify no network call + verifyNoInteractions(networkService); + + // verify local variables + assertNull(previewManager.getPreviewToken()); + }); + } + + @Test + public void test_EnterPreviewModeWithDeepLinkParams_EmptyDeepLink() { + runUsingMockedServiceProvider( + () -> { + // test + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, ""); + + // verify no fullScreenMessage or floating button is created + verifyNoInteractions(uiService); + + // verify no network call + verifyNoInteractions(networkService); + + // verify local variables + assertNull(previewManager.getPreviewToken()); + }); + } + + @Test + public void test_EnterPreviewModeWithDeepLinkParams_ValidDeepLink_Without_Double_Decoding() { + runUsingMockedServiceProvider( + () -> { + // Validate fix for AMSDK-8272 Preview Link getting re-encoded from %2B to %20 + // setup + ArgumentCaptor networkResponseCapture = + ArgumentCaptor.forClass(NetworkRequest.class); + String testDeeplink = + "test://path?at_preview_token=olDho0%2Blkfr8LaHURjiCAnu1xIVRkvN3UqdXwawRz3E%3D&key1=val1"; + String expectedUrl = + "https://" + + PREVIEW_DEFAULT_EP + + "/ui/admin/" + + CLIENT_CODE + + "/preview?token=olDho0%2Blkfr8LaHURjiCAnu1xIVRkvN3UqdXwawRz3E%3D"; + setMockConnectionResponse("TestHTML", 200); + + // test + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); + + // verify floating button + verifyFloatingButtonDisplayed(); + + // verify network call + verify(networkService, times(1)) + .connectAsync(networkResponseCapture.capture(), any()); + assertEquals( + "network request has the correct URL", + expectedUrl, + networkResponseCapture.getValue().getUrl()); + + // verify fullscreen message created and displayed + verifyFullScreenMessageDisplayed(); + + // verify local variables + assertEquals( + "olDho0+lkfr8LaHURjiCAnu1xIVRkvN3UqdXwawRz3E=", + previewManager.getPreviewToken()); + }); + } + + @Test + public void test_EnterPreviewModeWithDeepLinkParams_DeepLinkMissingToken() { + runUsingMockedServiceProvider( + () -> { + // setup + String testDeeplink = "test://path?somethingelse=abcd&key1=val1"; + + // test + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); + + // verify no fullScreenMessage or floating button is created + verifyNoInteractions(uiService); + + // verify no network call + verifyNoInteractions(networkService); + + // verify no deeplink opened + verifyNoInteractions(uriService); + + // verify local variables + assertNull(previewManager.getPreviewToken()); + }); + } + + @Test + public void test_EnterPreviewModeWithDeepLinkParams_InValidDeeplink() { + runUsingMockedServiceProvider( + () -> { + // setup + String testDeeplink = "NotAValidDeeplink"; + + // test + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); + + // verify no fullScreenMessage or floating button is created + verifyNoInteractions(uiService); + + // verify no network call + verifyNoInteractions(networkService); + + // verify no deeplink opened + verifyNoInteractions(uriService); + + // verify local variables + assertNull(previewManager.getPreviewToken()); + }); + } + + @Test + public void test_EnterPreviewModeWithDeepLinkParams_NullUIService() { + runUsingMockedServiceProvider( + () -> { + // setup + String testDeeplink = "test://path?at_preview_token=abcd&key1=val1"; + previewManager = + new TargetPreviewManager(networkService, null, uriService, context); + + // test + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); + + // verify no fullScreenMessage or floating button is created + verifyNoInteractions(uiService); + + // verify no network call + verifyNoInteractions(networkService); + + // verify no deeplink opened + verifyNoInteractions(uriService); + + // verify local variables + assertNull(previewManager.getPreviewToken()); + }); + } + + @Test + public void test_EnterPreviewModeWithDeepLinkParams_NullUriService() { + runUsingMockedServiceProvider( + () -> { + // setup + String testDeeplink = "test://path?at_preview_token=abcd&key1=val1"; + previewManager = + new TargetPreviewManager(networkService, uiService, null, context); + + // test + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); + + // verify no fullScreenMessage or floating button is created + verifyNoInteractions(uiService); + + // verify no network call + verifyNoInteractions(networkService); + + // verify no deeplink opened + verifyNoInteractions(uriService); + + // verify local variables + assertNull(previewManager.getPreviewToken()); + }); + } + + @Test + public void test_EnterPreviewModeWithDeepLinkParams_NullNetworkService() { + runUsingMockedServiceProvider( + () -> { + // setup + String testDeeplink = "test://path?at_preview_token=abcd&key1=val1"; + previewManager = new TargetPreviewManager(null, uiService, uriService, context); + + // test + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); + + // verify no fullScreenMessage or floating button is created + verifyNoInteractions(uiService); + + // verify no network call + verifyNoInteractions(networkService); + + // verify no deeplink opened + verifyNoInteractions(uriService); + + // verify local variables + assertNull(previewManager.getPreviewToken()); + }); + } + + @Test + public void test_EnterPreviewModeWithDeepLinkParams_DifferentEndpoint() { + runUsingMockedServiceProvider( + () -> { + // setup + ArgumentCaptor networkResponseCapture = + ArgumentCaptor.forClass(NetworkRequest.class); + String testDeeplink = + "test://path?at_preview_token=abcd&key1=val1&" + + PREVIEW_ENDPOINT + + "=newEndPoint"; + String expectedUrl = + "https://newEndPoint/ui/admin/" + CLIENT_CODE + "/preview?token=abcd"; + setMockConnectionResponse("TestHTML", 200); + + // test + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); + + // verify floating button + verifyFloatingButtonDisplayed(); + + // verify message displayed + verifyFullScreenMessageDisplayed(); + + // verify network call + verify(networkService, times(1)) + .connectAsync(networkResponseCapture.capture(), any()); + assertEquals( + "network request has the correct URL", + expectedUrl, + networkResponseCapture.getValue().getUrl()); + }); + } + + @Test + public void test_EnterPreviewModeWithDeepLinkParams_LaunchingPreviewModeTwice() { + runUsingMockedServiceProvider( + () -> { + // setup + String testDeeplink = "test://path?at_preview_token=abcd&key1=val1"; + setMockConnectionResponse("TestHTML", 200); + + // test + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); + + // verify floating button + verifyFloatingButtonDisplayed(); + + // verify fullscreen message created and displayed + verifyFullScreenMessageDisplayed(); + + // verify local variables + assertEquals("abcd", previewManager.getPreviewToken()); + + // launch preview again + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); + + // verify floating button not created again + verify(uiService, times(1)) + .create( + any(FloatingButton.class), + any(PresentationUtilityProvider.class)); + verify(floatingButton, times(1)).show(); + }); + } + + @Test + public void + test_EnterPreviewModeWithDeepLinkParams_MissingAssetManagerForFloatingButtonImage() { + runUsingMockedServiceProvider( + () -> { + // setup + when(context.getAssets()).thenReturn(null); + String testDeeplink = "test://path?at_preview_token=abcd&key1=val1"; + setMockConnectionResponse("TestHTML", 200); + + // test + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); + + // verify floating button not displayed + verify(uiService, times(0)) + .create( + any(FloatingButton.class), + any(PresentationUtilityProvider.class)); + verifyNoMoreInteractions(floatingButton); + + // verify fullscreen message created and displayed + verifyFullScreenMessageDisplayed(); + + // verify local variables + assertEquals("abcd", previewManager.getPreviewToken()); + }); + } + + @Test + public void test_EnterPreviewModeWithDeepLinkParams_ExceptionInReadingInputStream() { + try (MockedStatic base64MockedStatic = Mockito.mockStatic(Base64.class); + MockedStatic bitmapFactoryMockedStatic = + Mockito.mockStatic(BitmapFactory.class); + MockedStatic streamUtilsMockedStatic = + Mockito.mockStatic(StreamUtils.class)) { + base64MockedStatic + .when( + () -> + Base64.decode( + ArgumentMatchers.anyString(), + ArgumentMatchers.anyInt())) + .thenAnswer( + (Answer) + invocation -> + java.util.Base64.getDecoder() + .decode((String) invocation.getArguments()[0])); + bitmapFactoryMockedStatic + .when(() -> BitmapFactory.decodeStream(any(InputStream.class))) + .thenReturn(floatingButtonImage); + streamUtilsMockedStatic.when(() -> StreamUtils.readAsString(any())).thenReturn(null); + + String testDeeplink = "test://path?at_preview_token=abcd&key1=val1"; + setMockConnectionResponse("TestHTML", 200); + + // test + previewManager.enterPreviewModeWithDeepLinkParams(CLIENT_CODE, testDeeplink); + + // verify floating button and fullscreen message not created and displayed + verifyNoMoreInteractions(uiService); + verifyNoMoreInteractions(floatingButton); + verifyNoMoreInteractions(fullscreenMessage); + + // verify local variables + assertEquals("abcd", previewManager.getPreviewToken()); + } + } + + // =================================== + // Test resetTargetPreviewProperties + // =================================== + @Test + public void test_resetTargetPreviewProperties() { + runUsingMockedServiceProvider( + () -> { + // setup + previewManager.token = "token"; + previewManager.webViewHtml = "html"; + previewManager.previewParams = "params"; + previewManager.endPoint = "endPoint"; + previewManager.restartUrl = "restartURL"; + previewManager.floatingButtonPresentable = floatingButton; + + // test + previewManager.resetTargetPreviewProperties(); + + // verify + assertNull(previewManager.token); + assertNull(previewManager.webViewHtml); + assertNull(previewManager.previewParams); + assertNull(previewManager.endPoint); + assertNull(previewManager.restartUrl); + assertNull(previewManager.floatingButtonPresentable); + verify(floatingButton).dismiss(); + }); + } + + // =================================== + // Test previewConfirmedWithUrl + // =================================== + @Test + public void test_previewConfirmedWithUrl_When_Confirm() { + runUsingMockedServiceProvider( + () -> { + // setup + ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(Event.class); + previewManager.floatingButtonPresentable = floatingButton; + + // test + previewManager.previewConfirmedWithUrl( + fullscreenMessage, TEST_CONFIRM_DEEPLINK); + + // verify + verify(fullscreenMessage).dismiss(); + assertEquals( + JSON_PREVIEW_PARAMS, + previewManager.getPreviewParameters().replaceAll("\\s+", "")); + }); + } + + @Test + public void test_previewConfirmedWithUrl_When_Cancel() { + runUsingMockedServiceProvider( + () -> { + // setup + ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(Event.class); + previewManager.floatingButtonPresentable = floatingButton; + + // test + previewManager.previewConfirmedWithUrl(fullscreenMessage, "adbinapp://cancel"); + + // verify + verify(fullscreenMessage).dismiss(); + assertNull(previewManager.getPreviewParameters()); + }); + } + + @Test + public void test_previewConfirmedWithUrl_ConfirmPreviewParamsEmpty() { + runUsingMockedServiceProvider( + () -> { + // setup + previewManager.floatingButtonPresentable = floatingButton; + + // test + previewManager.previewConfirmedWithUrl( + fullscreenMessage, "adbinapp://confirm?abc=def"); + + // verify + verify(fullscreenMessage).dismiss(); + assertNull(previewManager.getPreviewParameters()); + }); + } + + @Test + public void test_previewConfirmedWithUrl_InvalidURI() { + runUsingMockedServiceProvider( + () -> { + // setup + previewManager.floatingButtonPresentable = floatingButton; + + // test + previewManager.previewConfirmedWithUrl(fullscreenMessage, "Invalid"); + + // verify + verify(fullscreenMessage).dismiss(); + assertNull(previewManager.getPreviewParameters()); + }); + } + + @Test + public void test_previewConfirmedWithUrl_InvalidScheme() { + runUsingMockedServiceProvider( + () -> { + // setup + previewManager.floatingButtonPresentable = floatingButton; + + // test + previewManager.previewConfirmedWithUrl( + fullscreenMessage, "notAppScheme://confirm?abc=def"); + + // verify + verify(fullscreenMessage).dismiss(); + assertNull(previewManager.getPreviewParameters()); + }); + } + + @Test + public void test_previewConfirmedWithUrl_When_RestartDeepLink() { + runUsingMockedServiceProvider( + () -> { + // setup + previewManager.floatingButtonPresentable = floatingButton; + previewManager.restartUrl = "restartURL"; + + // test + previewManager.previewConfirmedWithUrl( + fullscreenMessage, TEST_CONFIRM_DEEPLINK); + + // verify + verify(fullscreenMessage).dismiss(); + verify(uriService).openUri("restartURL"); + }); + } + + @Test + public void test_previewConfirmedWithUrl_When_RestartDeepLinkUnAvailable() { + runUsingMockedServiceProvider( + () -> { + + // setup + previewManager.floatingButtonPresentable = floatingButton; + previewManager.restartUrl = null; + + // test + previewManager.previewConfirmedWithUrl( + fullscreenMessage, TEST_CONFIRM_DEEPLINK); + + // verify + verify(fullscreenMessage).dismiss(); + verify(uriService, times(0)).openUri(any(String.class)); + }); + } + + @Test + public void + test_previewConfirmedWithUrl_ConfirmPreviewParamsEmpty_Should_Not_Dispatch_TargetResponseEvent() { + runUsingMockedServiceProvider( + () -> { + // setup + previewManager.floatingButtonPresentable = floatingButton; + + // test + previewManager.previewConfirmedWithUrl( + fullscreenMessage, "adbinapp://confirm?"); + + // verify + verify(fullscreenMessage).dismiss(); + assertNull(previewManager.getPreviewParameters()); + }); + } + + // =================================== + // Test fetchWebView + // =================================== + @Test + public void test_fetchWebView_Works() { + runUsingMockedServiceProvider( + () -> { + // setup + ArgumentCaptor networkResponseCapture = + ArgumentCaptor.forClass(NetworkRequest.class); + previewManager.endPoint = "someEndpoint"; + setMockConnectionResponse("TestHTML", 200); + + // test + previewManager.fetchWebView(); + + // verify network call + verify(networkService, times(1)) + .connectAsync(networkResponseCapture.capture(), any()); + assertEquals( + "network request has the correct httpcommand", + HttpMethod.GET, + networkResponseCapture.getValue().getMethod()); + assertEquals( + "network request has the correct read timeout", + 2, + networkResponseCapture.getValue().getReadTimeout()); + assertEquals( + "network request has the correct URL", + "https://someEndpoint/ui/admin/preview", + networkResponseCapture.getValue().getUrl()); + assertEquals( + "network request has the correct request property", + 2, + networkResponseCapture.getValue().getHeaders().size()); + assertEquals( + "network request has the correct request property", + "text/html", + networkResponseCapture.getValue().getHeaders().get("Accept")); + assertEquals( + "network request has the correct request property", + "application/x-www-form-urlencoded", + networkResponseCapture.getValue().getHeaders().get("Content-Type")); + + // verify fullscreen message created and displayed + verifyFullScreenMessageDisplayed(); + }); + } + + @Test + public void test_fetchWebView_EmptyServerResponse() { + try (MockedStatic base64MockedStatic = Mockito.mockStatic(Base64.class); + MockedStatic bitmapFactoryMockedStatic = + Mockito.mockStatic(BitmapFactory.class); + MockedStatic streamUtilsMockedStatic = + Mockito.mockStatic(StreamUtils.class)) { + base64MockedStatic + .when( + () -> + Base64.decode( + ArgumentMatchers.anyString(), + ArgumentMatchers.anyInt())) + .thenAnswer( + (Answer) + invocation -> + java.util.Base64.getDecoder() + .decode((String) invocation.getArguments()[0])); + bitmapFactoryMockedStatic + .when(() -> BitmapFactory.decodeStream(any(InputStream.class))) + .thenReturn(floatingButtonImage); + streamUtilsMockedStatic.when(() -> StreamUtils.readAsString(any())).thenReturn(null); + // setup + ArgumentCaptor networkResponseCapture = + ArgumentCaptor.forClass(NetworkRequest.class); + previewManager.endPoint = "someEndpoint"; + setMockConnectionResponse("", 200); + + // test + previewManager.fetchWebView(); + + // verify network call + verify(networkService, times(1)).connectAsync(networkResponseCapture.capture(), any()); + assertEquals( + "network request has the correct URL", + "https://someEndpoint/ui/admin/preview", + networkResponseCapture.getValue().getUrl()); + + // verify message not displayed + verifyNoInteractions(uiService); + } + } + + @Test + public void test_fetchWebView_WhenConnectionNull() { + runUsingMockedServiceProvider( + () -> { + // setup + ArgumentCaptor networkResponseCapture = + ArgumentCaptor.forClass(NetworkRequest.class); + previewManager.endPoint = "someEndpoint"; + doAnswer( + invocation -> { + ((NetworkCallback) invocation.getArguments()[1]).call(null); + return null; + }) + .when(networkService) + .connectAsync(any(), any()); + + // test + previewManager.fetchWebView(); + + // verify network call + verify(networkService, times(1)) + .connectAsync(networkResponseCapture.capture(), any()); + assertEquals( + "network request has the correct URL", + "https://someEndpoint/ui/admin/preview", + networkResponseCapture.getValue().getUrl()); + + // verify message not displayed + verifyNoInteractions(uiService); + }); + } + + @Test + public void test_fetchWebView_ResponseCodeNot200() { + runUsingMockedServiceProvider( + () -> { + // setup + ArgumentCaptor networkResponseCapture = + ArgumentCaptor.forClass(NetworkRequest.class); + previewManager.endPoint = "someEndpoint"; + setMockConnectionResponse("TestHTML", 202); + + // test + previewManager.fetchWebView(); + + // verify network call + verify(networkService, times(1)) + .connectAsync(networkResponseCapture.capture(), any()); + assertEquals( + "network request has the correct URL", + "https://someEndpoint/ui/admin/preview", + networkResponseCapture.getValue().getUrl()); + + // verify message not displayed + verifyNoInteractions(uiService); + }); + } + + // =================================== + // Test setRestartDeepLink + // =================================== + @Test + public void test_setRestartDeepLink() { + runUsingMockedServiceProvider( + () -> { + // test + previewManager.setRestartDeepLink("restartURL"); + + // verify + assertEquals("restartURL", previewManager.restartUrl); + }); + } + + @Test + public void test_setRestartDeepLink_Null() { + runUsingMockedServiceProvider( + () -> { + // test + previewManager.setRestartDeepLink(null); + + // verify + assertNull(previewManager.restartUrl); + }); + } + + // =================================== + // Test getPreviewParameters + // =================================== + @Test + public void test_getPreviewParameters() { + runUsingMockedServiceProvider( + () -> { + // setup + previewManager.previewParams = "params"; + + // test + assertEquals("params", previewManager.getPreviewParameters()); + }); + } + + private void verifyFullScreenMessageDisplayed() { + verify(uiService, times(1)) + .create(any(InAppMessage.class), any(PresentationUtilityProvider.class)); + verify(fullscreenMessage).show(); + } + + private void verifyFloatingButtonDisplayed() { + verify(uiService, times(1)) + .create(any(FloatingButton.class), any(PresentationUtilityProvider.class)); + verify(floatingButton).show(); + } +} diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetProductTests.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetProductTests.java index 172676a..15aebb2 100644 --- a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetProductTests.java +++ b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetProductTests.java @@ -1,14 +1,13 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; @@ -16,23 +15,23 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import org.junit.Test; - import java.util.HashMap; import java.util.Map; +import org.junit.Test; public class TargetProductTests { - final static String PRODUCT_ID_HAPPY_PATH = "pId"; - final static String CATEGORY_ID_HAPPY_PATH = "cId"; + static final String PRODUCT_ID_HAPPY_PATH = "pId"; + static final String CATEGORY_ID_HAPPY_PATH = "cId"; protected final TargetProduct PRODUCT_PARAMETERS_HAPPY_PATH = new TargetProduct("pId", "cId"); - protected final Map PRODUCT_PARAMETERS_HAPPY_PATH_MAP = new HashMap() { - { - put("id", "pId"); - put("categoryId", "cId"); - } - }; + protected final Map PRODUCT_PARAMETERS_HAPPY_PATH_MAP = + new HashMap() { + { + put("id", "pId"); + put("categoryId", "cId"); + } + }; @Test public void testTargetProduct_happy() { @@ -44,7 +43,8 @@ public void testTargetProduct_happy() { @Test public void testFromEventData_validProduct() throws Exception { - TargetProduct targetProduct = TargetProduct.fromEventData(PRODUCT_PARAMETERS_HAPPY_PATH_MAP); + TargetProduct targetProduct = + TargetProduct.fromEventData(PRODUCT_PARAMETERS_HAPPY_PATH_MAP); assertNotNull(targetProduct); assertEquals(PRODUCT_ID_HAPPY_PATH, targetProduct.getId()); assertEquals(CATEGORY_ID_HAPPY_PATH, targetProduct.getCategoryId()); @@ -66,35 +66,38 @@ public void testFromEventData_emptyProduct() throws Exception { @Test public void testFromEventData_invalidProductNullId() throws Exception { - Map productMap = new HashMap() { - { - put("id", null); - put("categoryId", "cId"); - } - }; + Map productMap = + new HashMap() { + { + put("id", null); + put("categoryId", "cId"); + } + }; TargetProduct targetProduct = TargetProduct.fromEventData(productMap); assertNull(targetProduct); } @Test public void testFromEventData_invalidOrderEmptyId() throws Exception { - Map productMap = new HashMap() { - { - put("id", ""); - put("categoryId", "cId"); - } - }; + Map productMap = + new HashMap() { + { + put("id", ""); + put("categoryId", "cId"); + } + }; TargetProduct targetProduct = TargetProduct.fromEventData(productMap); assertNull(targetProduct); } @Test public void testFromEventData_invalidOrderMissingId() throws Exception { - Map productMap = new HashMap() { - { - put("categoryId", "cId"); - } - }; + Map productMap = + new HashMap() { + { + put("categoryId", "cId"); + } + }; TargetProduct targetProduct = TargetProduct.fromEventData(productMap); assertNull(targetProduct); } diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetRequestBuilderTest.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetRequestBuilderTest.java index 2797fc6..2756a33 100644 --- a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetRequestBuilderTest.java +++ b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetRequestBuilderTest.java @@ -1,5 +1,5 @@ /* - Copyright 2023 Adobe. All rights reserved. + Copyright 2022 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -7,7 +7,7 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ +*/ package com.adobe.marketing.mobile.target; @@ -16,10 +16,16 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import com.adobe.marketing.mobile.VisitorID; +import com.adobe.marketing.mobile.services.DeviceInforming; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -27,149 +33,172 @@ import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.adobe.marketing.mobile.VisitorID; -import com.adobe.marketing.mobile.services.DeviceInforming; - @RunWith(MockitoJUnitRunner.Silent.class) public class TargetRequestBuilderTest { - static final String METRICS = "metrics"; - static final String CONTEXT_PARAMETERS = "context"; - static String ID = "id"; - static String MARKETING_CLOUD_ID = "marketingCloudVisitorId"; - static String EXPERIENCE_CLOUD = "experienceCloud"; - static String CUSTOMER_IDS = "customerIds"; - static String LOCATION_HINT = "locationHint"; - static String BLOB = "blob"; - static String CATEGORY_ID = "categoryId"; - static String ORDER_TOTAL = "total"; - static String NAME = "name"; - static String PARAMETERS = "parameters"; - static String INDEX = "index"; - static String PRODUCT = "product"; - static String ORDER = "order"; - static String PURCHASED_PRODUCT_IDS = "purchasedProductIds"; - static String ENVIRONMENT_ID = "environmentId"; - static String PREFETCH_MBOXES = "prefetch"; - static String EXECUTE_MBOXES = "execute"; - static String PROFILE_PARAMETERS = "profileParameters"; - static String VISITED_MBOXES = "notifications"; - static String MBOX = "mbox"; - static String MBOXES = "mboxes"; - static String AAM_PARAMETERS = "audienceManager"; - static final String CUSTOMER_ID_ID = "id"; - static final String CUSTOMER_ID_INTEGRATION_CODE = "integrationCode"; - static final String CUSTOMER_ID_AUTHENTICATION_STATE = "authenticatedState"; - - static final String VISITOR_ID_MID = "mid"; - static final String VISITOR_ID_BLOB = "blob"; - static final String VISITOR_ID_LOCATION_HINT = "locationhint"; - static final String VISITOR_IDS_LIST = "visitoridslist"; - static final String VISITOR_IDS_ID = "ID"; - static final String VISITOR_IDS_ID_TYPE = "ID_TYPE"; - static final String VISITOR_IDS_STATE = "STATE"; - static final String VISITOR_IDS_ID_ORIGIN = "ID_ORIGIN"; - - static String PROPERTY = "property"; - static String TOKEN = "token"; - static String TOKENS = "tokens"; - static String AUTHENTICATION_STATE = "authenticatedState"; - - static String TIMESTAMP = "timestamp"; - static String CONTENT = "content"; - static String A4T = "clientSideAnalyticsLoggingPayload"; - static String METRIC_TYPE = "type"; - static String METRIC_TYPE_DISPLAY = "display"; - static String METRIC_TYPE_CLICK = "click"; - static String PREVIEW_QA_MODE = "qaMode"; - static String STATE = "state"; - static String OPTIONS= "options"; - - // setup - static Map lifecycleData = new HashMap() { - { - put("a.OSVersion", "iOS 14.2"); - put("a.DaysSinceFirstUse", "0"); - put("a.CrashEvent", "CrashEvent"); - put("a.CarrierName", "(nil)"); - put("a.Resolution", "828x1792"); - put("a.RunMode", "Application"); - put("a.ignoredSessionLength", "-1605549540"); - put("a.HourOfDay", "11"); - put("a.AppID", "v5ManualTestApp 1.0 (1)"); - put("a.DayOfWeek", "2"); - put("a.DeviceName", "x86_64"); - put("a.LaunchEvent", "LaunchEvent"); - put("a.Launches", "2"); - put("a.DaysSinceLastUse", "0"); - put("a.locale", "en-US"); - } - }; - - @Mock - DeviceInforming mockDeviceInfoService; - - @Mock - TargetPreviewManager mockTargetPreviewManager; - - @Mock - TargetState mockTargetState; - - TargetRequestBuilder targetRequestBuilder; - - @Before - public void beforeEach() { - targetRequestBuilder = new TargetRequestBuilder(mockDeviceInfoService, mockTargetPreviewManager, mockTargetState); - } + static final String METRICS = "metrics"; + static final String CONTEXT_PARAMETERS = "context"; + static String ID = "id"; + static String MARKETING_CLOUD_ID = "marketingCloudVisitorId"; + static String EXPERIENCE_CLOUD = "experienceCloud"; + static String CUSTOMER_IDS = "customerIds"; + static String LOCATION_HINT = "locationHint"; + static String BLOB = "blob"; + static String CATEGORY_ID = "categoryId"; + static String ORDER_TOTAL = "total"; + static String NAME = "name"; + static String PARAMETERS = "parameters"; + static String INDEX = "index"; + static String PRODUCT = "product"; + static String ORDER = "order"; + static String PURCHASED_PRODUCT_IDS = "purchasedProductIds"; + static String ENVIRONMENT_ID = "environmentId"; + static String PREFETCH_MBOXES = "prefetch"; + static String EXECUTE_MBOXES = "execute"; + static String PROFILE_PARAMETERS = "profileParameters"; + static String VISITED_MBOXES = "notifications"; + static String MBOX = "mbox"; + static String MBOXES = "mboxes"; + static String AAM_PARAMETERS = "audienceManager"; + static final String CUSTOMER_ID_ID = "id"; + static final String CUSTOMER_ID_INTEGRATION_CODE = "integrationCode"; + static final String CUSTOMER_ID_AUTHENTICATION_STATE = "authenticatedState"; + + static final String VISITOR_ID_MID = "mid"; + static final String VISITOR_ID_BLOB = "blob"; + static final String VISITOR_ID_LOCATION_HINT = "locationhint"; + static final String VISITOR_IDS_LIST = "visitoridslist"; + static final String VISITOR_IDS_ID = "ID"; + static final String VISITOR_IDS_ID_TYPE = "ID_TYPE"; + static final String VISITOR_IDS_STATE = "STATE"; + static final String VISITOR_IDS_ID_ORIGIN = "ID_ORIGIN"; + + static String PROPERTY = "property"; + static String TOKEN = "token"; + static String TOKENS = "tokens"; + static String AUTHENTICATION_STATE = "authenticatedState"; + + static String TIMESTAMP = "timestamp"; + static String CONTENT = "content"; + static String A4T = "clientSideAnalyticsLoggingPayload"; + static String METRIC_TYPE = "type"; + static String METRIC_TYPE_DISPLAY = "display"; + static String METRIC_TYPE_CLICK = "click"; + static String PREVIEW_QA_MODE = "qaMode"; + static String STATE = "state"; + static String OPTIONS = "options"; + + // setup + static Map lifecycleData = + new HashMap() { + { + put("a.OSVersion", "iOS 14.2"); + put("a.DaysSinceFirstUse", "0"); + put("a.CrashEvent", "CrashEvent"); + put("a.CarrierName", "(nil)"); + put("a.Resolution", "828x1792"); + put("a.RunMode", "Application"); + put("a.ignoredSessionLength", "-1605549540"); + put("a.HourOfDay", "11"); + put("a.AppID", "v5ManualTestApp 1.0 (1)"); + put("a.DayOfWeek", "2"); + put("a.DeviceName", "x86_64"); + put("a.LaunchEvent", "LaunchEvent"); + put("a.Launches", "2"); + put("a.DaysSinceLastUse", "0"); + put("a.locale", "en-US"); + } + }; + + @Mock DeviceInforming mockDeviceInfoService; + + @Mock TargetPreviewManager mockTargetPreviewManager; + + @Mock TargetState mockTargetState; + + TargetRequestBuilder targetRequestBuilder; + + @Before + public void beforeEach() { + targetRequestBuilder = + new TargetRequestBuilder( + mockDeviceInfoService, mockTargetPreviewManager, mockTargetState); + } // =================================== // Test getRequestPayload_prefetch // =================================== @Test public void getRequestPayload_PrefetchInJson_When_PrefetchListContainsOneObject() { - // test - JSONObject json = targetRequestBuilder.getRequestPayload(getTargetPrefetchList(1), null, null, - null, null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + getTargetPrefetchList(1), null, null, null, null, null, null); - // verify + // verify assertEquals(1, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).length()); - assertEquals(0, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(INDEX)); - assertEquals("mbox0", json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(NAME)); + assertEquals( + 0, + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .opt(INDEX)); + assertEquals( + "mbox0", + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .opt(NAME)); } @Test public void getRequestPayload_PrefetchInJson_When_PrefetchListContainsTwoObjects() { - // test - JSONObject json = targetRequestBuilder.getRequestPayload(getTargetPrefetchList(2), null, null, - null, null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + getTargetPrefetchList(2), null, null, null, null, null, null); - // verify - assertEquals(2, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).length()); - assertEquals(0, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(INDEX)); - assertEquals("mbox0", json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(NAME)); - assertEquals(1, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(1).opt(INDEX)); - assertEquals("mbox1", json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(1).opt(NAME)); + // verify + assertEquals(2, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + 0, + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .opt(INDEX)); + assertEquals( + "mbox0", + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .opt(NAME)); + assertEquals( + 1, + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(1) + .opt(INDEX)); + assertEquals( + "mbox1", + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(1) + .opt(NAME)); } - @Test public void getRequestPayload_PrefetchInJson_When_PrefetchListIsEmptyOrNull() { - // test - JSONObject json = targetRequestBuilder.getRequestPayload(getTargetPrefetchList(0), null, null, - null, null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + getTargetPrefetchList(0), null, null, null, null, null, null); - // verify + // verify assertNull(json.optJSONArray(PREFETCH_MBOXES)); - // test + // test json = targetRequestBuilder.getRequestPayload(null, null, null, null, null, null, null); - // verify + // verify assertNull(json.optJSONArray(PREFETCH_MBOXES)); } @@ -178,36 +207,39 @@ public void getRequestPayload_PrefetchInJson_When_PrefetchListIsEmptyOrNull() { // =================================== @Test public void getRequestPayload_ProfileWhen_ProfileParametersIsValid() { - // setup - Map map = new HashMap() { - { - put("key", "value"); - } - }; + // setup + Map map = + new HashMap() { + { + put("key", "value"); + } + }; TargetParameters params = new TargetParameters.Builder().profileParameters(map).build(); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, params, null, null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(null, null, params, null, null, null, null); - // verify + // verify assertNull(json.optJSONObject(EXECUTE_MBOXES)); assertNull(json.optJSONObject(PREFETCH_MBOXES)); } @Test public void getRequestPayload_ProfileParametersNotInJson_When_ProfileParametersIsEmptyOrNull() { - // setup + // setup Map map = new HashMap(); TargetParameters params = new TargetParameters.Builder(map).build(); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, params, null, null, null, null); - // verify + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(null, null, params, null, null, null, null); + // verify assertNull(json.optJSONObject(PROFILE_PARAMETERS)); - // test + // test json = targetRequestBuilder.getRequestPayload(null, null, params, null, null, null, null); - // verify + // verify assertNull(json.optJSONObject(PROFILE_PARAMETERS)); } @@ -216,41 +248,65 @@ public void getRequestPayload_ProfileParametersNotInJson_When_ProfileParametersI // =================================== @Test public void getRequestPayload_BatchInJson_When_BatchListContainsOneObject() { - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, getTargetRequestList(1), null, - null, null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, getTargetRequestList(1), null, null, null, null, null); - // verify + // verify assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals(0, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(INDEX)); - assertEquals("mbox0", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(NAME)); + assertEquals( + 0, + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .opt(INDEX)); + assertEquals( + "mbox0", + json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(NAME)); } @Test public void getRequestPayload_BatchInJson_When_BatchListContainsTwoObjects() { - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, getTargetRequestList(2), null, - null, null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, getTargetRequestList(2), null, null, null, null, null); - // verify + // verify assertEquals(2, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals(0, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(INDEX)); - assertEquals("mbox0", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(NAME)); - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(1).opt(INDEX)); - assertEquals("mbox1", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(1).opt(NAME)); + assertEquals( + 0, + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .opt(INDEX)); + assertEquals( + "mbox0", + json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(NAME)); + assertEquals( + 1, + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(1) + .opt(INDEX)); + assertEquals( + "mbox1", + json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(1).opt(NAME)); } @Test public void getRequestPayload_BatchNotInJson_When_BatchListIsEmptyOrNull() { - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, getTargetRequestList(0), null, - null, null, null, null); - // verify + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, getTargetRequestList(0), null, null, null, null, null); + // verify assertNull(json.optJSONObject(EXECUTE_MBOXES)); - // test + // test json = targetRequestBuilder.getRequestPayload(null, null, null, null, null, null, null); - // verify + // verify assertNull(json.optJSONObject(EXECUTE_MBOXES)); } @@ -259,35 +315,42 @@ public void getRequestPayload_BatchNotInJson_When_BatchListIsEmptyOrNull() { // =================================== @Test public void getRequestPayload_NotificationInJson_When_NotificationListContainsOneObject() { - // setup - List notifications = new ArrayList() { - { - add(new JSONObject()); - } - }; + // setup + List notifications = + new ArrayList() { + { + add(new JSONObject()); + } + }; - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null, notifications , null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, notifications, null, null, null); - // verify + // verify assertEquals(1, json.optJSONArray(VISITED_MBOXES).length()); assertEquals("{}", json.optJSONArray(VISITED_MBOXES).optJSONObject(0).toString()); } @Test - public void getRequestPayload_NotificationInJson_When_NotificationListContainsTwoObjects() throws JSONException { - // setup - List notifications = new ArrayList() { - { - add(new JSONObject()); - add(new JSONObject("{\"id\":1}")); - } - }; + public void getRequestPayload_NotificationInJson_When_NotificationListContainsTwoObjects() + throws JSONException { + // setup + List notifications = + new ArrayList() { + { + add(new JSONObject()); + add(new JSONObject("{\"id\":1}")); + } + }; - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null,notifications, null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, notifications, null, null, null); - // verify + // verify assertEquals(2, json.optJSONArray(VISITED_MBOXES).length()); assertEquals("{}", json.optJSONArray(VISITED_MBOXES).optJSONObject(0).toString()); assertEquals("{\"id\":1}", json.optJSONArray(VISITED_MBOXES).optJSONObject(1).toString()); @@ -295,15 +358,16 @@ public void getRequestPayload_NotificationInJson_When_NotificationListContainsTw @Test public void getRequestPayload_NotificationNotInJson_When_NotificationListIsEmpytOrNull() { - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null, - new ArrayList<>(), null, null, null); - // verify + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, new ArrayList<>(), null, null, null); + // verify assertNull(json.optJSONArray(VISITED_MBOXES)); - // test + // test json = targetRequestBuilder.getRequestPayload(null, null, null, null, null, null, null); - // verify + // verify assertNull(json.optJSONArray(VISITED_MBOXES)); } @@ -312,1924 +376,2721 @@ public void getRequestPayload_NotificationNotInJson_When_NotificationListIsEmpyt // =================================== @Test public void getRequestPayload_PreviewInJson_When_PreviewTokenAndPreviewParameterValid() { - // setup + // setup Mockito.when(mockTargetPreviewManager.getPreviewToken()).thenReturn("previewToken"); - Mockito.when(mockTargetPreviewManager.getPreviewParameters()).thenReturn("{\"qaMode\":{\"key\":\"value\"}}"); + Mockito.when(mockTargetPreviewManager.getPreviewParameters()) + .thenReturn("{\"qaMode\":{\"key\":\"value\"}}"); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null, null, null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(null, null, null, null, null, null, null); - // verify + // verify assertEquals("value", json.optJSONObject(PREVIEW_QA_MODE).opt("key")); } @Test public void getRequestPayload_PreviewInJson_When_PreviewTokenIsEmpty() { - // setup + // setup Mockito.when(mockTargetPreviewManager.getPreviewToken()).thenReturn(""); - Mockito.when(mockTargetPreviewManager.getPreviewParameters()).thenReturn("{\"qaMode\":{\"key\":\"value\"}}"); + Mockito.when(mockTargetPreviewManager.getPreviewParameters()) + .thenReturn("{\"qaMode\":{\"key\":\"value\"}}"); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null, null, null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(null, null, null, null, null, null, null); - // verify - assertEquals("value", json.optJSONObject(PREVIEW_QA_MODE).opt("key")); + // verify + assertEquals("value", json.optJSONObject(PREVIEW_QA_MODE).opt("key")); } @Test public void getRequestPayload_PreviewNotInJson_When_PreviewTokenIsNull() { - // setup + // setup Mockito.when(mockTargetPreviewManager.getPreviewToken()).thenReturn(null); - Mockito.when(mockTargetPreviewManager.getPreviewParameters()).thenReturn("{\"qaMode\":{\"key\":\"value\"}}"); + Mockito.when(mockTargetPreviewManager.getPreviewParameters()) + .thenReturn("{\"qaMode\":{\"key\":\"value\"}}"); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null, null, null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(null, null, null, null, null, null, null); - // verify + // verify assertNull(json.optJSONObject(PREVIEW_QA_MODE)); - } @Test public void getRequestPayload_PreviewInJson_When_PreviewParameterIsEmpty() { - // setup + // setup Mockito.when(mockTargetPreviewManager.getPreviewToken()).thenReturn("previewToken"); Mockito.when(mockTargetPreviewManager.getPreviewParameters()).thenReturn(""); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null, null, null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(null, null, null, null, null, null, null); - // verify + // verify assertNull(json.optJSONObject(PREVIEW_QA_MODE)); } @Test public void getRequestPayload_PreviewNotInJson_When_PreviewParameterIsNull() { - // setup + // setup Mockito.when(mockTargetPreviewManager.getPreviewToken()).thenReturn("previewToken"); Mockito.when(mockTargetPreviewManager.getPreviewParameters()).thenReturn(null); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null, null, null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(null, null, null, null, null, null, null); - // verify + // verify assertNull(json.optJSONObject(PREVIEW_QA_MODE)); - } // =================================== // Test getRequestPayload_orderParameters - // =================================== - @Test - public void getRequestPayload_OrderWhen_OrderParametersAreValid() { - // setup - TargetOrder targetOrder = new TargetOrder("orderId", 0.1, new ArrayList() { - { - add("id1"); - add("id2"); - } - }); - TargetParameters targetParameters = new TargetParameters.Builder().order(targetOrder).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, null, null, null); - - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals(0.1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER).opt( - ORDER_TOTAL)); - assertEquals("orderId", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - ORDER).opt(ID)); - assertEquals(2, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - ORDER).optJSONArray( - PURCHASED_PRODUCT_IDS).length()); - assertEquals("id1", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - ORDER).optJSONArray( - PURCHASED_PRODUCT_IDS).opt(0)); - assertEquals("id2", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - ORDER).optJSONArray( - PURCHASED_PRODUCT_IDS).opt(1)); - - } - - @Test - public void getRequestPayload_OrderIdNotInJson_When_OrderIdIsEmpty() { - // setup - TargetOrder targetOrder = new TargetOrder("", 0.1, null); - TargetParameters targetParameters = new TargetParameters.Builder().order(targetOrder).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, null, null, null); - - // verify - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER)); - } - - @Test - public void getRequestPayload_OrderIdNotInJson_When_OrderIdIsNull() { - // setup - TargetOrder targetOrder = new TargetOrder(null, 0.1, null); - TargetParameters targetParameters = new TargetParameters.Builder().order(targetOrder).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, null, null, null); - - // verify - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER)); - } - - @Test - public void getRequestPayload_NoOrderIdInJson_NoOrderInJson_When_PurchasedProductIdsIsEmpty() { - // setup - TargetOrder targetOrder = new TargetOrder("orderId", 0.1, new ArrayList<>()); - TargetParameters targetParameters = new TargetParameters.Builder().order(targetOrder).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, null, null, null); - - // verify - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER).optJSONArray( - PURCHASED_PRODUCT_IDS)); - } - - @Test - public void getRequestPayload_NoOrderIdInJson_NoOrderInJson_When_PurchasedProductIdsIsNull() { - // setup - TargetOrder targetOrder = new TargetOrder("orderId", 0.1, null); - TargetParameters targetParameters = new TargetParameters.Builder().order(targetOrder).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, null, null, null); - - // verify - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER).optJSONArray( - PURCHASED_PRODUCT_IDS)); - } - - @Test - public void getRequestPayload_OrderParametersFromMap_When_OrderParametersAreValid() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .order(TargetOrder.fromEventData(new HashMap() { - { - put(ID, "orderId"); - put(ORDER_TOTAL, 0.1); - put(PURCHASED_PRODUCT_IDS, new ArrayList() { - { - add("id1"); - add("id2"); - } - }); - } - })).build(); - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals(0.1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER).opt( - ORDER_TOTAL)); - assertEquals("orderId", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - ORDER).opt(ID)); - assertEquals(2, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - ORDER).optJSONArray( - PURCHASED_PRODUCT_IDS).length()); - assertEquals("id1", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - ORDER).optJSONArray( - PURCHASED_PRODUCT_IDS).opt(0)); - assertEquals("id2", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - ORDER).optJSONArray( - PURCHASED_PRODUCT_IDS).opt(1)); - } - - @Test - public void getRequestPayload_OrderParametersFromMap_OrderNotInJson_When_OrderIdIsEmpty() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .order(TargetOrder.fromEventData(new HashMap() { - { - put(ID, ""); - put(ORDER_TOTAL, ""); - } - })).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER)); - } - - @Test - public void getRequestPayload_OrderParametersFromMap_OrderNotInJson_When_OrderIdIsNull() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .order(TargetOrder.fromEventData(new HashMap() { - { - put(ID, null); - put(ORDER_TOTAL, ""); - } - })).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER)); - } - - @Test - public void getRequestPayload_OrderParametersFromMap_NoOrderInJson_When_OrderTotalIsEmpty() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .order(TargetOrder.fromEventData(new HashMap() { - { - put(ID, "orderId"); - put(ORDER_TOTAL, ""); - } - })).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER)); - } - - @Test - public void getRequestPayload_OrderParametersFromMap_NoOrderInJson_When_OrderTotalIsNull() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .order(TargetOrder.fromEventData(new HashMap() { - { - put(ID, "orderId"); - put(ORDER_TOTAL, null); - } - })).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER)); - } - - @Test - public void getRequestPayload_OrderParametersFromMap_NoOrderInJson_When_OrderTotalIsStringDouble() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .order(TargetOrder.fromEventData(new HashMap() { - { - put(ID, "orderId"); - put(ORDER_TOTAL, "0.1"); - } - })).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER)); - } - - @Test - public void getRequestPayload_OrderParametersFromMap_NoOrderInJson_When_OrderTotalIsRandomString() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .order(TargetOrder.fromEventData(new HashMap() { - { - put(ID, "orderId"); - put(ORDER_TOTAL, "total"); - } - })).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER)); - } - - @Test - public void getRequestPayload_OrderParametersFromMap_NoOrderInJson_When_PurchasedProductIdsIsEmpty() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .order(TargetOrder.fromEventData(new HashMap() { - { - put(ID, "orderId"); - put(ORDER_TOTAL, null); - put(PURCHASED_PRODUCT_IDS, new ArrayList() { - { - } - }); - } - })).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER)); - } - - @Test - public void getRequestPayload_OrderParametersFromMap_NoOrderInJson_When_PurchasedProductIdsOnlyContainsNoneString() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .order(TargetOrder.fromEventData(new HashMap() { - { - put(ID, "orderId"); - put(ORDER_TOTAL, null); - put(PURCHASED_PRODUCT_IDS, new ArrayList() { - { - add(new Object()); - } - }); - } - })).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER)); - } - - // =================================== - // Test getRequestPayload_ProductParameters // =================================== @Test - public void getRequestPayload_ProductWhen_ProductParametersIsValid() { - // setup - TargetProduct targetProduct = new TargetProduct("productId", "categoryId"); - TargetParameters targetParameters = new TargetParameters.Builder().product(targetProduct).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); + public void getRequestPayload_OrderWhen_OrderParametersAreValid() { + // setup + TargetOrder targetOrder = + new TargetOrder( + "orderId", + 0.1, + new ArrayList() { + { + add("id1"); + add("id2"); + } + }); + TargetParameters targetParameters = + new TargetParameters.Builder().order(targetOrder).build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); List targetRequestList = new ArrayList<>(); targetRequestList.add(targetRequest); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); - // verify + // verify assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("productId", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PRODUCT).opt(ID)); - assertEquals("categoryId", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PRODUCT).opt(CATEGORY_ID)); - + assertEquals( + 0.1, + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER) + .opt(ORDER_TOTAL)); + assertEquals( + "orderId", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER) + .opt(ID)); + assertEquals( + 2, + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER) + .optJSONArray(PURCHASED_PRODUCT_IDS) + .length()); + assertEquals( + "id1", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER) + .optJSONArray(PURCHASED_PRODUCT_IDS) + .opt(0)); + assertEquals( + "id2", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER) + .optJSONArray(PURCHASED_PRODUCT_IDS) + .opt(1)); } @Test - public void getRequestPayload_ProductIdNotInJson_When_ProductIdIsNull() { - // setup - TargetProduct targetProduct = new TargetProduct(null, "categoryId"); - TargetParameters targetParameters = new TargetParameters.Builder().product(targetProduct).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); + public void getRequestPayload_OrderIdNotInJson_When_OrderIdIsEmpty() { + // setup + TargetOrder targetOrder = new TargetOrder("", 0.1, null); + TargetParameters targetParameters = + new TargetParameters.Builder().order(targetOrder).build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); List targetRequestList = new ArrayList<>(); targetRequestList.add(targetRequest); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PRODUCT)); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + // verify + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER)); } @Test - public void getRequestPayload_ProductIdNotInJson_When_ProductIdIsEmpty() { - // setup - TargetProduct targetProduct = new TargetProduct("", "categoryId"); - TargetParameters targetParameters = new TargetParameters.Builder().product(targetProduct).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); + public void getRequestPayload_OrderIdNotInJson_When_OrderIdIsNull() { + // setup + TargetOrder targetOrder = new TargetOrder(null, 0.1, null); + TargetParameters targetParameters = + new TargetParameters.Builder().order(targetOrder).build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); List targetRequestList = new ArrayList<>(); targetRequestList.add(targetRequest); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PRODUCT)); + // verify + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER)); } @Test - public void getRequestPayload_NoProductInJson_When_ProductCategoryIsEmpty() { - // setup - TargetProduct targetProduct = new TargetProduct("productId", ""); - TargetParameters targetParameters = new TargetParameters.Builder().product(targetProduct).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); + public void getRequestPayload_NoOrderIdInJson_NoOrderInJson_When_PurchasedProductIdsIsEmpty() { + // setup + TargetOrder targetOrder = new TargetOrder("orderId", 0.1, new ArrayList<>()); + TargetParameters targetParameters = + new TargetParameters.Builder().order(targetOrder).build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); List targetRequestList = new ArrayList<>(); targetRequestList.add(targetRequest); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("productId", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PRODUCT).opt(ID)); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PRODUCT).opt( - CATEGORY_ID)); - } + // verify + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER) + .optJSONArray(PURCHASED_PRODUCT_IDS)); + } @Test - public void getRequestPayload_NoProductInJson_When_ProductCategoryIsNull() { - // setup - TargetProduct targetProduct = new TargetProduct("productId", null); - TargetParameters targetParameters = new TargetParameters.Builder().product(targetProduct).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); + public void getRequestPayload_NoOrderIdInJson_NoOrderInJson_When_PurchasedProductIdsIsNull() { + // setup + TargetOrder targetOrder = new TargetOrder("orderId", 0.1, null); + TargetParameters targetParameters = + new TargetParameters.Builder().order(targetOrder).build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); List targetRequestList = new ArrayList<>(); targetRequestList.add(targetRequest); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER) + .optJSONArray(PURCHASED_PRODUCT_IDS)); + } - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("productId", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PRODUCT).opt(ID)); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PRODUCT).opt( - CATEGORY_ID)); - } - - @Test - public void getRequestPayload_ProductFromMap_When_ProductParameterAreValid() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .product(TargetProduct.fromEventData(new HashMap() { - { - put(ID, "productId"); - put(CATEGORY_ID, "categoryId"); - } - })).build(); - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("productId", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PRODUCT).opt(ID)); - assertEquals("categoryId", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PRODUCT).opt(CATEGORY_ID)); - } - - @Test - public void getRequestPayload_ProductFromMap_ProductIdNotInJson_When_ProductIdIsNull() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .product(TargetProduct.fromEventData(new HashMap () { - { - put(ID, null); - put(CATEGORY_ID, "categoryId"); - } - })).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PRODUCT)); - - } - - @Test - public void getRequestPayload_ProductFromMap_ProductIdNotInJson_When_ProductIdIsEmpty() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .product(TargetProduct.fromEventData(new HashMap () { - { - put(ID, ""); - put(CATEGORY_ID, "categoryId"); - } - })).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PRODUCT)); - } - - @Test - public void getRequestPayload_ProductFromMap_NoProductInJson_When_ProductCategoryIsEmpty() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .product(TargetProduct.fromEventData(new HashMap () { - { - put(ID, "productId"); - put(CATEGORY_ID, ""); - } - })).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("productId", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PRODUCT).opt(ID)); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PRODUCT).opt( - CATEGORY_ID)); - } - - @Test - public void getRequestPayload_ProductFromMap_NoProductInJson_When_ProductCategoryIsNull() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .product(TargetProduct.fromEventData(new HashMap () { - { - put(ID, "productId"); - put(CATEGORY_ID, null); - } - })).build(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - List targetRequestList = new ArrayList<>(); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("productId", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PRODUCT).opt(ID)); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PRODUCT).opt( - CATEGORY_ID)); - } - - // =================================== - // Test getRequestPayload_rawPrefetch - // =================================== @Test - public void getRequestPayload_PrefetchInJson() { + public void getRequestPayload_OrderParametersFromMap_When_OrderParametersAreValid() { // setup - final JSONObject defaultJson = new JSONObject();; - final Map prefetchMbox1 = new HashMap() { - { - put("index", 0); - put("name", "mbox1"); - } - }; - final Map prefetchMbox2 = new HashMap() { - { - put("index", 1); - put("name", "mbox2"); - } - }; - final List> prefetchMboxes = new ArrayList<>(); - prefetchMboxes.add(prefetchMbox1); - prefetchMboxes.add(prefetchMbox2); - - final Map prefetch = new HashMap() { - { - put("mboxes", prefetchMboxes); - } - }; + TargetParameters targetParameters = + new TargetParameters.Builder() + .order( + TargetOrder.fromEventData( + new HashMap() { + { + put(ID, "orderId"); + put(ORDER_TOTAL, 0.1); + put( + PURCHASED_PRODUCT_IDS, + new ArrayList() { + { + add("id1"); + add("id2"); + } + }); + } + })) + .build(); + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + targetRequestList.add(targetRequest); // test - JSONObject json = targetRequestBuilder.getRequestPayload(defaultJson, prefetch, null, null, - null); + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); // verify - assertEquals(2, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).length()); - assertEquals(0, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(INDEX)); - assertEquals("mbox1", json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(NAME)); - assertEquals(1, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(1).opt(INDEX)); - assertEquals("mbox2", json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(1).opt(NAME)); + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + 0.1, + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER) + .opt(ORDER_TOTAL)); + assertEquals( + "orderId", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER) + .opt(ID)); + assertEquals( + 2, + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER) + .optJSONArray(PURCHASED_PRODUCT_IDS) + .length()); + assertEquals( + "id1", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER) + .optJSONArray(PURCHASED_PRODUCT_IDS) + .opt(0)); + assertEquals( + "id2", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER) + .optJSONArray(PURCHASED_PRODUCT_IDS) + .opt(1)); } @Test - public void getRequestPayload_NoPrefetchInJson_When_PrefetchMapIsEmpty() { + public void getRequestPayload_OrderParametersFromMap_OrderNotInJson_When_OrderIdIsEmpty() { // setup - final JSONObject defaultJson = new JSONObject();; - final Map prefetch = new HashMap(); + TargetParameters targetParameters = + new TargetParameters.Builder() + .order( + TargetOrder.fromEventData( + new HashMap() { + { + put(ID, ""); + put(ORDER_TOTAL, ""); + } + })) + .build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); // test - JSONObject json = targetRequestBuilder.getRequestPayload(defaultJson, prefetch, null, null, - null); + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); // verify - assertNull(json.optJSONArray(PREFETCH_MBOXES)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER)); } @Test - public void getRequestPayload_NoPrefetchInJson_When_NullPrefetch() { + public void getRequestPayload_OrderParametersFromMap_OrderNotInJson_When_OrderIdIsNull() { // setup - final JSONObject defaultJson = new JSONObject();; + TargetParameters targetParameters = + new TargetParameters.Builder() + .order( + TargetOrder.fromEventData( + new HashMap() { + { + put(ID, null); + put(ORDER_TOTAL, ""); + } + })) + .build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); // test - JSONObject json = targetRequestBuilder.getRequestPayload(defaultJson, null, null, null, - null); + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); // verify - assertNull(json.optJSONArray(PREFETCH_MBOXES)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER)); } - // =================================== - // Test getRequestPayload_rawExecute - // =================================== @Test - public void getRequestPayload_ExecuteInJson() { + public void getRequestPayload_OrderParametersFromMap_NoOrderInJson_When_OrderTotalIsEmpty() { // setup - final JSONObject defaultJson = new JSONObject();; - final Map executeMbox1 = new HashMap() { - { - put("index", 0); - put("name", "mbox1"); - } - }; - final Map executeMbox2 = new HashMap() { - { - put("index", 1); - put("name", "mbox2"); - } - }; - final List> executeMboxes = new ArrayList<>(); - executeMboxes.add(executeMbox1); - executeMboxes.add(executeMbox2); - - final Map execute = new HashMap() { - { - put("mboxes", executeMboxes); - } - }; + TargetParameters targetParameters = + new TargetParameters.Builder() + .order( + TargetOrder.fromEventData( + new HashMap() { + { + put(ID, "orderId"); + put(ORDER_TOTAL, ""); + } + })) + .build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); // test - JSONObject json = targetRequestBuilder.getRequestPayload(defaultJson, null, execute, null, - null); + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); // verify - assertEquals(2, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals(0, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(INDEX)); - assertEquals("mbox1", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(NAME)); - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(1).opt(INDEX)); - assertEquals("mbox2", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(1).opt(NAME)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER)); } @Test - public void getRequestPayload_NoExecuteInJson_When_RawExecuteMapIsEmpty() { + public void getRequestPayload_OrderParametersFromMap_NoOrderInJson_When_OrderTotalIsNull() { // setup - final JSONObject defaultJson = new JSONObject();; - final Map execute = new HashMap(); + TargetParameters targetParameters = + new TargetParameters.Builder() + .order( + TargetOrder.fromEventData( + new HashMap() { + { + put(ID, "orderId"); + put(ORDER_TOTAL, null); + } + })) + .build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); // test - JSONObject json = targetRequestBuilder.getRequestPayload(defaultJson, null, execute, null, - null); + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); // verify - assertNull(json.optJSONArray(EXECUTE_MBOXES)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER)); } @Test - public void getRequestPayload_NoExecuteInJson_When_NullExecute() { + public void + getRequestPayload_OrderParametersFromMap_NoOrderInJson_When_OrderTotalIsStringDouble() { // setup - final JSONObject defaultJson = new JSONObject();; + TargetParameters targetParameters = + new TargetParameters.Builder() + .order( + TargetOrder.fromEventData( + new HashMap() { + { + put(ID, "orderId"); + put(ORDER_TOTAL, "0.1"); + } + })) + .build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); // test - JSONObject json = targetRequestBuilder.getRequestPayload(defaultJson, null, null, null, - null); + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); // verify - assertNull(json.optJSONArray(EXECUTE_MBOXES)); + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER)); } - // =================================== - // Test getRequestPayload_rawNotification - // =================================== @Test - public void getRequestPayload_NotificationsInJson() { + public void + getRequestPayload_OrderParametersFromMap_NoOrderInJson_When_OrderTotalIsRandomString() { // setup - final JSONObject defaultJson = new JSONObject();; - final Map notification1 = new HashMap() { - { - put("id", "0"); - put("timestamp", (long)(System.currentTimeMillis())); - put("type", "display"); - put("mbox", new HashMap() { - { - put("name", "mbox1"); - } - }); - put("tokens", new ArrayList() { - { - add("displayToken"); - } - }); - } - }; - final Map notification2 = new HashMap() { - { - put("id", "1"); - put("timestamp", (long)(System.currentTimeMillis())); - put("type", "click"); - put("mbox", new HashMap() { - { - put("name", "mbox2"); - } - }); - put("tokens", new ArrayList() { - { - add("clickToken"); - } - }); - } - }; - final List> notifications = new ArrayList>() { - { - add(notification1); - add(notification2); - } - }; + TargetParameters targetParameters = + new TargetParameters.Builder() + .order( + TargetOrder.fromEventData( + new HashMap() { + { + put(ID, "orderId"); + put(ORDER_TOTAL, "total"); + } + })) + .build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); // test - JSONObject json = targetRequestBuilder.getRequestPayload(defaultJson, null, null, notifications, - null); + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); // verify - assertEquals(2, json.optJSONArray(VISITED_MBOXES).length()); - assertEquals("0", json.optJSONArray(VISITED_MBOXES).optJSONObject(0).opt(ID)); - assertEquals("display", json.optJSONArray(VISITED_MBOXES).optJSONObject(0).opt(METRIC_TYPE)); - assertEquals("mbox1", json.optJSONArray(VISITED_MBOXES).optJSONObject(0).optJSONObject(MBOX).opt(NAME)); - assertEquals("displayToken", json.optJSONArray(VISITED_MBOXES).optJSONObject(0).optJSONArray(TOKENS).opt(0)); - assertNotEquals(0L, json.optJSONArray(VISITED_MBOXES).optJSONObject(0).opt(TIMESTAMP)); - assertEquals("1", json.optJSONArray(VISITED_MBOXES).optJSONObject(1).opt(ID)); - assertEquals("click", json.optJSONArray(VISITED_MBOXES).optJSONObject(1).opt(METRIC_TYPE)); - assertEquals("mbox2", json.optJSONArray(VISITED_MBOXES).optJSONObject(1).optJSONObject(MBOX).opt(NAME)); - assertEquals("clickToken", json.optJSONArray(VISITED_MBOXES).optJSONObject(1).optJSONArray(TOKENS).opt(0)); - assertNotEquals(0L, json.optJSONArray(VISITED_MBOXES).optJSONObject(1).opt(TIMESTAMP)); + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER)); } @Test - public void getRequestPayload_NoNotificationsInJson_When_RawNotificationsListIsEmpty() { + public void + getRequestPayload_OrderParametersFromMap_NoOrderInJson_When_PurchasedProductIdsIsEmpty() { // setup - final JSONObject defaultJson = new JSONObject();; - final List> notifications = new ArrayList<>(); + TargetParameters targetParameters = + new TargetParameters.Builder() + .order( + TargetOrder.fromEventData( + new HashMap() { + { + put(ID, "orderId"); + put(ORDER_TOTAL, null); + put( + PURCHASED_PRODUCT_IDS, + new ArrayList() { + { + } + }); + } + })) + .build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); // test - JSONObject json = targetRequestBuilder.getRequestPayload(defaultJson, null, null, notifications, - null); + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); // verify - assertNull(json.optJSONArray(VISITED_MBOXES)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER)); } @Test - public void getRequestPayload_NoNotificationsInJson_When_NullNotifications() { + public void + getRequestPayload_OrderParametersFromMap_NoOrderInJson_When_PurchasedProductIdsOnlyContainsNoneString() { // setup - final JSONObject defaultJson = new JSONObject();; + TargetParameters targetParameters = + new TargetParameters.Builder() + .order( + TargetOrder.fromEventData( + new HashMap() { + { + put(ID, "orderId"); + put(ORDER_TOTAL, null); + put( + PURCHASED_PRODUCT_IDS, + new ArrayList() { + { + add(new Object()); + } + }); + } + })) + .build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); // test - JSONObject json = targetRequestBuilder.getRequestPayload(defaultJson, null, null, null, - null); + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); // verify - assertNull(json.optJSONArray(VISITED_MBOXES)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER)); } // =================================== - // Test getRequestPayload_PropertyToken + // Test getRequestPayload_ProductParameters // =================================== @Test - public void getRequestPayload_PropertyTokenInJson_When_validToken() throws JSONException { + public void getRequestPayload_ProductWhen_ProductParametersIsValid() { // setup - final JSONObject defaultJson = new JSONObject();; + TargetProduct targetProduct = new TargetProduct("productId", "categoryId"); + TargetParameters targetParameters = + new TargetParameters.Builder().product(targetProduct).build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); // test - JSONObject json = targetRequestBuilder.getRequestPayload(defaultJson, null, null, null, - "randomPropertyToken"); + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); // verify - assertNotNull(json.optJSONObject(PROPERTY)); - assertEquals(1, json.optJSONObject(PROPERTY).length()); - assertEquals("randomPropertyToken", json.getJSONObject(PROPERTY).opt(TOKEN)); + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + "productId", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT) + .opt(ID)); + assertEquals( + "categoryId", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT) + .opt(CATEGORY_ID)); } @Test - public void getRequestPayload_NoPropertyTokenInJson_When_nullToken() { + public void getRequestPayload_ProductIdNotInJson_When_ProductIdIsNull() { // setup - final JSONObject defaultJson = new JSONObject();; + TargetProduct targetProduct = new TargetProduct(null, "categoryId"); + TargetParameters targetParameters = + new TargetParameters.Builder().product(targetProduct).build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); // test - JSONObject json = targetRequestBuilder.getRequestPayload(defaultJson, null, null, null, - null); + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); // verify - assertNull(json.optJSONObject(PROPERTY)); + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT)); } @Test - public void getRequestPayload_NoPropertyTokenInJson_When_EmptyToken() { + public void getRequestPayload_ProductIdNotInJson_When_ProductIdIsEmpty() { // setup - final JSONObject defaultJson = new JSONObject();; + TargetProduct targetProduct = new TargetProduct("", "categoryId"); + TargetParameters targetParameters = + new TargetParameters.Builder().product(targetProduct).build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); // test - JSONObject json = targetRequestBuilder.getRequestPayload(defaultJson, null, null, null, - ""); + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); // verify - assertNull(json.optJSONObject(PROPERTY)); + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT)); } @Test - public void getRequestPayload_PropertyTokenNotInJson_When_TokenIsNull() { - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, getTargetRequestList(1), null, - null, null, null, null); - - // verify - assertNull(json.optJSONObject(PROPERTY)); - } + public void getRequestPayload_NoProductInJson_When_ProductCategoryIsEmpty() { + // setup + TargetProduct targetProduct = new TargetProduct("productId", ""); + TargetParameters targetParameters = + new TargetParameters.Builder().product(targetProduct).build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); - @Test - public void getRequestPayload_PropertyTokenNotInJson_When_TokenIsEmpty() { - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, getTargetRequestList(1), null, - null, "", null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); - // verify - assertNull(json.optJSONObject(PROPERTY)); + // verify + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + "productId", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT) + .opt(ID)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT) + .opt(CATEGORY_ID)); } @Test - public void getRequestPayload_PropertyTokenInJson_When_TokenIsNotNull() throws JSONException { - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, getTargetRequestList(1), null, - null, "randomPropertyToken", null, null); + public void getRequestPayload_NoProductInJson_When_ProductCategoryIsNull() { + // setup + TargetProduct targetProduct = new TargetProduct("productId", null); + TargetParameters targetParameters = + new TargetParameters.Builder().product(targetProduct).build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); - // verify - assertNotNull(json.optJSONObject(PROPERTY)); - assertEquals(1, json.optJSONObject(PROPERTY).length()); - assertEquals("randomPropertyToken", json.getJSONObject(PROPERTY).opt(TOKEN)); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + "productId", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT) + .opt(ID)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT) + .opt(CATEGORY_ID)); } - // =================================== - // Test getRequestPayload_MBoxParameters - // =================================== @Test - public void getRequestPayload_MboxWhen_MboxParametersAreValid() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder().parameters(new HashMap() { - { - put("mBox-parameter-Key1", "mBox-Value1"); - put("mBox-parameter-Key2", "mBox-Value2"); - } - }).build(); + public void getRequestPayload_ProductFromMap_When_ProductParameterAreValid() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .product( + TargetProduct.fromEventData( + new HashMap() { + { + put(ID, "productId"); + put(CATEGORY_ID, "categoryId"); + } + })) + .build(); List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); targetRequestList.add(targetRequest); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); - // verify + // verify assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("mBox-Value1", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PARAMETERS).opt("mBox-parameter-Key1")); - assertEquals("mBox-Value2", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PARAMETERS).opt("mBox-parameter-Key2")); + assertEquals( + "productId", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT) + .opt(ID)); + assertEquals( + "categoryId", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT) + .opt(CATEGORY_ID)); } @Test - public void getRequestPayload_Mboxparameter_Key1_NotInJson_When_parameter_Key1_ValueIsNull() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder().parameters(new HashMap() { - { - put("mBox-parameter-Key1", null); - put("mBox-parameter-Key2", "mBox-Value2"); - } - }).build(); - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify + public void getRequestPayload_ProductFromMap_ProductIdNotInJson_When_ProductIdIsNull() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .product( + TargetProduct.fromEventData( + new HashMap() { + { + put(ID, null); + put(CATEGORY_ID, "categoryId"); + } + })) + .build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PARAMETERS).optString("mBox-parameter-Key1", null)); - assertEquals("mBox-Value2", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PARAMETERS).opt("mBox-parameter-Key2")); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT)); } @Test - public void getRequestPayload_Mboxparameter_When_Mboxparameters_Are_Empty() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder().parameters(new HashMap<>()).build(); - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - targetRequestList.add(targetRequest); + public void getRequestPayload_ProductFromMap_ProductIdNotInJson_When_ProductIdIsEmpty() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .product( + TargetProduct.fromEventData( + new HashMap() { + { + put(ID, ""); + put(CATEGORY_ID, "categoryId"); + } + })) + .build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); - // verify + // verify assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PARAMETERS)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT)); } - // =================================== - // Test getRequestPayload_ProfileParameters - // =================================== @Test - public void getRequestPayload_ProfileWhen_ProfileParametersAreValid() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder().profileParameters(new HashMap() { - { - put("profile-parameter-Key1", "profile-Value1"); - put("profile-parameter-Key2", "profile-Value2"); - } - }).build(); - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("profile-Value1", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key1")); - assertEquals("profile-Value2", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key2")); - } - - @Test - public void getRequestPayload_Profileparameter_Key1_NotInJson_When_parameter_Key1_ValueIsNull() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder().profileParameters(new HashMap() { - { - put("profile-parameter-Key1", null); - put("profile-parameter-Key2", "profile-Value2"); - } - }).build(); - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - targetRequestList.add(targetRequest); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify + public void getRequestPayload_ProductFromMap_NoProductInJson_When_ProductCategoryIsEmpty() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .product( + TargetProduct.fromEventData( + new HashMap() { + { + put(ID, "productId"); + put(CATEGORY_ID, ""); + } + })) + .build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PROFILE_PARAMETERS).optString("profile-parameter-Key1", null)); - assertEquals("profile-Value2", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key2")); + assertEquals( + "productId", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT) + .opt(ID)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT) + .opt(CATEGORY_ID)); } @Test - public void getRequestPayload_Profileparameter_When_Profileparameters_are_Empty() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder().profileParameters(new HashMap<>()).build(); - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - targetRequestList.add(targetRequest); + public void getRequestPayload_ProductFromMap_NoProductInJson_When_ProductCategoryIsNull() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .product( + TargetProduct.fromEventData( + new HashMap() { + { + put(ID, "productId"); + put(CATEGORY_ID, null); + } + })) + .build(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + List targetRequestList = new ArrayList<>(); + targetRequestList.add(targetRequest); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); - // verify + // verify assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PROFILE_PARAMETERS)); + assertEquals( + "productId", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT) + .opt(ID)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT) + .opt(CATEGORY_ID)); } // =================================== - // Test getRequestPayload_TargetParameters + // Test getRequestPayload_rawPrefetch // =================================== @Test - public void getRequestPayload_When_TargetParametersAreEmpty() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder().build(); - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - targetRequestList.add(targetRequest); + public void getRequestPayload_PrefetchInJson() { + // setup + final JSONObject defaultJson = new JSONObject(); + ; + final Map prefetchMbox1 = + new HashMap() { + { + put("index", 0); + put("name", "mbox1"); + } + }; + final Map prefetchMbox2 = + new HashMap() { + { + put("index", 1); + put("name", "mbox2"); + } + }; + final List> prefetchMboxes = new ArrayList<>(); + prefetchMboxes.add(prefetchMbox1); + prefetchMboxes.add(prefetchMbox2); + + final Map prefetch = + new HashMap() { + { + put("mboxes", prefetchMboxes); + } + }; - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(defaultJson, prefetch, null, null, null); - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER)); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PRODUCT)); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PROFILE_PARAMETERS)); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PARAMETERS)); + // verify + assertEquals(2, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + 0, + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .opt(INDEX)); + assertEquals( + "mbox1", + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .opt(NAME)); + assertEquals( + 1, + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(1) + .opt(INDEX)); + assertEquals( + "mbox2", + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(1) + .opt(NAME)); } @Test - public void getRequestPayload_When_TargetParametersAreNull() { - // setup - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest = new TargetRequest("mbox", null, "default", callback -> {}); - targetRequestList.add(targetRequest); + public void getRequestPayload_NoPrefetchInJson_When_PrefetchMapIsEmpty() { + // setup + final JSONObject defaultJson = new JSONObject(); + ; + final Map prefetch = new HashMap(); - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(defaultJson, prefetch, null, null, null); - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(ORDER)); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PRODUCT)); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PROFILE_PARAMETERS)); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PARAMETERS)); + // verify + assertNull(json.optJSONArray(PREFETCH_MBOXES)); } - // =================================== - // Test getRequestPayload_PropertyToken - // =================================== @Test - public void getRequestPayload_PropertyWhen_ATPropertyInMboxParameters() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("at_property", "randomPropertyToken"); - } - }) - .profileParameters(new HashMap() { - { - put("profile-parameter-Key1", "profile-Value1"); - } - }).build(); - - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - targetRequestList.add(targetRequest); + public void getRequestPayload_NoPrefetchInJson_When_NullPrefetch() { + // setup + final JSONObject defaultJson = new JSONObject(); + ; - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(defaultJson, null, null, null, null); - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("profile-Value1", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key1")); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PARAMETERS)); - assertNull(json.optJSONObject(TargetJson.PROPERTY)); + // verify + assertNull(json.optJSONArray(PREFETCH_MBOXES)); } + // =================================== + // Test getRequestPayload_rawExecute + // =================================== @Test - public void getRequestPayload_PropertyParametersNotInJson_When_NullATPropertyInMboxParameters() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("at_property", null); - } - }) - .profileParameters(new HashMap() { - { - put("profile-parameter-Key1", "profile-Value1"); - } - }).build(); + public void getRequestPayload_ExecuteInJson() { + // setup + final JSONObject defaultJson = new JSONObject(); + ; + final Map executeMbox1 = + new HashMap() { + { + put("index", 0); + put("name", "mbox1"); + } + }; + final Map executeMbox2 = + new HashMap() { + { + put("index", 1); + put("name", "mbox2"); + } + }; + final List> executeMboxes = new ArrayList<>(); + executeMboxes.add(executeMbox1); + executeMboxes.add(executeMbox2); - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - targetRequestList.add(targetRequest); + final Map execute = + new HashMap() { + { + put("mboxes", executeMboxes); + } + }; - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(defaultJson, null, execute, null, null); - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("profile-Value1", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key1")); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PARAMETERS)); - assertNull(json.optJSONObject(TargetJson.PROPERTY)); + // verify + assertEquals(2, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + 0, + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .opt(INDEX)); + assertEquals( + "mbox1", + json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).opt(NAME)); + assertEquals( + 1, + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(1) + .opt(INDEX)); + assertEquals( + "mbox2", + json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(1).opt(NAME)); } @Test - public void getRequestPayload_ForMultipleMboxes_PropertyWhen_ATPropertyInMboxParameters() { - // setup - TargetParameters targetParameters1 = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("at_property", "randomPropertyToken"); - } - }) - .profileParameters(new HashMap() { - { - put("profile-parameter-Key1", "profile-Value1"); - } - }).build(); - - TargetParameters targetParameters2 = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("at_property", "randomPropertyToken2"); - } - }) - .profileParameters(new HashMap() { - { - put("profile-parameter-Key2", "profile-Value2"); - } - }).build(); - - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest1 = new TargetRequest("mbox1", targetParameters1, "default", callback -> {}); - TargetRequest targetRequest2 = new TargetRequest("mbox2", targetParameters2, "default", callback -> {}); - targetRequestList.add(targetRequest1); - targetRequestList.add(targetRequest2); - - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); + public void getRequestPayload_NoExecuteInJson_When_RawExecuteMapIsEmpty() { + // setup + final JSONObject defaultJson = new JSONObject(); + ; + final Map execute = new HashMap(); - assertNull(json.optJSONObject(TargetJson.PROPERTY)); - JSONArray mboxesArray = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES); - assertEquals(2, mboxesArray.length()); - JSONObject mbox1 = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0); - assertEquals("profile-Value1", mbox1.optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key1")); - assertNull(mbox1.optJSONObject(PARAMETERS)); - JSONObject mbox2 = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(1); - assertEquals("profile-Value2", mbox2.optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key2")); - assertNull(mbox2.optJSONObject(PARAMETERS)); - } + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(defaultJson, null, execute, null, null); - @Test - public void getRequestPayload_ForMultipleMboxes_PropertyParametersNotInJson_When_NullATPropertyInMboxParameters() { - // setup - TargetParameters targetParameters1 = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("at_property", null); - } - }) - .profileParameters(new HashMap() { - { - put("profile-parameter-Key1", "profile-Value1"); - } - }).build(); - - TargetParameters targetParameters2 = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("at_property", null); - } - }) - .profileParameters(new HashMap() { - { - put("profile-parameter-Key2", "profile-Value2"); - } - }).build(); - - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest1 = new TargetRequest("mbox1", targetParameters1, "default", callback -> {}); - TargetRequest targetRequest2 = new TargetRequest("mbox2", targetParameters2, "default", callback -> {}); - targetRequestList.add(targetRequest1); - targetRequestList.add(targetRequest2); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertNull(json.optJSONObject(TargetJson.PROPERTY)); - JSONArray mboxesArray = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES); - assertEquals(2, mboxesArray.length()); - JSONObject mbox1 = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0); - assertEquals("profile-Value1", mbox1.optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key1")); - assertNull(mbox1.optJSONObject(PARAMETERS)); - JSONObject mbox2 = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(1); - assertEquals("profile-Value2", mbox2.optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key2")); - assertNull(mbox2.optJSONObject(PARAMETERS)); + // verify + assertNull(json.optJSONArray(EXECUTE_MBOXES)); } @Test - public void - getRequestPayload_ForMultipleMboxes_SecondMboxPropertyWhen_NullATPropertyInFirstMboxParameters() { - // setup - TargetParameters targetParameters1 = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("at_property", null); - } - }) - .profileParameters(new HashMap() { - { - put("profile-parameter-Key1", "profile-Value1"); - } - }).build(); - - TargetParameters targetParameters2 = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("at_property", "randomPropertyToken2"); - } - }) - .profileParameters(new HashMap() { - { - put("profile-parameter-Key2", "profile-Value2"); - } - }).build(); - - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest1 = new TargetRequest("mbox1", targetParameters1, "default", callback -> {}); - TargetRequest targetRequest2 = new TargetRequest("mbox2", targetParameters2, "default", callback -> {}); - targetRequestList.add(targetRequest1); - targetRequestList.add(targetRequest2); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - null, null, null); - - // verify - assertNull(json.optJSONObject(TargetJson.PROPERTY)); - JSONArray mboxesArray = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES); - assertEquals(2, mboxesArray.length()); - JSONObject mbox1 = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0); - assertEquals("profile-Value1", mbox1.optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key1")); - assertNull(mbox1.optJSONObject(PARAMETERS)); - JSONObject mbox2 = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(1); - assertEquals("profile-Value2", mbox2.optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key2")); - assertNull(mbox2.optJSONObject(PARAMETERS)); + public void getRequestPayload_NoExecuteInJson_When_NullExecute() { + // setup + final JSONObject defaultJson = new JSONObject(); + ; + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(defaultJson, null, null, null, null); + + // verify + assertNull(json.optJSONArray(EXECUTE_MBOXES)); } + // =================================== + // Test getRequestPayload_rawNotification + // =================================== @Test - public void getRequestPayload_PropertyWhen_ATPropertyInMboxParametersOverriddenByGlobalProperty() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("at_property", "randomPropertyToken"); - } - }) - .profileParameters(new HashMap() { - { - put("profile-parameter-Key1", "profile-Value1"); - } - }).build(); - - List targetRequestList = new ArrayList<>(); - TargetRequest targetRequest = new TargetRequest("mbox", targetParameters, "default", callback -> {}); - targetRequestList.add(targetRequest); + public void getRequestPayload_NotificationsInJson() { + // setup + final JSONObject defaultJson = new JSONObject(); + ; + final Map notification1 = + new HashMap() { + { + put("id", "0"); + put("timestamp", (long) (System.currentTimeMillis())); + put("type", "display"); + put( + "mbox", + new HashMap() { + { + put("name", "mbox1"); + } + }); + put( + "tokens", + new ArrayList() { + { + add("displayToken"); + } + }); + } + }; + final Map notification2 = + new HashMap() { + { + put("id", "1"); + put("timestamp", (long) (System.currentTimeMillis())); + put("type", "click"); + put( + "mbox", + new HashMap() { + { + put("name", "mbox2"); + } + }); + put( + "tokens", + new ArrayList() { + { + add("clickToken"); + } + }); + } + }; + final List> notifications = + new ArrayList>() { + { + add(notification1); + add(notification2); + } + }; - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, targetRequestList, null, null, - "GlobalPropertyToken", null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + defaultJson, null, null, notifications, null); - // verify - assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("profile-Value1", json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key1")); - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PARAMETERS)); - assertEquals(1, json.optJSONObject(TargetJson.PROPERTY).length()); - assertEquals("GlobalPropertyToken", json.optJSONObject(TargetJson.PROPERTY).optString(TargetJson.TOKEN, "")); + // verify + assertEquals(2, json.optJSONArray(VISITED_MBOXES).length()); + assertEquals("0", json.optJSONArray(VISITED_MBOXES).optJSONObject(0).opt(ID)); + assertEquals( + "display", json.optJSONArray(VISITED_MBOXES).optJSONObject(0).opt(METRIC_TYPE)); + assertEquals( + "mbox1", + json.optJSONArray(VISITED_MBOXES).optJSONObject(0).optJSONObject(MBOX).opt(NAME)); + assertEquals( + "displayToken", + json.optJSONArray(VISITED_MBOXES).optJSONObject(0).optJSONArray(TOKENS).opt(0)); + assertNotEquals(0L, json.optJSONArray(VISITED_MBOXES).optJSONObject(0).opt(TIMESTAMP)); + assertEquals("1", json.optJSONArray(VISITED_MBOXES).optJSONObject(1).opt(ID)); + assertEquals("click", json.optJSONArray(VISITED_MBOXES).optJSONObject(1).opt(METRIC_TYPE)); + assertEquals( + "mbox2", + json.optJSONArray(VISITED_MBOXES).optJSONObject(1).optJSONObject(MBOX).opt(NAME)); + assertEquals( + "clickToken", + json.optJSONArray(VISITED_MBOXES).optJSONObject(1).optJSONArray(TOKENS).opt(0)); + assertNotEquals(0L, json.optJSONArray(VISITED_MBOXES).optJSONObject(1).opt(TIMESTAMP)); } @Test - public void getRequestPayloadWithPrefetchRequests_PropertyWhen_ATPropertyInMboxParameters() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("at_property", "randomPropertyToken"); - } - }) - .profileParameters(new HashMap() { - { - put("profile-parameter-Key1", "profile-Value1"); - } - }).build(); - - List targetPrefetchList = new ArrayList(); - TargetPrefetch targetRequest = new TargetPrefetch("mbox", targetParameters); - targetPrefetchList.add(targetRequest); - - // setup - JSONObject json = targetRequestBuilder.getRequestPayload(targetPrefetchList, null, null, null, - null, null, null); - - // verify - assertEquals(1, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("profile-Value1", json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key1")); - assertNull(json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PARAMETERS)); - assertNull(json.optJSONObject(TargetJson.PROPERTY)); + public void getRequestPayload_NoNotificationsInJson_When_RawNotificationsListIsEmpty() { + // setup + final JSONObject defaultJson = new JSONObject(); + ; + final List> notifications = new ArrayList<>(); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + defaultJson, null, null, notifications, null); + + // verify + assertNull(json.optJSONArray(VISITED_MBOXES)); } @Test - public void - getRequestPayloadWithPrefetchRequests_PropertyWhen_ATPropertyInMboxParametersOverriddenByGlobalProperty() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("at_property", "randomPropertyToken"); - } - }) - .profileParameters(new HashMap() { - { - put("profile-parameter-Key1", "profile-Value1"); - } - }).build(); - - List targetPrefetchList = new ArrayList(); - TargetPrefetch targetRequest = new TargetPrefetch("mbox", targetParameters); - targetPrefetchList.add(targetRequest); - - // setup - JSONObject json = targetRequestBuilder.getRequestPayload(targetPrefetchList, null, null, null, - "GlobalPropertyToken", null, null); - - // verify - assertEquals(1, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("profile-Value1", json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key1")); - assertNull(json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PARAMETERS)); - assertEquals(1, json.optJSONObject(TargetJson.PROPERTY).length()); - assertEquals("GlobalPropertyToken", json.optJSONObject(TargetJson.PROPERTY).optString(TargetJson.TOKEN, "")); + public void getRequestPayload_NoNotificationsInJson_When_NullNotifications() { + // setup + final JSONObject defaultJson = new JSONObject(); + ; + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(defaultJson, null, null, null, null); + + // verify + assertNull(json.optJSONArray(VISITED_MBOXES)); } + // =================================== + // Test getRequestPayload_PropertyToken + // =================================== @Test - public void getRequestPayloadWithPrefetchRequests_PropertyParametersNotInJson_When_NullATPropertyInMboxParameters() { - // setup - TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("at_property", null); - } - }) - .profileParameters(new HashMap() { - { - put("profile-parameter-Key1", "profile-Value1"); - } - }).build(); - - List targetPrefetchList = new ArrayList(); - TargetPrefetch targetRequest = new TargetPrefetch("mbox", targetParameters); - targetPrefetchList.add(targetRequest); + public void getRequestPayload_PropertyTokenInJson_When_validToken() throws JSONException { + // setup + final JSONObject defaultJson = new JSONObject(); + ; - // setup - JSONObject json = targetRequestBuilder.getRequestPayload(targetPrefetchList, null, null, null, - null, null, null); + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + defaultJson, null, null, null, "randomPropertyToken"); - // verify - assertEquals(1, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).length()); - assertEquals("profile-Value1", json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PROFILE_PARAMETERS).opt("profile-parameter-Key1")); - assertNull(json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PARAMETERS)); - assertNull(json.optJSONObject(TargetJson.PROPERTY)); + // verify + assertNotNull(json.optJSONObject(PROPERTY)); + assertEquals(1, json.optJSONObject(PROPERTY).length()); + assertEquals("randomPropertyToken", json.getJSONObject(PROPERTY).opt(TOKEN)); } + @Test + public void getRequestPayload_NoPropertyTokenInJson_When_nullToken() { + // setup + final JSONObject defaultJson = new JSONObject(); + ; + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload(defaultJson, null, null, null, null); - // =================================== - // Test getRequestPayload_IdentityData - // =================================== - @Test - public void getRequestPayload_MidNotInJson_When_MidIsEmptyOrNull() { - // setup - Map identitySharedState = getIdentitySharedState("", "", "", null); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null, null, null, identitySharedState, null); - - // test - assertNull(json.optJSONObject(ID)); + // verify + assertNull(json.optJSONObject(PROPERTY)); + } - // setup - Map identitySharedState2 = getIdentitySharedState(null, "", "", null); + @Test + public void getRequestPayload_NoPropertyTokenInJson_When_EmptyToken() { + // setup + final JSONObject defaultJson = new JSONObject(); + ; - // test - JSONObject json2 = targetRequestBuilder.getRequestPayload(null, null, null, null, null, identitySharedState2, null); + // test + JSONObject json = targetRequestBuilder.getRequestPayload(defaultJson, null, null, null, ""); - // test - assertNull(json2.optJSONObject(ID)); - } + // verify + assertNull(json.optJSONObject(PROPERTY)); + } - @Test - public void getRequestPayload_MidInJson_When_MidIsValid() throws JSONException { - // setup - Map identitySharedState = getIdentitySharedState("mid", "", "", null); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null,null, null, identitySharedState, null); - - // test - assertEquals(json.getJSONObject(ID).getString(MARKETING_CLOUD_ID), "mid"); - } - - @Test - public void getRequestPayload_BlobNotInJson_When_BlobIsEmptyOrNull() throws JSONException { - // setup - Map identitySharedState = getIdentitySharedState("", "", "", null); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null,null, null, identitySharedState, null); - - // test - assertNull(json.optJSONObject(EXPERIENCE_CLOUD).optJSONObject(AAM_PARAMETERS)); - - // setup - Map identitySharedState2 = getIdentitySharedState("", null, "", null); - - // test - JSONObject json2 = targetRequestBuilder.getRequestPayload(null, null, null, null,null, identitySharedState2, null); - - // test - assertNull(json2.optJSONObject(EXPERIENCE_CLOUD).optJSONObject(AAM_PARAMETERS)); - } - - @Test - public void getRequestPayload_BlobInJson_When_BlobIsValid() throws JSONException { - // setup - Map identitySharedState = getIdentitySharedState("", "blob", "", null); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null, null,null, identitySharedState, null); - - // test - assertEquals(json.optJSONObject(EXPERIENCE_CLOUD).optJSONObject(AAM_PARAMETERS).getString(BLOB), "blob"); - } - - @Test - public void getRequestPayload_LocationHintInJson_When_LocationHintIsValid() throws JSONException { - // setup - Map identitySharedState = getIdentitySharedState("", "", "LocationHint", null); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null, null,null, identitySharedState, null); - - // test - assertEquals(json.optJSONObject(EXPERIENCE_CLOUD).optJSONObject(AAM_PARAMETERS).getString(LOCATION_HINT), - "LocationHint"); - } - - @Test - public void getRequestPayload_LocationHintNotInJson_When_LocationHintIsEmptyOrNull() throws JSONException { - // setup - Map identitySharedState = getIdentitySharedState("", "", "", null); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null,null, null, identitySharedState, null); - - // test - assertNull(json.optJSONObject(EXPERIENCE_CLOUD).optJSONObject(AAM_PARAMETERS)); - - // setup - Map identitySharedState2 = getIdentitySharedState("", null, "", null); - - // test - JSONObject json2 = targetRequestBuilder.getRequestPayload(null, null, null, null,null, identitySharedState2, null); - - // test - assertNull(json2.optJSONObject(EXPERIENCE_CLOUD).optJSONObject(AAM_PARAMETERS)); - } - - @Test - public void getRequestPayload_CustomerIdsInJson_When_CustomerIdsIsValid() throws JSONException { - // setup - final Map customVisitorID = new HashMap(){{ - put(VISITOR_IDS_ID, "someID"); - put(VISITOR_IDS_ID_TYPE, "someType" ); - put(VISITOR_IDS_ID_ORIGIN, "someOrigin" ); - put(VISITOR_IDS_STATE, VisitorID.AuthenticationState.AUTHENTICATED.getValue()); - }}; - final Map identitySharedState = getIdentitySharedState("", "", "", Arrays.asList(customVisitorID)); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null,null, null, identitySharedState, null); - - // test - assertEquals(json.optJSONObject(ID).optJSONArray(CUSTOMER_IDS).getJSONObject(0).get(AUTHENTICATION_STATE), - "authenticated"); - } - - @Test - public void getRequestPayload_CustomerIdsInJson_OnlyPicks_ValidCustomerIDs() throws JSONException { - // setup - final Map customVisitorID1 = new HashMap(){{ - put(VISITOR_IDS_ID, "someID1"); - put(VISITOR_IDS_ID_TYPE, "someType1" ); - put(VISITOR_IDS_ID_ORIGIN, "someOrigin1" ); - put(VISITOR_IDS_STATE, VisitorID.AuthenticationState.LOGGED_OUT.getValue()); - }}; - - // without ID - final Map customVisitorID2 = new HashMap(){{ - put(VISITOR_IDS_ID_TYPE, "someType2" ); - put(VISITOR_IDS_ID_ORIGIN, "someOrigin2" ); - put(VISITOR_IDS_STATE, VisitorID.AuthenticationState.AUTHENTICATED.getValue()); - }}; - - // without integrationCode (type) - final Map customVisitorID3 = new HashMap(){{ - put(VISITOR_IDS_ID, "someID2"); - put(VISITOR_IDS_ID_ORIGIN, "someOrigin2" ); - put(VISITOR_IDS_STATE, VisitorID.AuthenticationState.AUTHENTICATED.getValue()); - }}; - - // nonString integrationCode value - final Map customVisitorID4 = new HashMap(){{ - put(VISITOR_IDS_ID, 34); - put(VISITOR_IDS_ID_TYPE, "someType2" ); - put(VISITOR_IDS_ID_ORIGIN, "someOrigin2" ); - put(VISITOR_IDS_STATE, VisitorID.AuthenticationState.LOGGED_OUT.getValue()); - }}; - Map identitySharedState = getIdentitySharedState("", "", "", Arrays.asList(customVisitorID1, customVisitorID2, customVisitorID3, customVisitorID4)); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null,null, null, identitySharedState, null); - - // verify - JSONArray gatheredIds = json.optJSONObject(ID).optJSONArray(CUSTOMER_IDS); - assertEquals("Length of customerIDs is correct", 1,gatheredIds.length()); - JSONObject gatheredVisitorID = gatheredIds.getJSONObject(0); - assertEquals("Correct CustomerID id is set", gatheredVisitorID.get(CUSTOMER_ID_ID), "someID1"); - assertEquals("Correct CustomerID IntegrationCode is set", gatheredVisitorID.get(CUSTOMER_ID_INTEGRATION_CODE), "someType1"); - assertEquals("Correct CustomerID authentication state is set", gatheredVisitorID.get(CUSTOMER_ID_AUTHENTICATION_STATE), "logged_out"); - } - - - @Test - public void getRequestPayload_CustomerIdsInJson_When_CustomerIdsIsValid_AndLoggedOut() throws JSONException { - // setup - final Map customVisitorID = new HashMap(){{ - put(VISITOR_IDS_ID, "someID"); - put(VISITOR_IDS_ID_TYPE, "someType" ); - put(VISITOR_IDS_ID_ORIGIN, "someOrigin" ); - put(VISITOR_IDS_STATE, VisitorID.AuthenticationState.LOGGED_OUT.getValue()); - }}; - Map identitySharedState = getIdentitySharedState("", "", "", Arrays.asList(customVisitorID)); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null,null, null, identitySharedState, null); - - // test - assertEquals(json.optJSONObject(ID).optJSONArray(CUSTOMER_IDS).getJSONObject(0).get(AUTHENTICATION_STATE), - "logged_out"); - } - - - @Test - public void getRequestPayload_CustomerIdsInJson_When_CustomerIdsIsValid_AndUnknown() throws JSONException { - // setup - final Map customVisitorID = new HashMap(){{ - put(VISITOR_IDS_ID, "someID"); - put(VISITOR_IDS_ID_TYPE, "someType" ); - put(VISITOR_IDS_ID_ORIGIN, "someOrigin" ); - put(VISITOR_IDS_STATE, 5); - }}; - - List testVisitorIDList = new ArrayList<>(); - testVisitorIDList.add(new VisitorID("d_cid_ic", "id1", "hodor", - VisitorID.AuthenticationState.UNKNOWN)); - Map identitySharedState = getIdentitySharedState("", "", "", Arrays.asList(customVisitorID)); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null,null, null, identitySharedState, null); - - // test - assertEquals(json.optJSONObject(ID).optJSONArray(CUSTOMER_IDS).getJSONObject(0).get(AUTHENTICATION_STATE), - "unknown"); - } - - @Test - public void getRequestPayload_CustomerIdsNotInJson_When_CustomerIdsIsEmptyOrNull() throws JSONException { - // setup - Map identitySharedState = getIdentitySharedState("", "", "", new ArrayList<>()); - - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, null, null,null, null, identitySharedState, null); - - // test - assertNull(json.optJSONObject(ID)); - - // setup - Map identitySharedState2 = getIdentitySharedState("", null, "", null); - - // test - JSONObject json2 = targetRequestBuilder.getRequestPayload(null, null, null, null,null, identitySharedState2, null); - - // test - assertNull(json.optJSONObject(ID)); - } - - - // =================================== - // Test getRequestPayload_LifecycleData - // =================================== @Test - public void getRequestPayload_LifecycleDataNotInJson_When_LifecycleIsEmptyOrNull() { - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, getTargetRequestList(1), null, - null, null, null, null); + public void getRequestPayload_PropertyTokenNotInJson_When_TokenIsNull() { + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, getTargetRequestList(1), null, null, null, null, null); - // verify - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PARAMETERS)); + // verify + assertNull(json.optJSONObject(PROPERTY)); + } - // test - json = targetRequestBuilder.getRequestPayload(null, getTargetRequestList(1), null, - null, null, null, new HashMap<>()); + @Test + public void getRequestPayload_PropertyTokenNotInJson_When_TokenIsEmpty() { + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, getTargetRequestList(1), null, null, "", null, null); - // verify - assertNull(json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject(PARAMETERS)); + // verify + assertNull(json.optJSONObject(PROPERTY)); + } + @Test + public void getRequestPayload_PropertyTokenInJson_When_TokenIsNotNull() throws JSONException { + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, + getTargetRequestList(1), + null, + null, + "randomPropertyToken", + null, + null); + // verify + assertNotNull(json.optJSONObject(PROPERTY)); + assertEquals(1, json.optJSONObject(PROPERTY).length()); + assertEquals("randomPropertyToken", json.getJSONObject(PROPERTY).opt(TOKEN)); + } + + // =================================== + // Test getRequestPayload_MBoxParameters + // =================================== + @Test + public void getRequestPayload_MboxWhen_MboxParametersAreValid() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mBox-parameter-Key1", "mBox-Value1"); + put("mBox-parameter-Key2", "mBox-Value2"); + } + }) + .build(); + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + targetRequestList.add(targetRequest); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + "mBox-Value1", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS) + .opt("mBox-parameter-Key1")); + assertEquals( + "mBox-Value2", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS) + .opt("mBox-parameter-Key2")); + } + + @Test + public void getRequestPayload_Mboxparameter_Key1_NotInJson_When_parameter_Key1_ValueIsNull() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mBox-parameter-Key1", null); + put("mBox-parameter-Key2", "mBox-Value2"); + } + }) + .build(); + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + targetRequestList.add(targetRequest); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS) + .optString("mBox-parameter-Key1", null)); + assertEquals( + "mBox-Value2", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS) + .opt("mBox-parameter-Key2")); + } + + @Test + public void getRequestPayload_Mboxparameter_When_Mboxparameters_Are_Empty() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder().parameters(new HashMap<>()).build(); + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + targetRequestList.add(targetRequest); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS)); + } + + // =================================== + // Test getRequestPayload_ProfileParameters + // =================================== + @Test + public void getRequestPayload_ProfileWhen_ProfileParametersAreValid() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key1", "profile-Value1"); + put("profile-parameter-Key2", "profile-Value2"); + } + }) + .build(); + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + targetRequestList.add(targetRequest); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + "profile-Value1", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PROFILE_PARAMETERS) + .opt("profile-parameter-Key1")); + assertEquals( + "profile-Value2", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PROFILE_PARAMETERS) + .opt("profile-parameter-Key2")); + } + + @Test + public void + getRequestPayload_Profileparameter_Key1_NotInJson_When_parameter_Key1_ValueIsNull() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key1", null); + put("profile-parameter-Key2", "profile-Value2"); + } + }) + .build(); + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + targetRequestList.add(targetRequest); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PROFILE_PARAMETERS) + .optString("profile-parameter-Key1", null)); + assertEquals( + "profile-Value2", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PROFILE_PARAMETERS) + .opt("profile-parameter-Key2")); + } + + @Test + public void getRequestPayload_Profileparameter_When_Profileparameters_are_Empty() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder().profileParameters(new HashMap<>()).build(); + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + targetRequestList.add(targetRequest); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PROFILE_PARAMETERS)); + } + + // =================================== + // Test getRequestPayload_TargetParameters + // =================================== + @Test + public void getRequestPayload_When_TargetParametersAreEmpty() { + // setup + TargetParameters targetParameters = new TargetParameters.Builder().build(); + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + targetRequestList.add(targetRequest); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PROFILE_PARAMETERS)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS)); + } + + @Test + public void getRequestPayload_When_TargetParametersAreNull() { + // setup + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest = new TargetRequest("mbox", null, "default", callback -> {}); + targetRequestList.add(targetRequest); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(ORDER)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PRODUCT)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PROFILE_PARAMETERS)); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS)); + } + + // =================================== + // Test getRequestPayload_PropertyToken + // =================================== + @Test + public void getRequestPayload_PropertyWhen_ATPropertyInMboxParameters() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("at_property", "randomPropertyToken"); + } + }) + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key1", "profile-Value1"); + } + }) + .build(); + + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + targetRequestList.add(targetRequest); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + "profile-Value1", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PROFILE_PARAMETERS) + .opt("profile-parameter-Key1")); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS)); + assertNull(json.optJSONObject(TargetJson.PROPERTY)); + } + + @Test + public void + getRequestPayload_PropertyParametersNotInJson_When_NullATPropertyInMboxParameters() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("at_property", null); + } + }) + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key1", "profile-Value1"); + } + }) + .build(); + + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + targetRequestList.add(targetRequest); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + "profile-Value1", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PROFILE_PARAMETERS) + .opt("profile-parameter-Key1")); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS)); + assertNull(json.optJSONObject(TargetJson.PROPERTY)); + } + + @Test + public void getRequestPayload_ForMultipleMboxes_PropertyWhen_ATPropertyInMboxParameters() { + // setup + TargetParameters targetParameters1 = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("at_property", "randomPropertyToken"); + } + }) + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key1", "profile-Value1"); + } + }) + .build(); + + TargetParameters targetParameters2 = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("at_property", "randomPropertyToken2"); + } + }) + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key2", "profile-Value2"); + } + }) + .build(); + + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest1 = + new TargetRequest("mbox1", targetParameters1, "default", callback -> {}); + TargetRequest targetRequest2 = + new TargetRequest("mbox2", targetParameters2, "default", callback -> {}); + targetRequestList.add(targetRequest1); + targetRequestList.add(targetRequest2); + + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + assertNull(json.optJSONObject(TargetJson.PROPERTY)); + JSONArray mboxesArray = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES); + assertEquals(2, mboxesArray.length()); + JSONObject mbox1 = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0); + assertEquals( + "profile-Value1", + mbox1.optJSONObject(PROFILE_PARAMETERS).opt("profile-parameter-Key1")); + assertNull(mbox1.optJSONObject(PARAMETERS)); + JSONObject mbox2 = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(1); + assertEquals( + "profile-Value2", + mbox2.optJSONObject(PROFILE_PARAMETERS).opt("profile-parameter-Key2")); + assertNull(mbox2.optJSONObject(PARAMETERS)); + } + + @Test + public void + getRequestPayload_ForMultipleMboxes_PropertyParametersNotInJson_When_NullATPropertyInMboxParameters() { + // setup + TargetParameters targetParameters1 = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("at_property", null); + } + }) + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key1", "profile-Value1"); + } + }) + .build(); + + TargetParameters targetParameters2 = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("at_property", null); + } + }) + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key2", "profile-Value2"); + } + }) + .build(); + + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest1 = + new TargetRequest("mbox1", targetParameters1, "default", callback -> {}); + TargetRequest targetRequest2 = + new TargetRequest("mbox2", targetParameters2, "default", callback -> {}); + targetRequestList.add(targetRequest1); + targetRequestList.add(targetRequest2); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertNull(json.optJSONObject(TargetJson.PROPERTY)); + JSONArray mboxesArray = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES); + assertEquals(2, mboxesArray.length()); + JSONObject mbox1 = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0); + assertEquals( + "profile-Value1", + mbox1.optJSONObject(PROFILE_PARAMETERS).opt("profile-parameter-Key1")); + assertNull(mbox1.optJSONObject(PARAMETERS)); + JSONObject mbox2 = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(1); + assertEquals( + "profile-Value2", + mbox2.optJSONObject(PROFILE_PARAMETERS).opt("profile-parameter-Key2")); + assertNull(mbox2.optJSONObject(PARAMETERS)); + } + + @Test + public void + getRequestPayload_ForMultipleMboxes_SecondMboxPropertyWhen_NullATPropertyInFirstMboxParameters() { + // setup + TargetParameters targetParameters1 = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("at_property", null); + } + }) + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key1", "profile-Value1"); + } + }) + .build(); + + TargetParameters targetParameters2 = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("at_property", "randomPropertyToken2"); + } + }) + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key2", "profile-Value2"); + } + }) + .build(); + + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest1 = + new TargetRequest("mbox1", targetParameters1, "default", callback -> {}); + TargetRequest targetRequest2 = + new TargetRequest("mbox2", targetParameters2, "default", callback -> {}); + targetRequestList.add(targetRequest1); + targetRequestList.add(targetRequest2); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, null, null, null); + + // verify + assertNull(json.optJSONObject(TargetJson.PROPERTY)); + JSONArray mboxesArray = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES); + assertEquals(2, mboxesArray.length()); + JSONObject mbox1 = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0); + assertEquals( + "profile-Value1", + mbox1.optJSONObject(PROFILE_PARAMETERS).opt("profile-parameter-Key1")); + assertNull(mbox1.optJSONObject(PARAMETERS)); + JSONObject mbox2 = json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(1); + assertEquals( + "profile-Value2", + mbox2.optJSONObject(PROFILE_PARAMETERS).opt("profile-parameter-Key2")); + assertNull(mbox2.optJSONObject(PARAMETERS)); + } + + @Test + public void + getRequestPayload_PropertyWhen_ATPropertyInMboxParametersOverriddenByGlobalProperty() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("at_property", "randomPropertyToken"); + } + }) + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key1", "profile-Value1"); + } + }) + .build(); + + List targetRequestList = new ArrayList<>(); + TargetRequest targetRequest = + new TargetRequest("mbox", targetParameters, "default", callback -> {}); + targetRequestList.add(targetRequest); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, targetRequestList, null, null, "GlobalPropertyToken", null, null); + + // verify + assertEquals(1, json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + "profile-Value1", + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PROFILE_PARAMETERS) + .opt("profile-parameter-Key1")); + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS)); + assertEquals(1, json.optJSONObject(TargetJson.PROPERTY).length()); + assertEquals( + "GlobalPropertyToken", + json.optJSONObject(TargetJson.PROPERTY).optString(TargetJson.TOKEN, "")); + } + + @Test + public void getRequestPayloadWithPrefetchRequests_PropertyWhen_ATPropertyInMboxParameters() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("at_property", "randomPropertyToken"); + } + }) + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key1", "profile-Value1"); + } + }) + .build(); + + List targetPrefetchList = new ArrayList(); + TargetPrefetch targetRequest = new TargetPrefetch("mbox", targetParameters); + targetPrefetchList.add(targetRequest); + + // setup + JSONObject json = + targetRequestBuilder.getRequestPayload( + targetPrefetchList, null, null, null, null, null, null); + + // verify + assertEquals(1, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + "profile-Value1", + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PROFILE_PARAMETERS) + .opt("profile-parameter-Key1")); + assertNull( + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS)); + assertNull(json.optJSONObject(TargetJson.PROPERTY)); + } + + @Test + public void + getRequestPayloadWithPrefetchRequests_PropertyWhen_ATPropertyInMboxParametersOverriddenByGlobalProperty() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("at_property", "randomPropertyToken"); + } + }) + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key1", "profile-Value1"); + } + }) + .build(); + + List targetPrefetchList = new ArrayList(); + TargetPrefetch targetRequest = new TargetPrefetch("mbox", targetParameters); + targetPrefetchList.add(targetRequest); + + // setup + JSONObject json = + targetRequestBuilder.getRequestPayload( + targetPrefetchList, null, null, null, "GlobalPropertyToken", null, null); + + // verify + assertEquals(1, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + "profile-Value1", + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PROFILE_PARAMETERS) + .opt("profile-parameter-Key1")); + assertNull( + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS)); + assertEquals(1, json.optJSONObject(TargetJson.PROPERTY).length()); + assertEquals( + "GlobalPropertyToken", + json.optJSONObject(TargetJson.PROPERTY).optString(TargetJson.TOKEN, "")); + } + + @Test + public void + getRequestPayloadWithPrefetchRequests_PropertyParametersNotInJson_When_NullATPropertyInMboxParameters() { + // setup + TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("at_property", null); + } + }) + .profileParameters( + new HashMap() { + { + put("profile-parameter-Key1", "profile-Value1"); + } + }) + .build(); + + List targetPrefetchList = new ArrayList(); + TargetPrefetch targetRequest = new TargetPrefetch("mbox", targetParameters); + targetPrefetchList.add(targetRequest); + + // setup + JSONObject json = + targetRequestBuilder.getRequestPayload( + targetPrefetchList, null, null, null, null, null, null); + + // verify + assertEquals(1, json.optJSONObject(PREFETCH_MBOXES).optJSONArray(MBOXES).length()); + assertEquals( + "profile-Value1", + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PROFILE_PARAMETERS) + .opt("profile-parameter-Key1")); + assertNull( + json.optJSONObject(PREFETCH_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS)); + assertNull(json.optJSONObject(TargetJson.PROPERTY)); + } + + // =================================== + // Test getRequestPayload_IdentityData + // =================================== + @Test + public void getRequestPayload_MidNotInJson_When_MidIsEmptyOrNull() { + // setup + Map identitySharedState = getIdentitySharedState("", "", "", null); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState, null); + + // test + assertNull(json.optJSONObject(ID)); + + // setup + Map identitySharedState2 = getIdentitySharedState(null, "", "", null); + + // test + JSONObject json2 = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState2, null); + + // test + assertNull(json2.optJSONObject(ID)); + } + + @Test + public void getRequestPayload_MidInJson_When_MidIsValid() throws JSONException { + // setup + Map identitySharedState = getIdentitySharedState("mid", "", "", null); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState, null); + + // test + assertEquals(json.getJSONObject(ID).getString(MARKETING_CLOUD_ID), "mid"); + } + + @Test + public void getRequestPayload_BlobNotInJson_When_BlobIsEmptyOrNull() throws JSONException { + // setup + Map identitySharedState = getIdentitySharedState("", "", "", null); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState, null); + + // test + assertNull(json.optJSONObject(EXPERIENCE_CLOUD).optJSONObject(AAM_PARAMETERS)); + + // setup + Map identitySharedState2 = getIdentitySharedState("", null, "", null); + + // test + JSONObject json2 = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState2, null); + + // test + assertNull(json2.optJSONObject(EXPERIENCE_CLOUD).optJSONObject(AAM_PARAMETERS)); + } + + @Test + public void getRequestPayload_BlobInJson_When_BlobIsValid() throws JSONException { + // setup + Map identitySharedState = getIdentitySharedState("", "blob", "", null); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState, null); + + // test + assertEquals( + json.optJSONObject(EXPERIENCE_CLOUD).optJSONObject(AAM_PARAMETERS).getString(BLOB), + "blob"); + } + + @Test + public void getRequestPayload_LocationHintInJson_When_LocationHintIsValid() + throws JSONException { + // setup + Map identitySharedState = + getIdentitySharedState("", "", "LocationHint", null); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState, null); + + // test + assertEquals( + json.optJSONObject(EXPERIENCE_CLOUD) + .optJSONObject(AAM_PARAMETERS) + .getString(LOCATION_HINT), + "LocationHint"); + } + + @Test + public void getRequestPayload_LocationHintNotInJson_When_LocationHintIsEmptyOrNull() + throws JSONException { + // setup + Map identitySharedState = getIdentitySharedState("", "", "", null); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState, null); + + // test + assertNull(json.optJSONObject(EXPERIENCE_CLOUD).optJSONObject(AAM_PARAMETERS)); + + // setup + Map identitySharedState2 = getIdentitySharedState("", null, "", null); + + // test + JSONObject json2 = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState2, null); + + // test + assertNull(json2.optJSONObject(EXPERIENCE_CLOUD).optJSONObject(AAM_PARAMETERS)); + } + + @Test + public void getRequestPayload_CustomerIdsInJson_When_CustomerIdsIsValid() throws JSONException { + // setup + final Map customVisitorID = + new HashMap() { + { + put(VISITOR_IDS_ID, "someID"); + put(VISITOR_IDS_ID_TYPE, "someType"); + put(VISITOR_IDS_ID_ORIGIN, "someOrigin"); + put( + VISITOR_IDS_STATE, + VisitorID.AuthenticationState.AUTHENTICATED.getValue()); + } + }; + final Map identitySharedState = + getIdentitySharedState("", "", "", Arrays.asList(customVisitorID)); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState, null); + + // test + assertEquals( + json.optJSONObject(ID) + .optJSONArray(CUSTOMER_IDS) + .getJSONObject(0) + .get(AUTHENTICATION_STATE), + "authenticated"); + } + + @Test + public void getRequestPayload_CustomerIdsInJson_OnlyPicks_ValidCustomerIDs() + throws JSONException { + // setup + final Map customVisitorID1 = + new HashMap() { + { + put(VISITOR_IDS_ID, "someID1"); + put(VISITOR_IDS_ID_TYPE, "someType1"); + put(VISITOR_IDS_ID_ORIGIN, "someOrigin1"); + put(VISITOR_IDS_STATE, VisitorID.AuthenticationState.LOGGED_OUT.getValue()); + } + }; + + // without ID + final Map customVisitorID2 = + new HashMap() { + { + put(VISITOR_IDS_ID_TYPE, "someType2"); + put(VISITOR_IDS_ID_ORIGIN, "someOrigin2"); + put( + VISITOR_IDS_STATE, + VisitorID.AuthenticationState.AUTHENTICATED.getValue()); + } + }; + + // without integrationCode (type) + final Map customVisitorID3 = + new HashMap() { + { + put(VISITOR_IDS_ID, "someID2"); + put(VISITOR_IDS_ID_ORIGIN, "someOrigin2"); + put( + VISITOR_IDS_STATE, + VisitorID.AuthenticationState.AUTHENTICATED.getValue()); + } + }; + + // nonString integrationCode value + final Map customVisitorID4 = + new HashMap() { + { + put(VISITOR_IDS_ID, 34); + put(VISITOR_IDS_ID_TYPE, "someType2"); + put(VISITOR_IDS_ID_ORIGIN, "someOrigin2"); + put(VISITOR_IDS_STATE, VisitorID.AuthenticationState.LOGGED_OUT.getValue()); + } + }; + Map identitySharedState = + getIdentitySharedState( + "", + "", + "", + Arrays.asList( + customVisitorID1, + customVisitorID2, + customVisitorID3, + customVisitorID4)); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState, null); + + // verify + JSONArray gatheredIds = json.optJSONObject(ID).optJSONArray(CUSTOMER_IDS); + assertEquals("Length of customerIDs is correct", 1, gatheredIds.length()); + JSONObject gatheredVisitorID = gatheredIds.getJSONObject(0); + assertEquals( + "Correct CustomerID id is set", gatheredVisitorID.get(CUSTOMER_ID_ID), "someID1"); + assertEquals( + "Correct CustomerID IntegrationCode is set", + gatheredVisitorID.get(CUSTOMER_ID_INTEGRATION_CODE), + "someType1"); + assertEquals( + "Correct CustomerID authentication state is set", + gatheredVisitorID.get(CUSTOMER_ID_AUTHENTICATION_STATE), + "logged_out"); + } + + @Test + public void getRequestPayload_CustomerIdsInJson_When_CustomerIdsIsValid_AndLoggedOut() + throws JSONException { + // setup + final Map customVisitorID = + new HashMap() { + { + put(VISITOR_IDS_ID, "someID"); + put(VISITOR_IDS_ID_TYPE, "someType"); + put(VISITOR_IDS_ID_ORIGIN, "someOrigin"); + put(VISITOR_IDS_STATE, VisitorID.AuthenticationState.LOGGED_OUT.getValue()); + } + }; + Map identitySharedState = + getIdentitySharedState("", "", "", Arrays.asList(customVisitorID)); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState, null); + + // test + assertEquals( + json.optJSONObject(ID) + .optJSONArray(CUSTOMER_IDS) + .getJSONObject(0) + .get(AUTHENTICATION_STATE), + "logged_out"); + } + + @Test + public void getRequestPayload_CustomerIdsInJson_When_CustomerIdsIsValid_AndUnknown() + throws JSONException { + // setup + final Map customVisitorID = + new HashMap() { + { + put(VISITOR_IDS_ID, "someID"); + put(VISITOR_IDS_ID_TYPE, "someType"); + put(VISITOR_IDS_ID_ORIGIN, "someOrigin"); + put(VISITOR_IDS_STATE, 5); + } + }; + + List testVisitorIDList = new ArrayList<>(); + testVisitorIDList.add( + new VisitorID("d_cid_ic", "id1", "hodor", VisitorID.AuthenticationState.UNKNOWN)); + Map identitySharedState = + getIdentitySharedState("", "", "", Arrays.asList(customVisitorID)); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState, null); + + // test + assertEquals( + json.optJSONObject(ID) + .optJSONArray(CUSTOMER_IDS) + .getJSONObject(0) + .get(AUTHENTICATION_STATE), + "unknown"); + } + + @Test + public void getRequestPayload_CustomerIdsNotInJson_When_CustomerIdsIsEmptyOrNull() + throws JSONException { + // setup + Map identitySharedState = + getIdentitySharedState("", "", "", new ArrayList<>()); + + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState, null); + + // test + assertNull(json.optJSONObject(ID)); + + // setup + Map identitySharedState2 = getIdentitySharedState("", null, "", null); + + // test + JSONObject json2 = + targetRequestBuilder.getRequestPayload( + null, null, null, null, null, identitySharedState2, null); + + // test + assertNull(json.optJSONObject(ID)); + } + + // =================================== + // Test getRequestPayload_LifecycleData + // =================================== + @Test + public void getRequestPayload_LifecycleDataNotInJson_When_LifecycleIsEmptyOrNull() { + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, getTargetRequestList(1), null, null, null, null, null); + + // verify + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS)); + + // test + json = + targetRequestBuilder.getRequestPayload( + null, getTargetRequestList(1), null, null, null, null, new HashMap<>()); + + // verify + assertNull( + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS)); } @Test public void getRequestPayload_LifecycleDataInMboxParameters_When_LifecycleIsValid() { - // test - JSONObject json = targetRequestBuilder.getRequestPayload(null, getTargetRequestList(1), null, - null, null, null, lifecycleData); - - // verify - assertEquals(new JSONObject(lifecycleData).toString(), json.optJSONObject(EXECUTE_MBOXES).optJSONArray(MBOXES).optJSONObject(0).optJSONObject( - PARAMETERS).toString()); - - } - - // =================================== - // Test getDisplayNotificationJsonObject - // =================================== - @Test - public void getDisplayNotificationJsonObject_ReturnNull_When_InputJsonIsNull() { - // test - JSONObject json = targetRequestBuilder.getDisplayNotificationJsonObject(null, null, null, 123L, null); - - // verify - assertNull(json); - } - - @Test - public void getDisplayNotificationJsonObject_ReturnObjectWithTimeStampAndMetricType1_When_InputJsonIsNotNull() throws - JSONException { - // setup - JSONObject json = new JSONObject();; - json.put(CONTENT, "content"); - json.put(A4T, "A4T"); - json.put("key", "value"); - json.put(STATE, "somestate"); - JSONObject options1 = new JSONObject(); - options1.put("eventToken", "token1"); - JSONObject options2 = new JSONObject(); - JSONArray optionsArray = new JSONArray(); - optionsArray.put(options1); - optionsArray.put(options2); - json.put(OPTIONS, optionsArray); - - // test - JSONObject visitedMboxNode = targetRequestBuilder.getDisplayNotificationJsonObject("mboxName", json, - null, 123L, null); - - // verify - assertNull(visitedMboxNode.opt(CONTENT)); - assertNull(visitedMboxNode.opt(A4T)); - assertEquals(METRIC_TYPE_DISPLAY, visitedMboxNode.opt(METRIC_TYPE)); - assertEquals(123L, visitedMboxNode.opt(TIMESTAMP)); - assertEquals("mboxName", visitedMboxNode.optJSONObject(MBOX).opt(NAME)); - assertEquals("somestate", visitedMboxNode.optJSONObject(MBOX).opt(STATE)); - assertEquals("token1", visitedMboxNode.optJSONArray(TOKENS).get(0)); - } - - // =================================== - // Test getClickNotificationJsonObject - // =================================== - @Test - public void getClickNotificationJsonObject_When_InputJsonIsNotNull() throws JSONException { - // setup - JSONObject mboxJson = new JSONObject();; - mboxJson.put(NAME, "mboxName"); - JSONObject metric1 = new JSONObject(); - metric1.put("eventToken", "token1"); - metric1.put(METRIC_TYPE, METRIC_TYPE_CLICK); - JSONObject metric2 = new JSONObject(); - JSONObject metric3 = new JSONObject(); - metric3.put(METRIC_TYPE, "custom"); - JSONArray metricsArray = new JSONArray(); - metricsArray.put(metric1); - metricsArray.put(metric2); - metricsArray.put(metric3); - mboxJson.put(METRICS, metricsArray); - - // test - JSONObject clickJson = targetRequestBuilder.getClickNotificationJsonObject(mboxJson, - null, 123L, null); - - // verify - assertEquals(123L, clickJson.opt(TIMESTAMP)); - assertEquals(METRIC_TYPE_CLICK, clickJson.opt(METRIC_TYPE)); - assertEquals("mboxName", clickJson.optJSONObject(MBOX).opt(NAME)); - assertEquals("token1", clickJson.optJSONArray(TOKENS).get(0)); - } - - @Test - public void getClickNotificationJsonObject_ReturnObjectWithTimeStampAndMetricType_When_InputJsonIsNull() { - // test - JSONObject json = targetRequestBuilder.getClickNotificationJsonObject(( - JSONObject) null, null, 123L, null); - - // verify - assertNotNull(json); - assertEquals(123L, json.opt(TIMESTAMP)); - assertEquals(METRIC_TYPE_CLICK, json.opt(METRIC_TYPE)); - } - - // =================================== - // Test getDefaultJsonObject - // =================================== - @Test - public void getDefaultJsonObject_NullParameters() { - // test - Mockito.when(mockTargetState.getTntId()).thenReturn("tntId"); - Mockito.when(mockTargetState.getThirdPartyId()).thenReturn("thirdPartyId"); - - JSONObject json = targetRequestBuilder.getDefaultJsonObject(null, null, null, 0L, null); - - // verify - assertEquals(3, json.length()); - assertNotNull(json.optJSONObject(ID)); - assertNotNull(json.optJSONObject(CONTEXT_PARAMETERS)); - assertNotNull(json.optJSONObject(EXPERIENCE_CLOUD)); - } - - @Test - public void getDefaultJsonObject_CustomParameters() { - // setup - Map idMap = new HashMap() { - { - put("id", "customId"); - } - }; - - Map contextMap = new HashMap() { - { - put("context", "customContext"); - } - }; - - Map experienceCloudId = new HashMap() { - { - put("ecid", "customEcid"); - } - }; - - // test - JSONObject json = targetRequestBuilder.getDefaultJsonObject(idMap, contextMap, experienceCloudId, - 1234L, getIdentitySharedState("mcid", "blob", "locationHint", new ArrayList<>())); - - // verify - assertEquals(new JSONObject(idMap).toString(), json.optJSONObject(ID).toString()); - assertEquals(new JSONObject(contextMap).toString(), json.optJSONObject(CONTEXT_PARAMETERS).toString()); - assertEquals(new JSONObject(experienceCloudId).toString(), json.optJSONObject(EXPERIENCE_CLOUD).toString()); - assertEquals(1234L, json.optLong(ENVIRONMENT_ID)); - } - - @Test - public void getDefaultJsonObject_WithCustomVisitorIDs() throws JSONException { - // test - JSONObject json = targetRequestBuilder.getDefaultJsonObject(null, null, null, 1234L, getIdentitySharedState("mcid", "blob", "locationHint", new ArrayList>(){{ - add(new HashMap(){{ - put(VISITOR_IDS_ID, "someID1" ); - put(VISITOR_IDS_ID_TYPE, "someType1" ); - put(VISITOR_IDS_ID_ORIGIN, "someOrigin1" ); - put(VISITOR_IDS_STATE, 1); - }}); - add(new HashMap(){{ - put(VISITOR_IDS_ID, "someID2" ); - put(VISITOR_IDS_ID_TYPE, "someType2" ); - put(VISITOR_IDS_ID_ORIGIN, "someOrigin2" ); - put(VISITOR_IDS_STATE, 2); - }}); - add(new HashMap(){{ - put(VISITOR_IDS_ID, "someID3" ); - put(VISITOR_IDS_ID_TYPE, "someType3" ); - put(VISITOR_IDS_STATE, 3); - }}); - }})); - - // verify - assertEquals(1234L, json.optLong(ENVIRONMENT_ID)); - JSONObject id = json.optJSONObject(ID); - JSONArray visitorIDList = id.optJSONArray(CUSTOMER_IDS); - JSONObject firstVisitorID = (JSONObject) visitorIDList.get(0); - JSONObject secondVisitorID = (JSONObject) visitorIDList.get(1); - - assertEquals("someID1", firstVisitorID.get(CUSTOMER_ID_ID)); - assertEquals("someType1", firstVisitorID.get(CUSTOMER_ID_INTEGRATION_CODE)); - assertEquals("authenticated", firstVisitorID.get(CUSTOMER_ID_AUTHENTICATION_STATE)); - - assertEquals("someID2", secondVisitorID.get(CUSTOMER_ID_ID)); - assertEquals("someType2", secondVisitorID.get(CUSTOMER_ID_INTEGRATION_CODE)); - assertEquals("logged_out", secondVisitorID.get(CUSTOMER_ID_AUTHENTICATION_STATE)); - } - - @Test - public void getDefaultJsonObject_CustomVisitorIDs_withInvalidValueTypes() throws JSONException { - // test - JSONObject json = targetRequestBuilder.getDefaultJsonObject(null, null, null, 1234L, getIdentitySharedState("mcid", "blob", "locationHint", new ArrayList>(){{ - add(new HashMap(){{ - put(VISITOR_IDS_ID, false); - put(VISITOR_IDS_ID_TYPE, 788); - put(VISITOR_IDS_STATE, "invalid"); - }}); - }})); - - // verify - JSONObject id = json.optJSONObject(ID); - JSONArray visitorIDList = id.optJSONArray(CUSTOMER_IDS); - assertEquals(0, visitorIDList.length()); - } + // test + JSONObject json = + targetRequestBuilder.getRequestPayload( + null, getTargetRequestList(1), null, null, null, null, lifecycleData); + + // verify + assertEquals( + new JSONObject(lifecycleData).toString(), + json.optJSONObject(EXECUTE_MBOXES) + .optJSONArray(MBOXES) + .optJSONObject(0) + .optJSONObject(PARAMETERS) + .toString()); + } + + // =================================== + // Test getDisplayNotificationJsonObject + // =================================== + @Test + public void getDisplayNotificationJsonObject_ReturnNull_When_InputJsonIsNull() { + // test + JSONObject json = + targetRequestBuilder.getDisplayNotificationJsonObject(null, null, null, 123L, null); + + // verify + assertNull(json); + } + + @Test + public void + getDisplayNotificationJsonObject_ReturnObjectWithTimeStampAndMetricType1_When_InputJsonIsNotNull() + throws JSONException { + // setup + JSONObject json = new JSONObject(); + ; + json.put(CONTENT, "content"); + json.put(A4T, "A4T"); + json.put("key", "value"); + json.put(STATE, "somestate"); + JSONObject options1 = new JSONObject(); + options1.put("eventToken", "token1"); + JSONObject options2 = new JSONObject(); + JSONArray optionsArray = new JSONArray(); + optionsArray.put(options1); + optionsArray.put(options2); + json.put(OPTIONS, optionsArray); + + // test + JSONObject visitedMboxNode = + targetRequestBuilder.getDisplayNotificationJsonObject( + "mboxName", json, null, 123L, null); + + // verify + assertNull(visitedMboxNode.opt(CONTENT)); + assertNull(visitedMboxNode.opt(A4T)); + assertEquals(METRIC_TYPE_DISPLAY, visitedMboxNode.opt(METRIC_TYPE)); + assertEquals(123L, visitedMboxNode.opt(TIMESTAMP)); + assertEquals("mboxName", visitedMboxNode.optJSONObject(MBOX).opt(NAME)); + assertEquals("somestate", visitedMboxNode.optJSONObject(MBOX).opt(STATE)); + assertEquals("token1", visitedMboxNode.optJSONArray(TOKENS).get(0)); + } + + // =================================== + // Test getClickNotificationJsonObject + // =================================== + @Test + public void getClickNotificationJsonObject_When_InputJsonIsNotNull() throws JSONException { + // setup + JSONObject mboxJson = new JSONObject(); + ; + mboxJson.put(NAME, "mboxName"); + JSONObject metric1 = new JSONObject(); + metric1.put("eventToken", "token1"); + metric1.put(METRIC_TYPE, METRIC_TYPE_CLICK); + JSONObject metric2 = new JSONObject(); + JSONObject metric3 = new JSONObject(); + metric3.put(METRIC_TYPE, "custom"); + JSONArray metricsArray = new JSONArray(); + metricsArray.put(metric1); + metricsArray.put(metric2); + metricsArray.put(metric3); + mboxJson.put(METRICS, metricsArray); + + // test + JSONObject clickJson = + targetRequestBuilder.getClickNotificationJsonObject(mboxJson, null, 123L, null); + + // verify + assertEquals(123L, clickJson.opt(TIMESTAMP)); + assertEquals(METRIC_TYPE_CLICK, clickJson.opt(METRIC_TYPE)); + assertEquals("mboxName", clickJson.optJSONObject(MBOX).opt(NAME)); + assertEquals("token1", clickJson.optJSONArray(TOKENS).get(0)); + } + + @Test + public void + getClickNotificationJsonObject_ReturnObjectWithTimeStampAndMetricType_When_InputJsonIsNull() { + // test + JSONObject json = + targetRequestBuilder.getClickNotificationJsonObject( + (JSONObject) null, null, 123L, null); + + // verify + assertNotNull(json); + assertEquals(123L, json.opt(TIMESTAMP)); + assertEquals(METRIC_TYPE_CLICK, json.opt(METRIC_TYPE)); + } + + // =================================== + // Test getDefaultJsonObject + // =================================== + @Test + public void getDefaultJsonObject_NullParameters() { + // test + Mockito.when(mockTargetState.getTntId()).thenReturn("tntId"); + Mockito.when(mockTargetState.getThirdPartyId()).thenReturn("thirdPartyId"); + + JSONObject json = targetRequestBuilder.getDefaultJsonObject(null, null, null, 0L, null); + + // verify + assertEquals(3, json.length()); + assertNotNull(json.optJSONObject(ID)); + assertNotNull(json.optJSONObject(CONTEXT_PARAMETERS)); + assertNotNull(json.optJSONObject(EXPERIENCE_CLOUD)); + } + + @Test + public void getDefaultJsonObject_CustomParameters() { + // setup + Map idMap = + new HashMap() { + { + put("id", "customId"); + } + }; + + Map contextMap = + new HashMap() { + { + put("context", "customContext"); + } + }; + + Map experienceCloudId = + new HashMap() { + { + put("ecid", "customEcid"); + } + }; + + // test + JSONObject json = + targetRequestBuilder.getDefaultJsonObject( + idMap, + contextMap, + experienceCloudId, + 1234L, + getIdentitySharedState("mcid", "blob", "locationHint", new ArrayList<>())); + + // verify + assertEquals(new JSONObject(idMap).toString(), json.optJSONObject(ID).toString()); + assertEquals( + new JSONObject(contextMap).toString(), + json.optJSONObject(CONTEXT_PARAMETERS).toString()); + assertEquals( + new JSONObject(experienceCloudId).toString(), + json.optJSONObject(EXPERIENCE_CLOUD).toString()); + assertEquals(1234L, json.optLong(ENVIRONMENT_ID)); + } + + @Test + public void getDefaultJsonObject_WithCustomVisitorIDs() throws JSONException { + // test + JSONObject json = + targetRequestBuilder.getDefaultJsonObject( + null, + null, + null, + 1234L, + getIdentitySharedState( + "mcid", + "blob", + "locationHint", + new ArrayList>() { + { + add( + new HashMap() { + { + put(VISITOR_IDS_ID, "someID1"); + put(VISITOR_IDS_ID_TYPE, "someType1"); + put(VISITOR_IDS_ID_ORIGIN, "someOrigin1"); + put(VISITOR_IDS_STATE, 1); + } + }); + add( + new HashMap() { + { + put(VISITOR_IDS_ID, "someID2"); + put(VISITOR_IDS_ID_TYPE, "someType2"); + put(VISITOR_IDS_ID_ORIGIN, "someOrigin2"); + put(VISITOR_IDS_STATE, 2); + } + }); + add( + new HashMap() { + { + put(VISITOR_IDS_ID, "someID3"); + put(VISITOR_IDS_ID_TYPE, "someType3"); + put(VISITOR_IDS_STATE, 3); + } + }); + } + })); + + // verify + assertEquals(1234L, json.optLong(ENVIRONMENT_ID)); + JSONObject id = json.optJSONObject(ID); + JSONArray visitorIDList = id.optJSONArray(CUSTOMER_IDS); + JSONObject firstVisitorID = (JSONObject) visitorIDList.get(0); + JSONObject secondVisitorID = (JSONObject) visitorIDList.get(1); + + assertEquals("someID1", firstVisitorID.get(CUSTOMER_ID_ID)); + assertEquals("someType1", firstVisitorID.get(CUSTOMER_ID_INTEGRATION_CODE)); + assertEquals("authenticated", firstVisitorID.get(CUSTOMER_ID_AUTHENTICATION_STATE)); + + assertEquals("someID2", secondVisitorID.get(CUSTOMER_ID_ID)); + assertEquals("someType2", secondVisitorID.get(CUSTOMER_ID_INTEGRATION_CODE)); + assertEquals("logged_out", secondVisitorID.get(CUSTOMER_ID_AUTHENTICATION_STATE)); + } + + @Test + public void getDefaultJsonObject_CustomVisitorIDs_withInvalidValueTypes() throws JSONException { + // test + JSONObject json = + targetRequestBuilder.getDefaultJsonObject( + null, + null, + null, + 1234L, + getIdentitySharedState( + "mcid", + "blob", + "locationHint", + new ArrayList>() { + { + add( + new HashMap() { + { + put(VISITOR_IDS_ID, false); + put(VISITOR_IDS_ID_TYPE, 788); + put(VISITOR_IDS_STATE, "invalid"); + } + }); + } + })); + + // verify + JSONObject id = json.optJSONObject(ID); + JSONArray visitorIDList = id.optJSONArray(CUSTOMER_IDS); + assertEquals(0, visitorIDList.length()); + } // =================================== // Helpers @@ -2239,7 +3100,8 @@ List getTargetRequestList(int count) { for (int i = 0; i < count; i++) { final String mboxName = "mbox" + i; - TargetRequest targetRequest = new TargetRequest(mboxName, null, "default", callback -> {}); + TargetRequest targetRequest = + new TargetRequest(mboxName, null, "default", callback -> {}); targetRequestList.add(targetRequest); } @@ -2258,9 +3120,11 @@ List getTargetPrefetchList(int count) { return targetPrefetchList; } - Map getIdentitySharedState(final String marketingCloudId, - final String blob, final String locationHint, - final List> customerIds) { + Map getIdentitySharedState( + final String marketingCloudId, + final String blob, + final String locationHint, + final List> customerIds) { return new HashMap() { { put(VISITOR_ID_MID, marketingCloudId); diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetRequestTests.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetRequestTests.java index 02f9e54..33d06f9 100644 --- a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetRequestTests.java +++ b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetRequestTests.java @@ -1,14 +1,13 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; @@ -18,12 +17,10 @@ import com.adobe.marketing.mobile.AdobeCallback; import com.adobe.marketing.mobile.AdobeError; - -import org.junit.Test; - import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +import org.junit.Test; public class TargetRequestTests { protected final String MBOX_NAME_HAPPY_PATH = "name"; @@ -32,82 +29,99 @@ public class TargetRequestTests { private final String DEFAULT_CONTENT_HAPPY_PATH = "defaultContent"; - protected final Map MBOX_PARAMETERS_HAPPY_PATH = new HashMap() { - { - put("one", "uno"); - put("two", "dos"); - put("three", "tres"); - } - }; - - protected final Map PROFILE_PARAMETERS_HAPPY_PATH = new HashMap() { - { - put("profileKey1", "profileValue1"); - put("profileKey2", "profileValue2"); - } - }; + protected final Map MBOX_PARAMETERS_HAPPY_PATH = + new HashMap() { + { + put("one", "uno"); + put("two", "dos"); + put("three", "tres"); + } + }; + + protected final Map PROFILE_PARAMETERS_HAPPY_PATH = + new HashMap() { + { + put("profileKey1", "profileValue1"); + put("profileKey2", "profileValue2"); + } + }; protected final TargetProduct PRODUCT_PARAMETERS_HAPPY_PATH = new TargetProduct("pId", "cId"); - protected final Map PRODUCT_PARAMETERS_HAPPY_PATH_MAP = new HashMap() { - { - put("id", "pId"); - put("categoryId", "cId"); - } - }; - - protected final TargetOrder ORDER_PARAMETERS_HAPPY_PATH = new TargetOrder("orderId", 100.34, new ArrayList() { - { - add("ppId"); - } - }); - - protected final Map ORDER_PARAMETERS_HAPPY_PATH_MAP = new HashMap() { - { - put("id", "orderId"); - put("purchasedProductIds", new ArrayList() { + protected final Map PRODUCT_PARAMETERS_HAPPY_PATH_MAP = + new HashMap() { + { + put("id", "pId"); + put("categoryId", "cId"); + } + }; + + protected final TargetOrder ORDER_PARAMETERS_HAPPY_PATH = + new TargetOrder( + "orderId", + 100.34, + new ArrayList() { + { + add("ppId"); + } + }); + + protected final Map ORDER_PARAMETERS_HAPPY_PATH_MAP = + new HashMap() { + { + put("id", "orderId"); + put( + "purchasedProductIds", + new ArrayList() { + { + add("ppId"); + } + }); + put("total", 100.34); + } + }; + + protected final TargetParameters TARGET_PARAMETERS_HAPPY_PATH = + new TargetParameters.Builder() + .parameters(MBOX_PARAMETERS_HAPPY_PATH) + .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) + .order(ORDER_PARAMETERS_HAPPY_PATH) + .product(PRODUCT_PARAMETERS_HAPPY_PATH) + .build(); + + protected final Map TARGET_PARAMETERS_HAPPY_PATH_MAP = + new HashMap() { { - add("ppId"); + put("parameters", MBOX_PARAMETERS_HAPPY_PATH); + put("profileParameters", PROFILE_PARAMETERS_HAPPY_PATH); + put("order", ORDER_PARAMETERS_HAPPY_PATH_MAP); + put("product", PRODUCT_PARAMETERS_HAPPY_PATH_MAP); } - }); - put("total", 100.34); - } - }; - - protected final TargetParameters TARGET_PARAMETERS_HAPPY_PATH = new TargetParameters.Builder() - .parameters(MBOX_PARAMETERS_HAPPY_PATH) - .profileParameters(PROFILE_PARAMETERS_HAPPY_PATH) - .order(ORDER_PARAMETERS_HAPPY_PATH) - .product(PRODUCT_PARAMETERS_HAPPY_PATH) - .build(); - - protected final Map TARGET_PARAMETERS_HAPPY_PATH_MAP = new HashMap() { - { - put("parameters", MBOX_PARAMETERS_HAPPY_PATH); - put("profileParameters", PROFILE_PARAMETERS_HAPPY_PATH); - put("order", ORDER_PARAMETERS_HAPPY_PATH_MAP); - put("product", PRODUCT_PARAMETERS_HAPPY_PATH_MAP); - } - }; - - final AdobeCallback CONTENT_CALLBACK_HAPPY_PATH = new AdobeCallback() { - @Override - public void call(String value) { - - } - }; - - final AdobeTargetDetailedCallback CONTENT_WITH_DATA_CALLBACK_HAPPY_PATH = new AdobeTargetDetailedCallback() { - @Override - public void call(String content, Map data) { } - - @Override - public void fail(AdobeError var1) { } - }; + }; + + final AdobeCallback CONTENT_CALLBACK_HAPPY_PATH = + new AdobeCallback() { + @Override + public void call(String value) {} + }; + + final AdobeTargetDetailedCallback CONTENT_WITH_DATA_CALLBACK_HAPPY_PATH = + new AdobeTargetDetailedCallback() { + @Override + public void call(String content, Map data) {} + + @Override + public void fail(AdobeError var1) {} + }; @Test public void testTargetRequest_happy() { - final TargetRequest targetRequest = new TargetRequest(MBOX_NAME_HAPPY_PATH, TARGET_PARAMETERS_HAPPY_PATH, DEFAULT_CONTENT_HAPPY_PATH, CONTENT_CALLBACK_HAPPY_PATH); + final TargetRequest targetRequest = + new TargetRequest( + MBOX_NAME_HAPPY_PATH, + TARGET_PARAMETERS_HAPPY_PATH, + DEFAULT_CONTENT_HAPPY_PATH, + CONTENT_CALLBACK_HAPPY_PATH); assertNotNull(targetRequest); assertEquals(MBOX_NAME_HAPPY_PATH, targetRequest.getMboxName()); assertEquals(TARGET_PARAMETERS_HAPPY_PATH, targetRequest.getTargetParameters()); @@ -117,17 +131,28 @@ public void testTargetRequest_happy() { @Test public void testTargetRequest_withAdobeTargetDetailedCallback() { - final TargetRequest targetRequest = new TargetRequest(MBOX_NAME_HAPPY_PATH, TARGET_PARAMETERS_HAPPY_PATH, DEFAULT_CONTENT_HAPPY_PATH, CONTENT_WITH_DATA_CALLBACK_HAPPY_PATH); + final TargetRequest targetRequest = + new TargetRequest( + MBOX_NAME_HAPPY_PATH, + TARGET_PARAMETERS_HAPPY_PATH, + DEFAULT_CONTENT_HAPPY_PATH, + CONTENT_WITH_DATA_CALLBACK_HAPPY_PATH); assertNotNull(targetRequest); assertEquals(MBOX_NAME_HAPPY_PATH, targetRequest.getMboxName()); assertEquals(TARGET_PARAMETERS_HAPPY_PATH, targetRequest.getTargetParameters()); assertEquals(DEFAULT_CONTENT_HAPPY_PATH, targetRequest.getDefaultContent()); - assertEquals(CONTENT_WITH_DATA_CALLBACK_HAPPY_PATH, targetRequest.getContentWithDataCallback()); + assertEquals( + CONTENT_WITH_DATA_CALLBACK_HAPPY_PATH, targetRequest.getContentWithDataCallback()); } @Test public void testToEventData_validTargetRequestMap() { - final TargetRequest targetRequest = new TargetRequest(MBOX_NAME_HAPPY_PATH, TARGET_PARAMETERS_HAPPY_PATH, DEFAULT_CONTENT_HAPPY_PATH, CONTENT_CALLBACK_HAPPY_PATH); + final TargetRequest targetRequest = + new TargetRequest( + MBOX_NAME_HAPPY_PATH, + TARGET_PARAMETERS_HAPPY_PATH, + DEFAULT_CONTENT_HAPPY_PATH, + CONTENT_CALLBACK_HAPPY_PATH); targetRequest.setResponsePairId(RESPONSE_PAIR_ID_HAPPY_PATH); final Map targetRequestMap = targetRequest.toEventData(); @@ -171,6 +196,6 @@ public void testFromEventData_InvalidTargetRequest() { public void testFromEventData_nullOrEmptyTargetRequest() { assertNull(TargetRequest.fromEventData(null)); - assertNull( TargetRequest.fromEventData(new HashMap<>())); + assertNull(TargetRequest.fromEventData(new HashMap<>())); } } diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetResponseParserTest.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetResponseParserTest.java index 246c8bb..e67a54a 100644 --- a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetResponseParserTest.java +++ b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetResponseParserTest.java @@ -1,18 +1,25 @@ /* - Copyright 2023 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ - + Copyright 2023 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; +import static org.junit.Assert.*; + +import com.adobe.marketing.mobile.services.HttpConnecting; +import com.adobe.marketing.mobile.util.JSONUtils; +import com.adobe.marketing.mobile.util.StreamUtils; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import org.json.JSONException; import org.json.JSONObject; import org.junit.Before; @@ -20,45 +27,36 @@ import org.mockito.MockedStatic; import org.mockito.Mockito; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.*; - -import com.adobe.marketing.mobile.services.HttpConnecting; -import com.adobe.marketing.mobile.util.JSONUtils; -import com.adobe.marketing.mobile.util.StreamUtils; - public class TargetResponseParserTest { - private static final String FAKE_SESSION_ID = "session_id"; + private static final String FAKE_SESSION_ID = "session_id"; - private TargetResponseParser responseParser; + private TargetResponseParser responseParser; - @Before() - public void beforeEach() { - responseParser = new TargetResponseParser(); - } + @Before() + public void beforeEach() { + responseParser = new TargetResponseParser(); + } - // =================================== - // Test parseResponseToJson - // =================================== - @Test - public void testParseResponseToJson_Happy() throws Exception { - // setup + // =================================== + // Test parseResponseToJson + // =================================== + @Test + public void testParseResponseToJson_Happy() throws Exception { + // setup try (MockedStatic streamUtilsMock = Mockito.mockStatic(StreamUtils.class)) { - streamUtilsMock.when(() -> StreamUtils.readAsString(Mockito.any())) - .thenReturn("{\n" + - " \"prefetch\" : {\n" + - " \"mboxes\" : [{\n" + - " \"name\" : \"mboxName\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"myContent\"" + - " }]\n" + - " }]\n" + " }\n" + - "}" - ); + streamUtilsMock + .when(() -> StreamUtils.readAsString(Mockito.any())) + .thenReturn( + "{\n" + + " \"prefetch\" : {\n" + + " \"mboxes\" : [{\n" + + " \"name\" : \"mboxName\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"myContent\"" + + " }]\n" + + " }]\n" + + " }\n" + + "}"); HttpConnecting mockedHttpConnecting = Mockito.mock(HttpConnecting.class); // test @@ -68,14 +66,13 @@ public void testParseResponseToJson_Happy() throws Exception { assertNotNull(jsonObject); assertNotNull(jsonObject.get("prefetch")); } - } + } - @Test - public void testParseResponseToJson_WhenEmptyResponse() { + @Test + public void testParseResponseToJson_WhenEmptyResponse() { // setup try (MockedStatic streamUtilsMock = Mockito.mockStatic(StreamUtils.class)) { - streamUtilsMock.when(() -> StreamUtils.readAsString(Mockito.any())) - .thenReturn(""); + streamUtilsMock.when(() -> StreamUtils.readAsString(Mockito.any())).thenReturn(""); HttpConnecting mockedHttpConnecting = Mockito.mock(HttpConnecting.class); // test @@ -87,7 +84,8 @@ public void testParseResponseToJson_WhenEmptyResponse() { public void testParseResponseToJson_When_ResponseInvalidJSON() { // setup try (MockedStatic streamUtilsMock = Mockito.mockStatic(StreamUtils.class)) { - streamUtilsMock.when(() -> StreamUtils.readAsString(Mockito.any())) + streamUtilsMock + .when(() -> StreamUtils.readAsString(Mockito.any())) .thenReturn("InvalidJSON"); HttpConnecting mockedHttpConnecting = Mockito.mock(HttpConnecting.class); @@ -96,1053 +94,1118 @@ public void testParseResponseToJson_When_ResponseInvalidJSON() { } } - @Test - public void testParseResponseToJson_When_ConnectionNull() { - // test - assertNull(responseParser.parseResponseToJson(null)); - } - - // =================================== - // Test ExtractPrefetchedMboxes - // =================================== - @Test - public void testExtractPrefetchedMboxes_Happy() throws Exception { - // setup - String serverResponse = "{\n" + - " \"prefetch\" : {\n" + - " \"mboxes\" : [{\n" + - " \"name\" : \"mboxName\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"myContent\"" + - " }]\n" + - " }]\n" + " }\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map prefetchedMboxes = responseParser.extractPrefetchedMboxes(jsonObject); - - // verify - assertEquals(1, prefetchedMboxes.size()); - assertEquals("mboxName", prefetchedMboxes.get("mboxName").getString("name")); - assertEquals("myContent", prefetchedMboxes.get("mboxName").getJSONArray("options").getJSONObject( - 0).getString("content")); - } - - @Test - public void testExtractPrefetchedMboxes_When_NoPrefetchMboxKeys() throws Exception { - // setup - String serverResponse = "{\n" + - " \"noprefetch\" : {\n" + - " \"mboxes\" : [{\n" + - " \"name\" : \"mboxName\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"myContent\"" + - " }]\n" + - " }]\n" + " }\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map prefetchedMboxes = responseParser.extractPrefetchedMboxes(jsonObject); - - // verify - assertNull(prefetchedMboxes); - } - - @Test - public void testExtractPrefetchedMboxes_Will_ReturnNull_When_PrefetchMboxInvalidType() throws Exception { - // setup - String serverResponse = "{\n" + - " \"prefetch\": \"ItsAString\"\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map prefetchedMboxes = responseParser.extractPrefetchedMboxes(jsonObject); - - // verify - assertNull(prefetchedMboxes); - } - - @Test - public void testExtractPrefetchedMboxes_Will_ReturnEmptyMap_When_PrefetchResponseContainsOneItemWithEmptyMbox() throws - Exception { - // setup - String serverResponse = "{\n" + - " \"prefetch\" : {\n" + - " \"mboxes\" : [{\n" + - " \"name\" : \"\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"myContent\"" + - " }]\n" + - " }]\n" + " }\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map prefetchedMboxes = responseParser.extractPrefetchedMboxes(jsonObject); - - // verify - assertEquals(0, prefetchedMboxes.size()); - } - - @Test - public void testExtractPrefetchedMboxes_Will_IgnoreUnwantedKeys() throws Exception { - // setup - String serverResponse = "{\n" + - " \"prefetch\" : {\n" + - " \"mboxes\" : [{\n" + - " \"name\" : \"mboxName\" , \n" + - " \"unwantedKey\" : \"someValue\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"myContent\"" + - " }]\n" + - " }]\n" + " }\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map prefetchedMboxes = responseParser.extractPrefetchedMboxes(jsonObject); - // verify - assertEquals(1, prefetchedMboxes.size()); - assertEquals(2, prefetchedMboxes.get("mboxName").length()); - assertEquals("mboxName", prefetchedMboxes.get("mboxName").getString("name")); - assertEquals("myContent", prefetchedMboxes.get("mboxName").getJSONArray("options").getJSONObject( - 0).getString("content")); - } - - // =================================== - // Test ExtractBatchedMBoxes - // =================================== - - @Test - public void testExtractBatchedMBoxes_Happy() throws Exception { - // setup - String serverResponse = "{\n" + - " \"execute\": {\n" + - " \"mboxes\": [\n" + - " {\n" + - " \"name\": \"mboxName\",\n" + - " \"index\": 0,\n" + - " }]\n" + " }\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map batchedMBoxes = responseParser.extractBatchedMBoxes(jsonObject); - - // verify - assertEquals(1, batchedMBoxes.size()); - assertEquals("mboxName", batchedMBoxes.get("mboxName").getString("name")); - assertEquals(0, batchedMBoxes.get("mboxName").getInt("index")); - } - - @Test - public void testExtractBatchedMBoxes_When_NoMboxKey() throws Exception { - // setup - String serverResponse = "{\n" + - " \"execute\": {\n" + - " \"nomboxesResponse\": [\n" + - " {\n" + - " \"name\": \"mboxName\",\n" + - " \"index\": 0,\n" + - " }]\n" + " }\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map batchedMBoxes = responseParser.extractBatchedMBoxes(jsonObject); - - // verify - assertNull(batchedMBoxes); - } - - @Test - public void testExtractBatchedMBoxes_Will_ReturnNull_When_MboxResponseInvalidType() throws Exception { - // setup - String serverResponse = "{\n" + - " \"execute\": {\n" + - " \"mboxes\": \"ItsAString\"" + - " }\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map batchedMBoxes = responseParser.extractBatchedMBoxes(jsonObject); - - // verify - assertNull(batchedMBoxes); - } - - @Test - public void testExtractBatchedMBoxes_Will_ReturnEmptyMap_When_MboxResponseContainsOneItemWithEmptyMbox() throws - Exception { - // setup - String serverResponse = "{\n" + - " \"execute\": {\n" + - " \"mboxes\": [\n" + - " {\n" + - " \"name\": \"\",\n" + - " \"index\": 0,\n" + - " }]\n" + " }\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map batchedMBoxes = responseParser.extractBatchedMBoxes(jsonObject); - - // verify - assertEquals(0, batchedMBoxes.size()); - } - - @Test - public void testExtractBatchedMBoxes_InvalidMboxResponse() throws Exception { - // setup - String serverResponse = "{\n" + - " \"execute\" : [2]\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map batchedMBoxes = responseParser.extractBatchedMBoxes(jsonObject); - - // verify - assertNull(batchedMBoxes); - } - - - // =================================== - // Test GetAnalyticsForTargetPayload - // =================================== - @Test - public void testGetAnalyticsForTargetPayload_Happy() throws Exception { - // setup - String serverResponse = "{\n" + - " \"analytics\" : {\n" + - " \"payload\" : {\n" + - " \"key1\" : \"value1\" , \n" + - " \"key2\" : \"value2\" \n" + - " }\n" + " }\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map a4tPayloadMap = responseParser.getAnalyticsForTargetPayload(jsonObject, FAKE_SESSION_ID); - - // verify - assertEquals(3, a4tPayloadMap.size()); - assertEquals("value1", a4tPayloadMap.get("&&key1")); - assertEquals("value2", a4tPayloadMap.get("&&key2")); - assertTrue(a4tPayloadMap.containsKey(TargetTestConstants.EventDataKeys.A4T_SESSION_ID)); - assertEquals(a4tPayloadMap.get(TargetTestConstants.EventDataKeys.A4T_SESSION_ID), FAKE_SESSION_ID); - } - - @Test - public void testGetAnalyticsForTargetPayload_Happy_With_Null_Session_Id() throws Exception { - // setup - String serverResponse = "{\n" + - " \"analytics\" : {\n" + - " \"payload\" : {\n" + - " \"key1\" : \"value1\" , \n" + - " \"key2\" : \"value2\" \n" + - " }\n" + " }\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map a4tPayloadMap = responseParser.getAnalyticsForTargetPayload(jsonObject, null); - - // verify - assertEquals(2, a4tPayloadMap.size()); - assertEquals("value1", a4tPayloadMap.get("&&key1")); - assertEquals("value2", a4tPayloadMap.get("&&key2")); - assertFalse(a4tPayloadMap.containsKey(TargetTestConstants.EventDataKeys.SESSION_ID)); - } - - @Test - public void testGetAnalyticsForTargetPayload_Happy_With_Empty_Session_Id() throws Exception { - // setup - String serverResponse = "{\n" + - " \"analytics\" : {\n" + - " \"payload\" : {\n" + - " \"key1\" : \"value1\" , \n" + - " \"key2\" : \"value2\" \n" + - " }\n" + " }\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map a4tPayloadMap = responseParser.getAnalyticsForTargetPayload(jsonObject, ""); - - // verify - assertEquals(2, a4tPayloadMap.size()); - assertEquals("value1", a4tPayloadMap.get("&&key1")); - assertEquals("value2", a4tPayloadMap.get("&&key2")); - assertFalse(a4tPayloadMap.containsKey(TargetTestConstants.EventDataKeys.SESSION_ID)); - } - - @Test - public void testGetAnalyticsForTargetPayload_A4TPayloadEmpty() throws Exception { - // setup - String serverResponse = "{\n" + - " \"analytics\" : {} }"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map a4tPayloadMap = responseParser.getAnalyticsForTargetPayload(jsonObject, FAKE_SESSION_ID); - - // verify - assertNull(a4tPayloadMap); - } - - @Test - public void testGetAnalyticsForTargetPayload_A4TPayloadIsAInvalidType() throws Exception { - // setup - String serverResponse = "{\n" + - " \"analytics\" : \"ShouldNotBeAString\" }"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map a4tPayloadMap = responseParser.getAnalyticsForTargetPayload(jsonObject, FAKE_SESSION_ID); - - // verify - assertNull(a4tPayloadMap); - } - - @Test - public void testGetAnalyticsForTargetPayload_EmptyJSON() throws Exception { - // setup - String serverResponse = "{}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - Map a4tPayloadMap = responseParser.getAnalyticsForTargetPayload(jsonObject, FAKE_SESSION_ID); - - // verify - assertNull(a4tPayloadMap); - } - - - // =================================== - // Test getTntId - // =================================== - @Test - public void testGetTntId_Happy() throws Exception { - // setup - String serverResponse = "{\n" + - " \"id\": {\n" + - " \"tntId\": \"tntIDValue\"\n" + - " }\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - String actualTntID = responseParser.getTntId(jsonObject); - - // verify - assertEquals("tntIDValue", actualTntID); - } - - @Test - public void testGetTntId_When_TntIDUnavailable() throws Exception { - // setup - String serverResponse = "{\n" + - " \"id\": {\n" + - " \"nottntID\": \"tntIDValue\"\n" + - " }\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - String actualTntID = responseParser.getTntId(jsonObject); - - // verify - assertEquals("",actualTntID); - } - - @Test - public void testGetTntId_When_InvalidServerJSONResponse() throws Exception { - // setup - String serverResponse = "{\n" + - " \"id\": \"nonJSON\"\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - String actualTntID = responseParser.getTntId(jsonObject); - - // verify - assertNull(actualTntID); - } - - - // =================================== - // Test getEdgeHost - // =================================== - @Test - public void testGetEdgeHost_Happy() throws Exception { - // setup - String serverResponse = "{\n" + - " \"edgeHost\": \"superHost\"\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - String edgeHost = responseParser.getEdgeHost(jsonObject); - - // verify - assertEquals("superHost", edgeHost); - } - - @Test - public void testGetEdgeHost_When_EdgeHostUnavailable() throws Exception { - // setup - String serverResponse = "{\n" + - " \"notedgeHost\": \"superHost\"\n" + - "}"; - JSONObject jsonObject = new JSONObject(serverResponse); - - // test - String edgeHost = responseParser.getEdgeHost(jsonObject); - - // verify - assertEquals("", edgeHost); - } - - - // =================================== - // Test GetErrorMessage - // =================================== - @Test - public void testGetErrorMessage_Happy() throws Exception { - // setup - String errorString = "{\n" + - " \"message\" : \"Error message\",\n" + - "}"; - JSONObject jsonObject = new JSONObject(errorString); - // test - String errorMessage = responseParser.getErrorMessage(jsonObject); - - // verify - assertEquals(1, jsonObject.length()); - assertEquals("Error message", errorMessage); - } - - @Test - public void testGetErrorMessage_EmptyJSON() throws Exception { - // setup - JSONObject jsonObject = new JSONObject(); - - // test - String errorMessage = responseParser.getErrorMessage(jsonObject); - - // verify - assertNull(errorMessage); - } - - @Test - public void testGetErrorMessage_nullJson() throws Exception { - // setup - - JSONObject jsonObject = null; - - // test - String errorMessage = responseParser.getErrorMessage(jsonObject); - - // verify - assertNull(errorMessage); - } - - // =================================== - // Test extractMboxContent - // =================================== - @Test - public void testExtractMboxContent_Happy() throws Exception { - // setup - String serverResponse = "{\n" + - " \"index\" : \"1\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"AAA\" , \n" + - " \"type\" : \"html\"" + - " }]\n" + - "}"; - // test - JSONObject jsonObject = new JSONObject(serverResponse); - String extractMboxContent = responseParser.extractMboxContent(jsonObject); - // verify - assertNotNull(extractMboxContent); - assertEquals("AAA", extractMboxContent); - } - - @Test - public void testExtractMboxContent_JsonArrayContent() throws Exception { - // setup - String serverResponse = "{\n" + - " \"index\" : \"1\" , \n" + - " \"options\" : [{\n" + - " \"content\" : [\"one\", \"two\", \"three\"] , \n" + - " \"type\" : \"json\"" + - " }]\n" + - "}"; - // test - JSONObject jsonObject = new JSONObject(serverResponse); - String extractMboxContent = responseParser.extractMboxContent(jsonObject); - // verify - assertNotNull(extractMboxContent); - assertEquals("[\"one\",\"two\",\"three\"]", extractMboxContent); - } - - @Test - public void testExtractMboxContent_MixedJsonArrayContent() throws Exception { - // setup - String serverResponse = "{\n" + - " \"index\" : \"1\" , \n" + - " \"options\" : [{\n" + - " \"content\" : [[\"one\", 1], true, 23] , \n" + - " \"type\" : \"json\"" + - " }]\n" + - "}"; - // test - JSONObject jsonObject = new JSONObject(serverResponse); - String extractMboxContent = responseParser.extractMboxContent(jsonObject); - // verify - assertNotNull(extractMboxContent); - assertEquals("[[\"one\",1],true,23]", extractMboxContent); - } - - @Test - public void testExtractMboxContentHappy_For_StringContent() throws Exception { - // setup - String serverResponse = "{\n" + - " \"index\" : \"1\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"AAA\" , \n" + - " \"type\" : \"html\"" + - " }]\n" + - "}"; - // test - JSONObject jsonObject = new JSONObject(serverResponse); - String extractMboxContent = responseParser.extractMboxContent(jsonObject); - assertEquals("AAA", extractMboxContent); - } - - @Test - public void testExtractMboxContentHappy_For_JsonContent() throws Exception { // setup - String serverResponse = "{\n" + - " \"index\" : \"1\" , \n" + - " \"options\" : [{\n" + - " \"content\" : {\"key\": \"value\"} , \n" + - " \"type\" : \"json\"" + - " }]\n" + - "}"; - // test - JSONObject jsonObject = new JSONObject(serverResponse); - String extractMboxContent = responseParser.extractMboxContent(jsonObject); - assertEquals("{\"key\":\"value\"}", extractMboxContent); - } - - @Test - public void testExtractMboxContent_When_NoMboxContentKeys() throws Exception { - // setup - String serverResponse = "{\n" + - " \"index\" : \"1\" , \n" + - " \"options\" : [{\n" + - " }]\n" + - "}"; - // test - JSONObject jsonObject = new JSONObject(serverResponse); - String extractMboxContent = responseParser.extractMboxContent(jsonObject); - assertEquals("", extractMboxContent); - } - - @Test - public void testExtractMboxContent_Will_ReturnEmpty_When_ExtractMboxContentInvalidType() throws Exception { - // setup - String serverResponse = "{\n" + - " \"index\" : \"1\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"\"" + - " }]\n" + - "}"; - // test - JSONObject jsonObject = new JSONObject(serverResponse); - String extractMboxContent = responseParser.extractMboxContent(jsonObject); - assertEquals("", extractMboxContent); - } - - // =================================== - // Test extract A4T Params - // =================================== - - @Test - public void testExtractA4TParams_Will_Return_Valid_Map_When_Analytics_Payload_Is_Present() throws JSONException { - //setup - final String mboxPayload = "{\n" + - " \"index\":0,\n" + - " \"name\":\"ryan_a4t2\",\n" + - " \"options\":[\n" + - " {\n" + - " \"content\":{\n" + - " \"key2\":\"value2\"\n" + - " },\n" + - " \"type\":\"json\",\n" + - " \"responseTokens\":{\n" + - " \"geo.connectionSpeed\":\"broadband\",\n" + - " \"geo.state\":\"california\",\n" + - " },\n" + - " \"sourceType\":\"target\"\n" + - " }\n" + - " ],\n" + - " \"analytics\":{\n" + - " \"payload\":{\n" + - " \"pe\":\"tnt\",\n" + - " \"tnta\":\"333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12\"\n" + - " }\n" + - " }\n" + - "}"; - - final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); - - //Assertions - Map a4tParams = responseParser.getAnalyticsForTargetPayload(mBoxPayloadObject); - - assertNotNull(a4tParams); - assertEquals(2, a4tParams.size()); - - assertEquals("tnt", a4tParams.get("pe")); - assertEquals("333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12", a4tParams.get("tnta")); - } - - @Test - public void testExtractA4TParams_Will_Return_Null_When_Analytics_Payload_Is_Missing() throws JSONException { - //setup - final String mboxPayload = "{\n" + - " \"index\":0,\n" + - " \"name\":\"ryan_a4t2\",\n" + - " \"options\":[\n" + - " {\n" + - " \"content\":{\n" + - " \"key2\":\"value2\"\n" + - " },\n" + - " \"type\":\"json\",\n" + - " \"responseTokens\":{\n" + - " \"geo.connectionSpeed\":\"broadband\",\n" + - " \"geo.state\":\"california\",\n" + - " },\n" + - " \"sourceType\":\"target\"\n" + - " }\n" + - " ]\n" + - "}"; - - final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); - - //Assertions - Map a4tParams = responseParser.getAnalyticsForTargetPayload(mBoxPayloadObject); - assertNull(a4tParams); - } - - // =================================== - // Test extract Response Tokens - // =================================== - - @Test - public void testExtractResponseTokens_Will_Return_Valid_Map_When_Response_Tokens_Payload_Is_Present() throws JSONException { - //setup - final String mboxPayload = "{\n" + - " \"index\":0,\n" + - " \"name\":\"ryan_a4t2\",\n" + - " \"options\":[\n" + - " {\n" + - " \"content\":{\n" + - " \"key2\":\"value2\"\n" + - " },\n" + - " \"type\":\"json\",\n" + - " \"responseTokens\":{\n" + - " \"geo.connectionSpeed\":\"broadband\",\n" + - " \"geo.state\":\"california\",\n" + - " \"profile.categoryAffinities\":[\"shoes\"],\n" + - " },\n" + - " \"sourceType\":\"target\"\n" + - " }\n" + - " ],\n" + - " \"analytics\":{\n" + - " \"payload\":{\n" + - " \"pe\":\"tnt\",\n" + - " \"tnta\":\"333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12\"\n" + - " }\n" + - " }\n" + - "}"; - - final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); - - //Assertions - Map responseTokens = responseParser.getResponseTokens(mBoxPayloadObject); - - assertNotNull(responseTokens); - assertEquals(3, responseTokens.size()); - assertEquals("broadband", responseTokens.get("geo.connectionSpeed")); - assertEquals("california", responseTokens.get("geo.state")); - assertEquals(new ArrayList(Arrays.asList("shoes")), responseTokens.get("profile.categoryAffinities")); - } - - @Test - public void testExtractResponseTokens_Will_Return_Null_When_response_Tokens_Payload_Is_Missing() throws JSONException { - //setup - final String mboxPayload = "{\n" + - " \"index\":0,\n" + - " \"name\":\"ryan_a4t2\",\n" + - " \"options\":[\n" + - " {\n" + - " \"content\":{\n" + - " \"key2\":\"value2\"\n" + - " },\n" + - " \"type\":\"json\",\n" + - " \"sourceType\":\"target\"\n" + - " }\n" + - " ],\n" + - " \"analytics\":{\n" + - " \"payload\":{\n" + - " \"pe\":\"tnt\",\n" + - " \"tnta\":\"333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12\"\n" + - " }\n" + - " }\n" + - "}"; - - final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); - - //Assertions - Map responseTokens = responseParser.getResponseTokens(mBoxPayloadObject); - assertNull(responseTokens); - } - - @Test - public void testExtractResponseTokens_Will_Return_Null_When_Mbox_Payload_Is_Null() throws JSONException { - // setup - final JSONObject mBoxPayloadObject = null; - - // test - Map responseTokens = responseParser.getResponseTokens(mBoxPayloadObject); - - // verify - assertNull(responseTokens); - } - - @Test - public void testExtractResponseTokens_Will_Return_Null_When_Response_Tokens_Payload_Is_Invalid() throws JSONException { - try (MockedStatic jsonUtilsMock = Mockito.mockStatic(JSONUtils.class)) { - // setup - jsonUtilsMock.when(() -> JSONUtils.toMap(Mockito.any())) - .thenThrow(new JSONException("Invalid JSON")); - - final String mboxPayload = "{\n" + - " \"index\":0,\n" + - " \"name\":\"ryan_a4t2\",\n" + - " \"options\":[\n" + - " {\n" + - " \"content\":{\n" + - " \"key2\":\"value2\"\n" + - " },\n" + - " \"type\":\"json\",\n" + - " \"responseTokens\":{\n" + - " \"geo.connectionSpeed\":\"broadband\"\n" + - " },\n" + - " \"sourceType\":\"target\"\n" + - " }\n" + - " ],\n" + - " \"analytics\":{\n" + - " \"payload\":{\n" + - " \"pe\":\"tnt\",\n" + - " \"tnta\":\"333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12\"\n" + - " }\n" + - " }\n" + - "}"; - - final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); - - // test - Map responseTokens = responseParser.getResponseTokens(mBoxPayloadObject); - - // verify - assertNull(responseTokens); - } - } - - // ===================================== - // Test extract Click Metric A4T Params - // ===================================== - - @Test - public void testExtractClickMetricAnalyticsPayload_Will_Return_Valid_Map_When_Analytics_Payload_Is_Present() throws JSONException { - //setup - final String mboxPayload = "{\n" + - " \"index\":0,\n" + - " \"name\":\"ryan_a4t2\",\n" + - " \"options\":[\n" + - " {\n" + - " \"content\":{\n" + - " \"key2\":\"value2\"\n" + - " },\n" + - " \"type\":\"json\",\n" + - " \"sourceType\":\"target\"\n" + - " }\n" + - " ],\n" + - "\"metrics\":[\n" + - " {\n" + - " \"type\":\"click\",\n" + - " \"eventToken\":\"ABPi/uih7s0vo6/8kqyxjA==\",\n" + - " \"analytics\":{\n" + - " \"payload\":{\n" + - " \"pe\":\"tnt\",\n" + - " \"tnta\":\"409277:0:0|32767\"\n" + - " }\n" + - " }\n" + - " }\n" + - " ]," + - " \"analytics\":{\n" + - " \"payload\":{\n" + - " \"pe\":\"tnt\",\n" + - " \"tnta\":\"333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12\"\n" + - " }\n" + - " }\n" + - "}"; - - final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); - - //Assertions - Map clickMetricsA4TParams = responseParser.extractClickMetricAnalyticsPayload(mBoxPayloadObject); - - assertNotNull(clickMetricsA4TParams); - assertEquals(2, clickMetricsA4TParams.size()); - - assertEquals("tnt", clickMetricsA4TParams.get("pe")); - assertEquals("409277:0:0|32767", clickMetricsA4TParams.get("tnta")); - } - - @Test - public void tesExtractClickMetricAnalyticsPayload_Will_Return_Null_When_Analytics_Payload_Is_Missing() throws JSONException { - //setup - final String mboxPayload = "{\n" + - " \"index\":0,\n" + - " \"name\":\"ryan_a4t2\",\n" + - " \"options\":[\n" + - " {\n" + - " \"content\":{\n" + - " \"key2\":\"value2\"\n" + - " },\n" + - " \"type\":\"json\",\n" + - " \"responseTokens\":{\n" + - " \"geo.connectionSpeed\":\"broadband\",\n" + - " \"geo.state\":\"california\",\n" + - " },\n" + - " \"sourceType\":\"target\"\n" + - " }\n" + - " ]\n" + - "}"; - - final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); - - //Assertions - Map clickMetricsA4TParams = responseParser.extractClickMetricAnalyticsPayload(mBoxPayloadObject); - assertNull(clickMetricsA4TParams); - } - - @Test - public void testExtractClickMetricAnalyticsPayload_Will_Return_Null_When_EventTokenIsMissing() throws JSONException { - //setup - final String mboxPayload = "{\n" + - " \"index\":0,\n" + - " \"name\":\"ryan_a4t2\",\n" + - " \"options\":[\n" + - " {\n" + - " \"content\":{\n" + - " \"key2\":\"value2\"\n" + - " },\n" + - " \"type\":\"json\",\n" + - " \"sourceType\":\"target\"\n" + - " }\n" + - " ],\n" + - "\"metrics\":[\n" + - " {\n" + - " \"type\":\"click\",\n" + - " \"analytics\":{\n" + - " \"payload\":{\n" + - " \"pe\":\"tnt\",\n" + - " \"tnta\":\"409277:0:0|32767\"\n" + - " }\n" + - " }\n" + - " }\n" + - " ]," + - " \"analytics\":{\n" + - " \"payload\":{\n" + - " \"pe\":\"tnt\",\n" + - " \"tnta\":\"333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12\"\n" + - " }\n" + - " }\n" + - "}"; - - final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); - - //Assertions - Map clickMetricsA4TParams = responseParser.extractClickMetricAnalyticsPayload(mBoxPayloadObject); - assertNull(clickMetricsA4TParams); - } - - @Test - public void test_preprocessAnalyticsForTargetPayload_Should_Return_Correctly_Formatted_Map() { - //Setup - final String pe = "tnt"; - final String tnta = "333911:0:0:0|32767"; - final String sessionId = "fake_sessionId"; - Map a4tParams = new HashMap() { - { - put("pe", pe); - put("tnta", tnta); - } - }; - - //Action - Map processedMap = responseParser.preprocessAnalyticsForTargetPayload(a4tParams, sessionId); - - //Assert - assertEquals(3, processedMap.size()); - assertEquals("tnt", processedMap.get("&&pe")); - assertEquals("333911:0:0:0|32767", processedMap.get("&&tnta")); - assertEquals(sessionId, processedMap.get(TargetTestConstants.EventDataKeys.A4T_SESSION_ID)); - } - - @Test - public void test_preprocessAnalyticsForTargetPayload_Should_Return_Null() { - //Setup - final String sessionId = "fake_sessionId"; - - //Action - Map processedMap = responseParser.preprocessAnalyticsForTargetPayload(null, sessionId); - - //Assert - assertNull(processedMap); - } - - @Test - public void test_getClickMetric_ShouldReturn_ClickMetricObject() throws JSONException { - final String mboxJsonString = "{\n" + - " \"index\":0,\n" + - " \"name\":\"ryan_a4t2\",\n" + - " \"options\":[\n" + - " {\n" + - " \"content\":{\n" + - " \"key2\":\"value2\"\n" + - " },\n" + - " \"type\":\"json\",\n" + - " \"responseTokens\":{\n" + - " \"activity.name\":\"ryan json offer a4t test 2\"\n" + - " },\n" + - " \"sourceType\":\"target\"\n" + - " }\n" + - " ],\n" + - " \"metrics\":[\n" + - " {\n" + - " \"type\":\"click\",\n" + - " \"eventToken\":\"1iqiEBgD3uMVv+V1rBrSug==\",\n" + - " \"analytics\":{\n" + - " \"payload\":{\n" + - " \"pe\":\"tnt\",\n" + - " \"tnta\":\"333911:0:0:0|32767\"\n" + - " }\n" + - " }\n" + - " }\n" + - " ],\n" + - " \"analytics\":{\n" + - " \"payload\":{\n" + - " \"pe\":\"tnt\",\n" + - " \"tnta\":\"333911:0:0:0|2\"\n" + - " }\n" + - " }\n" + - " }"; - - JSONObject mboxJson = new JSONObject(mboxJsonString); - JSONObject clickMetric = responseParser.getClickMetric(mboxJson); - assertNotNull(clickMetric); - assertEquals("click", clickMetric.getString("type")); - assertEquals("1iqiEBgD3uMVv+V1rBrSug==", clickMetric.getString("eventToken")); - assertEquals("tnt", clickMetric.getJSONObject("analytics").getJSONObject("payload").getString("pe")); - assertEquals("333911:0:0:0|32767", clickMetric.getJSONObject("analytics").getJSONObject("payload").getString("tnta")); - } - - @Test - public void test_getClickMetric_ShouldReturnNull_WhenClickMetricIsMissing() throws JSONException { - final String mboxJsonString = "{\n" + - " \"index\":0,\n" + - " \"name\":\"ryan_a4t2\",\n" + - " \"options\":[\n" + - " {\n" + - " \"content\":{\n" + - " \"key2\":\"value2\"\n" + - " },\n" + - " \"type\":\"json\",\n" + - " \"responseTokens\":{\n" + - " \"activity.name\":\"ryan json offer a4t test 2\"\n" + - " },\n" + - " \"sourceType\":\"target\"\n" + - " }\n" + - " ],\n" + - " \"metrics\":[\n" + - " {\n" + - " \"type\":\"display\",\n" + - " \"eventToken\":\"1iqiEBgD3uMVv+V1rBrSug==\"\n" + - " }\n" + - " ],\n" + - " \"analytics\":{\n" + - " \"payload\":{\n" + - " \"pe\":\"tnt\",\n" + - " \"tnta\":\"333911:0:0:0|2\"\n" + - " }\n" + - " }\n" + - " }"; - - JSONObject mboxJson = new JSONObject(mboxJsonString); - JSONObject clickMetric = responseParser.getClickMetric(mboxJson); - assertNull(clickMetric); - } - - @Test - public void test_getClickMetric_ShouldReturnNull_WhenEventTokenIsMissing() throws JSONException { - final String mboxJsonString = "{\n" + - " \"index\":0,\n" + - " \"name\":\"ryan_a4t2\",\n" + - " \"options\":[\n" + - " {\n" + - " \"content\":{\n" + - " \"key2\":\"value2\"\n" + - " },\n" + - " \"type\":\"json\",\n" + - " \"responseTokens\":{\n" + - " \"activity.name\":\"ryan json offer a4t test 2\"\n" + - " },\n" + - " \"sourceType\":\"target\"\n" + - " }\n" + - " ],\n" + - " \"metrics\":[\n" + - " {\n" + - " \"type\":\"click\",\n" + - " \"analytics\":{\n" + - " \"payload\":{\n" + - " \"pe\":\"tnt\",\n" + - " \"tnta\":\"333911:0:0:0|32767\"\n" + - " }\n" + - " }\n" + - " }\n" + - " ],\n" + - " \"analytics\":{\n" + - " \"payload\":{\n" + - " \"pe\":\"tnt\",\n" + - " \"tnta\":\"333911:0:0:0|2\"\n" + - " }\n" + - " }\n" + - " }"; - - JSONObject mboxJson = new JSONObject(mboxJsonString); - JSONObject clickMetric = responseParser.getClickMetric(mboxJson); - assertNull(clickMetric); - } -} \ No newline at end of file + @Test + public void testParseResponseToJson_When_ConnectionNull() { + // test + assertNull(responseParser.parseResponseToJson(null)); + } + + // =================================== + // Test ExtractPrefetchedMboxes + // =================================== + @Test + public void testExtractPrefetchedMboxes_Happy() throws Exception { + // setup + String serverResponse = + "{\n" + + " \"prefetch\" : {\n" + + " \"mboxes\" : [{\n" + + " \"name\" : \"mboxName\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"myContent\"" + + " }]\n" + + " }]\n" + + " }\n" + + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map prefetchedMboxes = + responseParser.extractPrefetchedMboxes(jsonObject); + + // verify + assertEquals(1, prefetchedMboxes.size()); + assertEquals("mboxName", prefetchedMboxes.get("mboxName").getString("name")); + assertEquals( + "myContent", + prefetchedMboxes + .get("mboxName") + .getJSONArray("options") + .getJSONObject(0) + .getString("content")); + } + + @Test + public void testExtractPrefetchedMboxes_When_NoPrefetchMboxKeys() throws Exception { + // setup + String serverResponse = + "{\n" + + " \"noprefetch\" : {\n" + + " \"mboxes\" : [{\n" + + " \"name\" : \"mboxName\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"myContent\"" + + " }]\n" + + " }]\n" + + " }\n" + + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map prefetchedMboxes = + responseParser.extractPrefetchedMboxes(jsonObject); + + // verify + assertNull(prefetchedMboxes); + } + + @Test + public void testExtractPrefetchedMboxes_Will_ReturnNull_When_PrefetchMboxInvalidType() + throws Exception { + // setup + String serverResponse = "{\n" + " \"prefetch\": \"ItsAString\"\n" + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map prefetchedMboxes = + responseParser.extractPrefetchedMboxes(jsonObject); + + // verify + assertNull(prefetchedMboxes); + } + + @Test + public void + testExtractPrefetchedMboxes_Will_ReturnEmptyMap_When_PrefetchResponseContainsOneItemWithEmptyMbox() + throws Exception { + // setup + String serverResponse = + "{\n" + + " \"prefetch\" : {\n" + + " \"mboxes\" : [{\n" + + " \"name\" : \"\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"myContent\"" + + " }]\n" + + " }]\n" + + " }\n" + + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map prefetchedMboxes = + responseParser.extractPrefetchedMboxes(jsonObject); + + // verify + assertEquals(0, prefetchedMboxes.size()); + } + + @Test + public void testExtractPrefetchedMboxes_Will_IgnoreUnwantedKeys() throws Exception { + // setup + String serverResponse = + "{\n" + + " \"prefetch\" : {\n" + + " \"mboxes\" : [{\n" + + " \"name\" : \"mboxName\" , \n" + + " \"unwantedKey\" : \"someValue\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"myContent\"" + + " }]\n" + + " }]\n" + + " }\n" + + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map prefetchedMboxes = + responseParser.extractPrefetchedMboxes(jsonObject); + // verify + assertEquals(1, prefetchedMboxes.size()); + assertEquals(2, prefetchedMboxes.get("mboxName").length()); + assertEquals("mboxName", prefetchedMboxes.get("mboxName").getString("name")); + assertEquals( + "myContent", + prefetchedMboxes + .get("mboxName") + .getJSONArray("options") + .getJSONObject(0) + .getString("content")); + } + + // =================================== + // Test ExtractBatchedMBoxes + // =================================== + + @Test + public void testExtractBatchedMBoxes_Happy() throws Exception { + // setup + String serverResponse = + "{\n" + + " \"execute\": {\n" + + " \"mboxes\": [\n" + + " {\n" + + " \"name\": \"mboxName\",\n" + + " \"index\": 0,\n" + + " }]\n" + + " }\n" + + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map batchedMBoxes = responseParser.extractBatchedMBoxes(jsonObject); + + // verify + assertEquals(1, batchedMBoxes.size()); + assertEquals("mboxName", batchedMBoxes.get("mboxName").getString("name")); + assertEquals(0, batchedMBoxes.get("mboxName").getInt("index")); + } + + @Test + public void testExtractBatchedMBoxes_When_NoMboxKey() throws Exception { + // setup + String serverResponse = + "{\n" + + " \"execute\": {\n" + + " \"nomboxesResponse\": [\n" + + " {\n" + + " \"name\": \"mboxName\",\n" + + " \"index\": 0,\n" + + " }]\n" + + " }\n" + + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map batchedMBoxes = responseParser.extractBatchedMBoxes(jsonObject); + + // verify + assertNull(batchedMBoxes); + } + + @Test + public void testExtractBatchedMBoxes_Will_ReturnNull_When_MboxResponseInvalidType() + throws Exception { + // setup + String serverResponse = + "{\n" + " \"execute\": {\n" + " \"mboxes\": \"ItsAString\"" + " }\n" + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map batchedMBoxes = responseParser.extractBatchedMBoxes(jsonObject); + + // verify + assertNull(batchedMBoxes); + } + + @Test + public void + testExtractBatchedMBoxes_Will_ReturnEmptyMap_When_MboxResponseContainsOneItemWithEmptyMbox() + throws Exception { + // setup + String serverResponse = + "{\n" + + " \"execute\": {\n" + + " \"mboxes\": [\n" + + " {\n" + + " \"name\": \"\",\n" + + " \"index\": 0,\n" + + " }]\n" + + " }\n" + + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map batchedMBoxes = responseParser.extractBatchedMBoxes(jsonObject); + + // verify + assertEquals(0, batchedMBoxes.size()); + } + + @Test + public void testExtractBatchedMBoxes_InvalidMboxResponse() throws Exception { + // setup + String serverResponse = "{\n" + " \"execute\" : [2]\n" + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map batchedMBoxes = responseParser.extractBatchedMBoxes(jsonObject); + + // verify + assertNull(batchedMBoxes); + } + + // =================================== + // Test GetAnalyticsForTargetPayload + // =================================== + @Test + public void testGetAnalyticsForTargetPayload_Happy() throws Exception { + // setup + String serverResponse = + "{\n" + + " \"analytics\" : {\n" + + " \"payload\" : {\n" + + " \"key1\" : \"value1\" , \n" + + " \"key2\" : \"value2\" \n" + + " }\n" + + " }\n" + + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map a4tPayloadMap = + responseParser.getAnalyticsForTargetPayload(jsonObject, FAKE_SESSION_ID); + + // verify + assertEquals(3, a4tPayloadMap.size()); + assertEquals("value1", a4tPayloadMap.get("&&key1")); + assertEquals("value2", a4tPayloadMap.get("&&key2")); + assertTrue(a4tPayloadMap.containsKey(TargetTestConstants.EventDataKeys.A4T_SESSION_ID)); + assertEquals( + a4tPayloadMap.get(TargetTestConstants.EventDataKeys.A4T_SESSION_ID), + FAKE_SESSION_ID); + } + + @Test + public void testGetAnalyticsForTargetPayload_Happy_With_Null_Session_Id() throws Exception { + // setup + String serverResponse = + "{\n" + + " \"analytics\" : {\n" + + " \"payload\" : {\n" + + " \"key1\" : \"value1\" , \n" + + " \"key2\" : \"value2\" \n" + + " }\n" + + " }\n" + + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map a4tPayloadMap = + responseParser.getAnalyticsForTargetPayload(jsonObject, null); + + // verify + assertEquals(2, a4tPayloadMap.size()); + assertEquals("value1", a4tPayloadMap.get("&&key1")); + assertEquals("value2", a4tPayloadMap.get("&&key2")); + assertFalse(a4tPayloadMap.containsKey(TargetTestConstants.EventDataKeys.SESSION_ID)); + } + + @Test + public void testGetAnalyticsForTargetPayload_Happy_With_Empty_Session_Id() throws Exception { + // setup + String serverResponse = + "{\n" + + " \"analytics\" : {\n" + + " \"payload\" : {\n" + + " \"key1\" : \"value1\" , \n" + + " \"key2\" : \"value2\" \n" + + " }\n" + + " }\n" + + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map a4tPayloadMap = + responseParser.getAnalyticsForTargetPayload(jsonObject, ""); + + // verify + assertEquals(2, a4tPayloadMap.size()); + assertEquals("value1", a4tPayloadMap.get("&&key1")); + assertEquals("value2", a4tPayloadMap.get("&&key2")); + assertFalse(a4tPayloadMap.containsKey(TargetTestConstants.EventDataKeys.SESSION_ID)); + } + + @Test + public void testGetAnalyticsForTargetPayload_A4TPayloadEmpty() throws Exception { + // setup + String serverResponse = "{\n" + " \"analytics\" : {} }"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map a4tPayloadMap = + responseParser.getAnalyticsForTargetPayload(jsonObject, FAKE_SESSION_ID); + + // verify + assertNull(a4tPayloadMap); + } + + @Test + public void testGetAnalyticsForTargetPayload_A4TPayloadIsAInvalidType() throws Exception { + // setup + String serverResponse = "{\n" + " \"analytics\" : \"ShouldNotBeAString\" }"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map a4tPayloadMap = + responseParser.getAnalyticsForTargetPayload(jsonObject, FAKE_SESSION_ID); + + // verify + assertNull(a4tPayloadMap); + } + + @Test + public void testGetAnalyticsForTargetPayload_EmptyJSON() throws Exception { + // setup + String serverResponse = "{}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + Map a4tPayloadMap = + responseParser.getAnalyticsForTargetPayload(jsonObject, FAKE_SESSION_ID); + + // verify + assertNull(a4tPayloadMap); + } + + // =================================== + // Test getTntId + // =================================== + @Test + public void testGetTntId_Happy() throws Exception { + // setup + String serverResponse = + "{\n" + " \"id\": {\n" + " \"tntId\": \"tntIDValue\"\n" + " }\n" + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + String actualTntID = responseParser.getTntId(jsonObject); + + // verify + assertEquals("tntIDValue", actualTntID); + } + + @Test + public void testGetTntId_When_TntIDUnavailable() throws Exception { + // setup + String serverResponse = + "{\n" + " \"id\": {\n" + " \"nottntID\": \"tntIDValue\"\n" + " }\n" + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + String actualTntID = responseParser.getTntId(jsonObject); + + // verify + assertEquals("", actualTntID); + } + + @Test + public void testGetTntId_When_InvalidServerJSONResponse() throws Exception { + // setup + String serverResponse = "{\n" + " \"id\": \"nonJSON\"\n" + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + String actualTntID = responseParser.getTntId(jsonObject); + + // verify + assertNull(actualTntID); + } + + // =================================== + // Test getEdgeHost + // =================================== + @Test + public void testGetEdgeHost_Happy() throws Exception { + // setup + String serverResponse = "{\n" + " \"edgeHost\": \"superHost\"\n" + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + String edgeHost = responseParser.getEdgeHost(jsonObject); + + // verify + assertEquals("superHost", edgeHost); + } + + @Test + public void testGetEdgeHost_When_EdgeHostUnavailable() throws Exception { + // setup + String serverResponse = "{\n" + " \"notedgeHost\": \"superHost\"\n" + "}"; + JSONObject jsonObject = new JSONObject(serverResponse); + + // test + String edgeHost = responseParser.getEdgeHost(jsonObject); + + // verify + assertEquals("", edgeHost); + } + + // =================================== + // Test GetErrorMessage + // =================================== + @Test + public void testGetErrorMessage_Happy() throws Exception { + // setup + String errorString = "{\n" + " \"message\" : \"Error message\",\n" + "}"; + JSONObject jsonObject = new JSONObject(errorString); + // test + String errorMessage = responseParser.getErrorMessage(jsonObject); + + // verify + assertEquals(1, jsonObject.length()); + assertEquals("Error message", errorMessage); + } + + @Test + public void testGetErrorMessage_EmptyJSON() throws Exception { + // setup + JSONObject jsonObject = new JSONObject(); + + // test + String errorMessage = responseParser.getErrorMessage(jsonObject); + + // verify + assertNull(errorMessage); + } + + @Test + public void testGetErrorMessage_nullJson() throws Exception { + // setup + + JSONObject jsonObject = null; + + // test + String errorMessage = responseParser.getErrorMessage(jsonObject); + + // verify + assertNull(errorMessage); + } + + // =================================== + // Test extractMboxContent + // =================================== + @Test + public void testExtractMboxContent_Happy() throws Exception { + // setup + String serverResponse = + "{\n" + + " \"index\" : \"1\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"AAA\" , \n" + + " \"type\" : \"html\"" + + " }]\n" + + "}"; + // test + JSONObject jsonObject = new JSONObject(serverResponse); + String extractMboxContent = responseParser.extractMboxContent(jsonObject); + // verify + assertNotNull(extractMboxContent); + assertEquals("AAA", extractMboxContent); + } + + @Test + public void testExtractMboxContent_JsonArrayContent() throws Exception { + // setup + String serverResponse = + "{\n" + + " \"index\" : \"1\" , \n" + + " \"options\" : [{\n" + + " \"content\" : [\"one\", \"two\", \"three\"] , \n" + + " \"type\" : \"json\"" + + " }]\n" + + "}"; + // test + JSONObject jsonObject = new JSONObject(serverResponse); + String extractMboxContent = responseParser.extractMboxContent(jsonObject); + // verify + assertNotNull(extractMboxContent); + assertEquals("[\"one\",\"two\",\"three\"]", extractMboxContent); + } + + @Test + public void testExtractMboxContent_MixedJsonArrayContent() throws Exception { + // setup + String serverResponse = + "{\n" + + " \"index\" : \"1\" , \n" + + " \"options\" : [{\n" + + " \"content\" : [[\"one\", 1], true, 23] , \n" + + " \"type\" : \"json\"" + + " }]\n" + + "}"; + // test + JSONObject jsonObject = new JSONObject(serverResponse); + String extractMboxContent = responseParser.extractMboxContent(jsonObject); + // verify + assertNotNull(extractMboxContent); + assertEquals("[[\"one\",1],true,23]", extractMboxContent); + } + + @Test + public void testExtractMboxContentHappy_For_StringContent() throws Exception { + // setup + String serverResponse = + "{\n" + + " \"index\" : \"1\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"AAA\" , \n" + + " \"type\" : \"html\"" + + " }]\n" + + "}"; + // test + JSONObject jsonObject = new JSONObject(serverResponse); + String extractMboxContent = responseParser.extractMboxContent(jsonObject); + assertEquals("AAA", extractMboxContent); + } + + @Test + public void testExtractMboxContentHappy_For_JsonContent() throws Exception { // setup + String serverResponse = + "{\n" + + " \"index\" : \"1\" , \n" + + " \"options\" : [{\n" + + " \"content\" : {\"key\": \"value\"} , \n" + + " \"type\" : \"json\"" + + " }]\n" + + "}"; + // test + JSONObject jsonObject = new JSONObject(serverResponse); + String extractMboxContent = responseParser.extractMboxContent(jsonObject); + assertEquals("{\"key\":\"value\"}", extractMboxContent); + } + + @Test + public void testExtractMboxContent_When_NoMboxContentKeys() throws Exception { + // setup + String serverResponse = + "{\n" + " \"index\" : \"1\" , \n" + " \"options\" : [{\n" + " }]\n" + "}"; + // test + JSONObject jsonObject = new JSONObject(serverResponse); + String extractMboxContent = responseParser.extractMboxContent(jsonObject); + assertEquals("", extractMboxContent); + } + + @Test + public void testExtractMboxContent_Will_ReturnEmpty_When_ExtractMboxContentInvalidType() + throws Exception { + // setup + String serverResponse = + "{\n" + + " \"index\" : \"1\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"\"" + + " }]\n" + + "}"; + // test + JSONObject jsonObject = new JSONObject(serverResponse); + String extractMboxContent = responseParser.extractMboxContent(jsonObject); + assertEquals("", extractMboxContent); + } + + // =================================== + // Test extract A4T Params + // =================================== + + @Test + public void testExtractA4TParams_Will_Return_Valid_Map_When_Analytics_Payload_Is_Present() + throws JSONException { + // setup + final String mboxPayload = + "{\n" + + " \"index\":0,\n" + + " \"name\":\"ryan_a4t2\",\n" + + " \"options\":[\n" + + " {\n" + + " \"content\":{\n" + + " \"key2\":\"value2\"\n" + + " },\n" + + " \"type\":\"json\",\n" + + " \"responseTokens\":{\n" + + " \"geo.connectionSpeed\":\"broadband\",\n" + + " \"geo.state\":\"california\",\n" + + " },\n" + + " \"sourceType\":\"target\"\n" + + " }\n" + + " ],\n" + + " \"analytics\":{\n" + + " \"payload\":{\n" + + " \"pe\":\"tnt\",\n" + + " \"tnta\":\"333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12\"\n" + + " }\n" + + " }\n" + + "}"; + + final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); + + // Assertions + Map a4tParams = + responseParser.getAnalyticsForTargetPayload(mBoxPayloadObject); + + assertNotNull(a4tParams); + assertEquals(2, a4tParams.size()); + + assertEquals("tnt", a4tParams.get("pe")); + assertEquals("333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12", a4tParams.get("tnta")); + } + + @Test + public void testExtractA4TParams_Will_Return_Null_When_Analytics_Payload_Is_Missing() + throws JSONException { + // setup + final String mboxPayload = + "{\n" + + " \"index\":0,\n" + + " \"name\":\"ryan_a4t2\",\n" + + " \"options\":[\n" + + " {\n" + + " \"content\":{\n" + + " \"key2\":\"value2\"\n" + + " },\n" + + " \"type\":\"json\",\n" + + " \"responseTokens\":{\n" + + " \"geo.connectionSpeed\":\"broadband\",\n" + + " \"geo.state\":\"california\",\n" + + " },\n" + + " \"sourceType\":\"target\"\n" + + " }\n" + + " ]\n" + + "}"; + + final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); + + // Assertions + Map a4tParams = + responseParser.getAnalyticsForTargetPayload(mBoxPayloadObject); + assertNull(a4tParams); + } + + // =================================== + // Test extract Response Tokens + // =================================== + + @Test + public void + testExtractResponseTokens_Will_Return_Valid_Map_When_Response_Tokens_Payload_Is_Present() + throws JSONException { + // setup + final String mboxPayload = + "{\n" + + " \"index\":0,\n" + + " \"name\":\"ryan_a4t2\",\n" + + " \"options\":[\n" + + " {\n" + + " \"content\":{\n" + + " \"key2\":\"value2\"\n" + + " },\n" + + " \"type\":\"json\",\n" + + " \"responseTokens\":{\n" + + " \"geo.connectionSpeed\":\"broadband\",\n" + + " \"geo.state\":\"california\",\n" + + " \"profile.categoryAffinities\":[\"shoes\"],\n" + + " },\n" + + " \"sourceType\":\"target\"\n" + + " }\n" + + " ],\n" + + " \"analytics\":{\n" + + " \"payload\":{\n" + + " \"pe\":\"tnt\",\n" + + " \"tnta\":\"333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12\"\n" + + " }\n" + + " }\n" + + "}"; + + final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); + + // Assertions + Map responseTokens = responseParser.getResponseTokens(mBoxPayloadObject); + + assertNotNull(responseTokens); + assertEquals(3, responseTokens.size()); + assertEquals("broadband", responseTokens.get("geo.connectionSpeed")); + assertEquals("california", responseTokens.get("geo.state")); + assertEquals( + new ArrayList(Arrays.asList("shoes")), + responseTokens.get("profile.categoryAffinities")); + } + + @Test + public void testExtractResponseTokens_Will_Return_Null_When_response_Tokens_Payload_Is_Missing() + throws JSONException { + // setup + final String mboxPayload = + "{\n" + + " \"index\":0,\n" + + " \"name\":\"ryan_a4t2\",\n" + + " \"options\":[\n" + + " {\n" + + " \"content\":{\n" + + " \"key2\":\"value2\"\n" + + " },\n" + + " \"type\":\"json\",\n" + + " \"sourceType\":\"target\"\n" + + " }\n" + + " ],\n" + + " \"analytics\":{\n" + + " \"payload\":{\n" + + " \"pe\":\"tnt\",\n" + + " \"tnta\":\"333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12\"\n" + + " }\n" + + " }\n" + + "}"; + + final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); + + // Assertions + Map responseTokens = responseParser.getResponseTokens(mBoxPayloadObject); + assertNull(responseTokens); + } + + @Test + public void testExtractResponseTokens_Will_Return_Null_When_Mbox_Payload_Is_Null() + throws JSONException { + // setup + final JSONObject mBoxPayloadObject = null; + + // test + Map responseTokens = responseParser.getResponseTokens(mBoxPayloadObject); + + // verify + assertNull(responseTokens); + } + + @Test + public void testExtractResponseTokens_Will_Return_Null_When_Response_Tokens_Payload_Is_Invalid() + throws JSONException { + try (MockedStatic jsonUtilsMock = Mockito.mockStatic(JSONUtils.class)) { + // setup + jsonUtilsMock + .when(() -> JSONUtils.toMap(Mockito.any())) + .thenThrow(new JSONException("Invalid JSON")); + + final String mboxPayload = + "{\n" + + " \"index\":0,\n" + + " \"name\":\"ryan_a4t2\",\n" + + " \"options\":[\n" + + " {\n" + + " \"content\":{\n" + + " \"key2\":\"value2\"\n" + + " },\n" + + " \"type\":\"json\",\n" + + " \"responseTokens\":{\n" + + " \"geo.connectionSpeed\":\"broadband\"\n" + + " },\n" + + " \"sourceType\":\"target\"\n" + + " }\n" + + " ],\n" + + " \"analytics\":{\n" + + " \"payload\":{\n" + + " \"pe\":\"tnt\",\n" + + " \"tnta\":\"333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12\"\n" + + " }\n" + + " }\n" + + "}"; + + final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); + + // test + Map responseTokens = + responseParser.getResponseTokens(mBoxPayloadObject); + + // verify + assertNull(responseTokens); + } + } + + // ===================================== + // Test extract Click Metric A4T Params + // ===================================== + + @Test + public void + testExtractClickMetricAnalyticsPayload_Will_Return_Valid_Map_When_Analytics_Payload_Is_Present() + throws JSONException { + // setup + final String mboxPayload = + "{\n" + + " \"index\":0,\n" + + " \"name\":\"ryan_a4t2\",\n" + + " \"options\":[\n" + + " {\n" + + " \"content\":{\n" + + " \"key2\":\"value2\"\n" + + " },\n" + + " \"type\":\"json\",\n" + + " \"sourceType\":\"target\"\n" + + " }\n" + + " ],\n" + + "\"metrics\":[\n" + + " {\n" + + " \"type\":\"click\",\n" + + " \"eventToken\":\"ABPi/uih7s0vo6/8kqyxjA==\",\n" + + " \"analytics\":{\n" + + " \"payload\":{\n" + + " \"pe\":\"tnt\",\n" + + " \"tnta\":\"409277:0:0|32767\"\n" + + " }\n" + + " }\n" + + " }\n" + + " ]," + + " \"analytics\":{\n" + + " \"payload\":{\n" + + " \"pe\":\"tnt\",\n" + + " \"tnta\":\"333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12\"\n" + + " }\n" + + " }\n" + + "}"; + + final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); + + // Assertions + Map clickMetricsA4TParams = + responseParser.extractClickMetricAnalyticsPayload(mBoxPayloadObject); + + assertNotNull(clickMetricsA4TParams); + assertEquals(2, clickMetricsA4TParams.size()); + + assertEquals("tnt", clickMetricsA4TParams.get("pe")); + assertEquals("409277:0:0|32767", clickMetricsA4TParams.get("tnta")); + } + + @Test + public void + tesExtractClickMetricAnalyticsPayload_Will_Return_Null_When_Analytics_Payload_Is_Missing() + throws JSONException { + // setup + final String mboxPayload = + "{\n" + + " \"index\":0,\n" + + " \"name\":\"ryan_a4t2\",\n" + + " \"options\":[\n" + + " {\n" + + " \"content\":{\n" + + " \"key2\":\"value2\"\n" + + " },\n" + + " \"type\":\"json\",\n" + + " \"responseTokens\":{\n" + + " \"geo.connectionSpeed\":\"broadband\",\n" + + " \"geo.state\":\"california\",\n" + + " },\n" + + " \"sourceType\":\"target\"\n" + + " }\n" + + " ]\n" + + "}"; + + final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); + + // Assertions + Map clickMetricsA4TParams = + responseParser.extractClickMetricAnalyticsPayload(mBoxPayloadObject); + assertNull(clickMetricsA4TParams); + } + + @Test + public void testExtractClickMetricAnalyticsPayload_Will_Return_Null_When_EventTokenIsMissing() + throws JSONException { + // setup + final String mboxPayload = + "{\n" + + " \"index\":0,\n" + + " \"name\":\"ryan_a4t2\",\n" + + " \"options\":[\n" + + " {\n" + + " \"content\":{\n" + + " \"key2\":\"value2\"\n" + + " },\n" + + " \"type\":\"json\",\n" + + " \"sourceType\":\"target\"\n" + + " }\n" + + " ],\n" + + "\"metrics\":[\n" + + " {\n" + + " \"type\":\"click\",\n" + + " \"analytics\":{\n" + + " \"payload\":{\n" + + " \"pe\":\"tnt\",\n" + + " \"tnta\":\"409277:0:0|32767\"\n" + + " }\n" + + " }\n" + + " }\n" + + " ]," + + " \"analytics\":{\n" + + " \"payload\":{\n" + + " \"pe\":\"tnt\",\n" + + " \"tnta\":\"333911:0:0:0|2|4445.12,333911:0:0:0|1|4445.12\"\n" + + " }\n" + + " }\n" + + "}"; + + final JSONObject mBoxPayloadObject = new JSONObject(mboxPayload); + + // Assertions + Map clickMetricsA4TParams = + responseParser.extractClickMetricAnalyticsPayload(mBoxPayloadObject); + assertNull(clickMetricsA4TParams); + } + + @Test + public void test_preprocessAnalyticsForTargetPayload_Should_Return_Correctly_Formatted_Map() { + // Setup + final String pe = "tnt"; + final String tnta = "333911:0:0:0|32767"; + final String sessionId = "fake_sessionId"; + Map a4tParams = + new HashMap() { + { + put("pe", pe); + put("tnta", tnta); + } + }; + + // Action + Map processedMap = + responseParser.preprocessAnalyticsForTargetPayload(a4tParams, sessionId); + + // Assert + assertEquals(3, processedMap.size()); + assertEquals("tnt", processedMap.get("&&pe")); + assertEquals("333911:0:0:0|32767", processedMap.get("&&tnta")); + assertEquals(sessionId, processedMap.get(TargetTestConstants.EventDataKeys.A4T_SESSION_ID)); + } + + @Test + public void test_preprocessAnalyticsForTargetPayload_Should_Return_Null() { + // Setup + final String sessionId = "fake_sessionId"; + + // Action + Map processedMap = + responseParser.preprocessAnalyticsForTargetPayload(null, sessionId); + + // Assert + assertNull(processedMap); + } + + @Test + public void test_getClickMetric_ShouldReturn_ClickMetricObject() throws JSONException { + final String mboxJsonString = + "{\n" + + " \"index\":0,\n" + + " \"name\":\"ryan_a4t2\",\n" + + " \"options\":[\n" + + " {\n" + + " \"content\":{\n" + + " \"key2\":\"value2\"\n" + + " },\n" + + " \"type\":\"json\",\n" + + " \"responseTokens\":{\n" + + " \"activity.name\":\"ryan json offer a4t test 2\"\n" + + " },\n" + + " \"sourceType\":\"target\"\n" + + " }\n" + + " ],\n" + + " \"metrics\":[\n" + + " {\n" + + " \"type\":\"click\",\n" + + " \"eventToken\":\"1iqiEBgD3uMVv+V1rBrSug==\",\n" + + " \"analytics\":{\n" + + " \"payload\":{\n" + + " \"pe\":\"tnt\",\n" + + " \"tnta\":\"333911:0:0:0|32767\"\n" + + " }\n" + + " }\n" + + " }\n" + + " ],\n" + + " \"analytics\":{\n" + + " \"payload\":{\n" + + " \"pe\":\"tnt\",\n" + + " \"tnta\":\"333911:0:0:0|2\"\n" + + " }\n" + + " }\n" + + " }"; + + JSONObject mboxJson = new JSONObject(mboxJsonString); + JSONObject clickMetric = responseParser.getClickMetric(mboxJson); + assertNotNull(clickMetric); + assertEquals("click", clickMetric.getString("type")); + assertEquals("1iqiEBgD3uMVv+V1rBrSug==", clickMetric.getString("eventToken")); + assertEquals( + "tnt", + clickMetric.getJSONObject("analytics").getJSONObject("payload").getString("pe")); + assertEquals( + "333911:0:0:0|32767", + clickMetric.getJSONObject("analytics").getJSONObject("payload").getString("tnta")); + } + + @Test + public void test_getClickMetric_ShouldReturnNull_WhenClickMetricIsMissing() + throws JSONException { + final String mboxJsonString = + "{\n" + + " \"index\":0,\n" + + " \"name\":\"ryan_a4t2\",\n" + + " \"options\":[\n" + + " {\n" + + " \"content\":{\n" + + " \"key2\":\"value2\"\n" + + " },\n" + + " \"type\":\"json\",\n" + + " \"responseTokens\":{\n" + + " \"activity.name\":\"ryan json offer a4t test 2\"\n" + + " },\n" + + " \"sourceType\":\"target\"\n" + + " }\n" + + " ],\n" + + " \"metrics\":[\n" + + " {\n" + + " \"type\":\"display\",\n" + + " \"eventToken\":\"1iqiEBgD3uMVv+V1rBrSug==\"\n" + + " }\n" + + " ],\n" + + " \"analytics\":{\n" + + " \"payload\":{\n" + + " \"pe\":\"tnt\",\n" + + " \"tnta\":\"333911:0:0:0|2\"\n" + + " }\n" + + " }\n" + + " }"; + + JSONObject mboxJson = new JSONObject(mboxJsonString); + JSONObject clickMetric = responseParser.getClickMetric(mboxJson); + assertNull(clickMetric); + } + + @Test + public void test_getClickMetric_ShouldReturnNull_WhenEventTokenIsMissing() + throws JSONException { + final String mboxJsonString = + "{\n" + + " \"index\":0,\n" + + " \"name\":\"ryan_a4t2\",\n" + + " \"options\":[\n" + + " {\n" + + " \"content\":{\n" + + " \"key2\":\"value2\"\n" + + " },\n" + + " \"type\":\"json\",\n" + + " \"responseTokens\":{\n" + + " \"activity.name\":\"ryan json offer a4t test 2\"\n" + + " },\n" + + " \"sourceType\":\"target\"\n" + + " }\n" + + " ],\n" + + " \"metrics\":[\n" + + " {\n" + + " \"type\":\"click\",\n" + + " \"analytics\":{\n" + + " \"payload\":{\n" + + " \"pe\":\"tnt\",\n" + + " \"tnta\":\"333911:0:0:0|32767\"\n" + + " }\n" + + " }\n" + + " }\n" + + " ],\n" + + " \"analytics\":{\n" + + " \"payload\":{\n" + + " \"pe\":\"tnt\",\n" + + " \"tnta\":\"333911:0:0:0|2\"\n" + + " }\n" + + " }\n" + + " }"; + + JSONObject mboxJson = new JSONObject(mboxJsonString); + JSONObject clickMetric = responseParser.getClickMetric(mboxJson); + assertNull(clickMetric); + } +} diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetStateTests.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetStateTests.java index 05afb17..5e4e500 100644 --- a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetStateTests.java +++ b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetStateTests.java @@ -7,13 +7,14 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ +*/ package com.adobe.marketing.mobile.target; import com.adobe.marketing.mobile.MobilePrivacyStatus; import com.adobe.marketing.mobile.services.NamedCollection; - +import java.util.HashMap; +import java.util.Map; import org.json.JSONException; import org.json.JSONObject; import org.junit.Assert; @@ -25,14 +26,10 @@ import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; -import java.util.HashMap; -import java.util.Map; - @RunWith(MockitoJUnitRunner.Silent.class) public class TargetStateTests { - @Mock - NamedCollection mockedDataStore; + @Mock NamedCollection mockedDataStore; TargetState targetState; @@ -49,12 +46,13 @@ public void testUpdateConfigurationSharedState() { Assert.assertNull(targetState.getStoredConfigurationSharedState()); // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + } + }; // test targetState.updateConfigurationSharedState(configuration); @@ -66,12 +64,13 @@ public void testUpdateConfigurationSharedState() { @Test public void testUpdateConfigurationSharedState_WhenNewClientCode() { // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + } + }; // test targetState.updateEdgeHost("edge-host-1"); @@ -86,18 +85,20 @@ public void testUpdateConfigurationSharedState_WhenNewClientCode() { @Test public void testUpdateConfigurationSharedState_WhenNewClientCode_WithStoredConfiguration() { // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - } - }; - Map newConfiguration = new HashMap(){ - { - put( "target.clientCode", "code_456"); - put("global.privacy", "optedin"); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + } + }; + Map newConfiguration = + new HashMap() { + { + put("target.clientCode", "code_456"); + put("global.privacy", "optedin"); + } + }; // test targetState.updateConfigurationSharedState(configuration); @@ -125,14 +126,16 @@ public void testUpdateConfigurationSharedState_WhenConfigurationNullOrEmpty() { } @Test - public void testUpdateConfigurationSharedState_WhenConfigurationNullOrEmpty_WithStoredConfiguration() { + public void + testUpdateConfigurationSharedState_WhenConfigurationNullOrEmpty_WithStoredConfiguration() { // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + } + }; // test targetState.updateConfigurationSharedState(configuration); @@ -159,12 +162,13 @@ public void testUpdateConfigurationSharedState_WhenConfigurationNullOrEmpty_With @Test public void testPrivacyStatus() { // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + } + }; // test targetState.updateConfigurationSharedState(configuration); @@ -173,12 +177,13 @@ public void testPrivacyStatus() { Assert.assertEquals(MobilePrivacyStatus.OPT_IN, targetState.getMobilePrivacyStatus()); // setup - Map newConfiguration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedout"); - } - }; + Map newConfiguration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedout"); + } + }; targetState.updateConfigurationSharedState(newConfiguration); // verify @@ -190,15 +195,18 @@ public void testPrivacyStatus() { // =================================== @Test public void testSessionTimeout() { - Assert.assertEquals(TargetTestConstants.DEFAULT_TARGET_SESSION_TIMEOUT_SEC, targetState.getSessionTimeout()); + Assert.assertEquals( + TargetTestConstants.DEFAULT_TARGET_SESSION_TIMEOUT_SEC, + targetState.getSessionTimeout()); // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - put("target.sessionTimeout", 1500); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + put("target.sessionTimeout", 1500); + } + }; // test targetState.updateConfigurationSharedState(configuration); @@ -207,13 +215,14 @@ public void testSessionTimeout() { Assert.assertEquals(1500, targetState.getSessionTimeout()); // setup - Map newConfiguration = new HashMap(){ - { - put( "target.clientCode", "code_456"); - put("global.privacy", "optedout"); - put("target.sessionTimeout", 1200); - } - }; + Map newConfiguration = + new HashMap() { + { + put("target.clientCode", "code_456"); + put("global.privacy", "optedout"); + put("target.sessionTimeout", 1200); + } + }; targetState.updateConfigurationSharedState(newConfiguration); // verify @@ -226,12 +235,13 @@ public void testSessionTimeout() { @Test public void testClientCode() { // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + } + }; // test targetState.updateConfigurationSharedState(configuration); @@ -240,12 +250,13 @@ public void testClientCode() { Assert.assertEquals("code_123", targetState.getClientCode()); // setup - Map newConfiguration = new HashMap(){ - { - put( "target.clientCode", "code_456"); - put("global.privacy", "optedout"); - } - }; + Map newConfiguration = + new HashMap() { + { + put("target.clientCode", "code_456"); + put("global.privacy", "optedout"); + } + }; targetState.updateConfigurationSharedState(newConfiguration); // verify @@ -260,13 +271,14 @@ public void testEnvironmentId() { Assert.assertEquals(0, targetState.getEnvironmentId()); // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - put( "target.environmentId", 45); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + put("target.environmentId", 45); + } + }; // test targetState.updateConfigurationSharedState(configuration); @@ -275,13 +287,14 @@ public void testEnvironmentId() { Assert.assertEquals(45, targetState.getEnvironmentId()); // setup - Map newConfiguration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedout"); - put( "target.environmentId", 50); - } - }; + Map newConfiguration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedout"); + put("target.environmentId", 50); + } + }; targetState.updateConfigurationSharedState(newConfiguration); // verify @@ -296,14 +309,15 @@ public void testPropertyToken() { Assert.assertEquals("", targetState.getPropertyToken()); // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - put( "target.environmentId", 45); - put("target.propertyToken", "configAtProperty"); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + put("target.environmentId", 45); + put("target.propertyToken", "configAtProperty"); + } + }; // test targetState.updateConfigurationSharedState(configuration); @@ -312,14 +326,15 @@ public void testPropertyToken() { Assert.assertEquals("configAtProperty", targetState.getPropertyToken()); // setup - Map newConfiguration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedout"); - put( "target.environmentId", 50); - put("target.propertyToken", "configAtPropertyNew"); - } - }; + Map newConfiguration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedout"); + put("target.environmentId", 50); + put("target.propertyToken", "configAtPropertyNew"); + } + }; targetState.updateConfigurationSharedState(newConfiguration); // verify @@ -334,14 +349,15 @@ public void testTargetServer() { Assert.assertEquals("", targetState.getTargetServer()); // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - put( "target.environmentId", 45); - put("target.propertyToken", "configAtProperty"); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + put("target.environmentId", 45); + put("target.propertyToken", "configAtProperty"); + } + }; // test targetState.updateConfigurationSharedState(configuration); @@ -350,14 +366,15 @@ public void testTargetServer() { Assert.assertEquals("configAtProperty", targetState.getPropertyToken()); // setup - Map newConfiguration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedout"); - put( "target.environmentId", 50); - put("target.propertyToken", "configAtPropertyNew"); - } - }; + Map newConfiguration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedout"); + put("target.environmentId", 50); + put("target.propertyToken", "configAtPropertyNew"); + } + }; targetState.updateConfigurationSharedState(newConfiguration); // verify @@ -369,16 +386,18 @@ public void testTargetServer() { // =================================== @Test public void testNetworkTimeout() { - Assert.assertEquals(TargetTestConstants.DEFAULT_NETWORK_TIMEOUT, targetState.getNetworkTimeout()); + Assert.assertEquals( + TargetTestConstants.DEFAULT_NETWORK_TIMEOUT, targetState.getNetworkTimeout()); // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - put("target.timeout", 10); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + put("target.timeout", 10); + } + }; // test targetState.updateConfigurationSharedState(configuration); @@ -387,13 +406,14 @@ public void testNetworkTimeout() { Assert.assertEquals(10, targetState.getNetworkTimeout()); // setup - Map newConfiguration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedout"); - put("target.timeout", 5); - } - }; + Map newConfiguration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedout"); + put("target.timeout", 5); + } + }; targetState.updateConfigurationSharedState(newConfiguration); // verify @@ -405,7 +425,8 @@ public void testNetworkTimeout() { // =================================== @Test public void testSessionId() { - Assert.assertEquals(TargetTestConstants.DEFAULT_NETWORK_TIMEOUT, targetState.getNetworkTimeout()); + Assert.assertEquals( + TargetTestConstants.DEFAULT_NETWORK_TIMEOUT, targetState.getNetworkTimeout()); // setup String sessionId = "mockSessionId"; @@ -416,7 +437,9 @@ public void testSessionId() { // verify Assert.assertEquals(sessionId, targetState.getSessionId()); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), Mockito.eq(sessionId)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), + Mockito.eq(sessionId)); } @Test @@ -430,7 +453,9 @@ public void testSessionId_WhenUpdatedSessionIdNull() { // verify Assert.assertEquals(sessionId, targetState.getSessionId()); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), Mockito.eq(sessionId)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), + Mockito.eq(sessionId)); // test targetState.updateSessionId(null); @@ -441,7 +466,9 @@ public void testSessionId_WhenUpdatedSessionIdNull() { Assert.assertNotNull(targetState.getSessionId()); Assert.assertNotEquals("", targetState.getSessionId()); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), AdditionalMatchers.not(Mockito.eq(sessionId))); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), + AdditionalMatchers.not(Mockito.eq(sessionId))); } @Test @@ -455,7 +482,9 @@ public void testSessionId_WhenUpdatedSessionIdEmpty() { // verify Assert.assertEquals(sessionId, targetState.getSessionId()); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), Mockito.eq(sessionId)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), + Mockito.eq(sessionId)); // test targetState.updateSessionId(""); @@ -466,19 +495,22 @@ public void testSessionId_WhenUpdatedSessionIdEmpty() { Assert.assertNotNull(targetState.getSessionId()); Assert.assertNotEquals("", targetState.getSessionId()); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), AdditionalMatchers.not(Mockito.eq(sessionId))); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), + AdditionalMatchers.not(Mockito.eq(sessionId))); } @Test public void testSessionId_WhenSessionIsExpired() throws InterruptedException { // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - put("target.sessionTimeout", 2); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + put("target.sessionTimeout", 2); + } + }; targetState.updateConfigurationSharedState(configuration); // test @@ -488,7 +520,9 @@ public void testSessionId_WhenSessionIsExpired() throws InterruptedException { Assert.assertNotNull(firstSessionId); Assert.assertNotEquals("", firstSessionId); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), Mockito.eq(firstSessionId)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), + Mockito.eq(firstSessionId)); Thread.sleep(3000L); @@ -500,19 +534,22 @@ public void testSessionId_WhenSessionIsExpired() throws InterruptedException { Assert.assertNotEquals("", newSessionId); Assert.assertNotEquals(firstSessionId, newSessionId); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), Mockito.eq(newSessionId)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), + Mockito.eq(newSessionId)); } @Test public void testSessionId_WhenSessionIsNotExpired() throws InterruptedException { // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - put("target.sessionTimeout", 100); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + put("target.sessionTimeout", 100); + } + }; targetState.updateConfigurationSharedState(configuration); // test @@ -522,7 +559,9 @@ public void testSessionId_WhenSessionIsNotExpired() throws InterruptedException Assert.assertNotNull(firstSessionId); Assert.assertNotEquals("", firstSessionId); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), Mockito.eq(firstSessionId)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), + Mockito.eq(firstSessionId)); Thread.sleep(3000L); @@ -532,7 +571,9 @@ public void testSessionId_WhenSessionIsNotExpired() throws InterruptedException // verify Assert.assertEquals(firstSessionId, newSessionId); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), Mockito.eq(firstSessionId)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_ID), + Mockito.eq(firstSessionId)); } // =================================== @@ -544,7 +585,9 @@ public void testEdgeHost() { targetState.updateSessionTimestamp(false); Assert.assertNull(targetState.getEdgeHost()); Mockito.verify(mockedDataStore, Mockito.times(1)) - .getString(Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), Mockito.anyString()); + .getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), + Mockito.anyString()); // setup String edgeHost = "edge-host-1"; @@ -555,7 +598,9 @@ public void testEdgeHost() { // verify Assert.assertEquals(edgeHost, targetState.getEdgeHost()); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), Mockito.eq(edgeHost)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), + Mockito.eq(edgeHost)); } @Test @@ -570,7 +615,9 @@ public void testEdgeHost_WhenUpdatedEdgeHostNull() { // verify Assert.assertEquals(edgeHost, targetState.getEdgeHost()); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), Mockito.eq(edgeHost)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), + Mockito.eq(edgeHost)); // test targetState.updateEdgeHost(null); @@ -595,7 +642,9 @@ public void testEdgeHost_WhenUpdatedEdgeHostEmpty() { // verify Assert.assertEquals(edgeHost, targetState.getEdgeHost()); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), Mockito.eq(edgeHost)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), + Mockito.eq(edgeHost)); // test targetState.updateEdgeHost(""); @@ -603,7 +652,9 @@ public void testEdgeHost_WhenUpdatedEdgeHostEmpty() { // verify Assert.assertNull(targetState.getEdgeHost()); Mockito.verify(mockedDataStore, Mockito.times(1)) - .getString(Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), Mockito.anyString()); + .getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), + Mockito.anyString()); Mockito.verify(mockedDataStore, Mockito.times(1)) .remove(Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST)); } @@ -611,13 +662,14 @@ public void testEdgeHost_WhenUpdatedEdgeHostEmpty() { @Test public void testEdgeHost_WhenSessionIsExpired() throws InterruptedException { // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - put("target.sessionTimeout", 2); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + put("target.sessionTimeout", 2); + } + }; targetState.updateConfigurationSharedState(configuration); // setup @@ -630,7 +682,9 @@ public void testEdgeHost_WhenSessionIsExpired() throws InterruptedException { // verify Assert.assertEquals(firstEdgeHost, targetState.getEdgeHost()); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), Mockito.eq(firstEdgeHost)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), + Mockito.eq(firstEdgeHost)); Thread.sleep(3000L); @@ -645,13 +699,14 @@ public void testEdgeHost_WhenSessionIsExpired() throws InterruptedException { @Test public void testEdgeHost_WhenSessionIsNotExpired() throws InterruptedException { // setup - Map configuration = new HashMap(){ - { - put( "target.clientCode", "code_123"); - put("global.privacy", "optedin"); - put("target.sessionTimeout", 100); - } - }; + Map configuration = + new HashMap() { + { + put("target.clientCode", "code_123"); + put("global.privacy", "optedin"); + put("target.sessionTimeout", 100); + } + }; targetState.updateConfigurationSharedState(configuration); // setup @@ -664,13 +719,15 @@ public void testEdgeHost_WhenSessionIsNotExpired() throws InterruptedException { // verify Assert.assertEquals(firstEdgeHost, targetState.getEdgeHost()); Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), Mockito.eq(firstEdgeHost)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), + Mockito.eq(firstEdgeHost)); Thread.sleep(3000L); // verify String newEdgeHost = targetState.getEdgeHost(); - Assert.assertEquals(firstEdgeHost,newEdgeHost); + Assert.assertEquals(firstEdgeHost, newEdgeHost); Mockito.verify(mockedDataStore, Mockito.times(1)) .getString(Mockito.eq(TargetTestConstants.DataStoreKeys.EDGE_HOST), Mockito.any()); } @@ -685,7 +742,9 @@ public void testSessionTimestamp() { // verify Mockito.verify(mockedDataStore, Mockito.times(1)) - .setLong(Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_TIMESTAMP), AdditionalMatchers.not(Mockito.eq(0))); + .setLong( + Mockito.eq(TargetTestConstants.DataStoreKeys.SESSION_TIMESTAMP), + AdditionalMatchers.not(Mockito.eq(0))); } @Test @@ -706,16 +765,16 @@ public void testIsPreviewEnabled() { Assert.assertTrue(targetState.isPreviewEnabled()); // setup - Map configuration = new HashMap(){ - { - put( "target.previewEnabled", false); - } - }; + Map configuration = + new HashMap() { + { + put("target.previewEnabled", false); + } + }; targetState.updateConfigurationSharedState(configuration); // test and verify Assert.assertFalse(targetState.isPreviewEnabled()); - } // =================================== @@ -725,7 +784,10 @@ public void testIsPreviewEnabled() { public void testGetTntId() { // setup String mockTntId = "mock-tntId"; - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), + Mockito.any())) .thenReturn(mockTntId); targetState = new TargetState(mockedDataStore); @@ -737,7 +799,10 @@ public void testGetTntId() { public void testUpdateTntId() { // setup String mockTntId = "mock-tntId"; - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), + Mockito.any())) .thenReturn(mockTntId); targetState = new TargetState(mockedDataStore); @@ -750,14 +815,18 @@ public void testUpdateTntId() { // verify Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), Mockito.eq(newTntId)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), Mockito.eq(newTntId)); } @Test public void testUpdateTntId_WhenNewTntIdNull() { // setup String mockTntId = "mock-tntId"; - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), + Mockito.any())) .thenReturn(mockTntId); targetState = new TargetState(mockedDataStore); @@ -776,7 +845,10 @@ public void testUpdateTntId_WhenNewTntIdNull() { public void testUpdateTntId_WhenNewTntIdEmpty() { // setup String mockTntId = "mock-tntId"; - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), + Mockito.any())) .thenReturn(mockTntId); targetState = new TargetState(mockedDataStore); @@ -798,7 +870,10 @@ public void testUpdateTntId_WhenNewTntIdEmpty() { public void testGetThirdPartyId() { // setup String mockThirdPartyId = "mock-thirdPartyId"; - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), + Mockito.any())) .thenReturn(mockThirdPartyId); targetState = new TargetState(mockedDataStore); @@ -810,7 +885,10 @@ public void testGetThirdPartyId() { public void testUpdateThirdPartyId() { // setup String mockThirdPartyId = "mock-thirdPartyId"; - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), + Mockito.any())) .thenReturn(mockThirdPartyId); targetState = new TargetState(mockedDataStore); @@ -823,14 +901,19 @@ public void testUpdateThirdPartyId() { // verify Mockito.verify(mockedDataStore, Mockito.times(1)) - .setString(Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), Mockito.eq(newThirdPartyId)); + .setString( + Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), + Mockito.eq(newThirdPartyId)); } @Test public void testUpdateThirdPartyId_WhenNewTntIdNull() { // setup String mockThirdPartyId = "mock-thirdPartyId"; - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), + Mockito.any())) .thenReturn(mockThirdPartyId); targetState = new TargetState(mockedDataStore); @@ -849,7 +932,10 @@ public void testUpdateThirdPartyId_WhenNewTntIdNull() { public void testUpdateThirdPartyId_WhenNewTntIdEmpty() { // setup String mockThirdPartyId = "mock-thirdPartyId"; - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), + Mockito.any())) .thenReturn(mockThirdPartyId); targetState = new TargetState(mockedDataStore); @@ -886,10 +972,16 @@ public void testResetSession() { public void testGenerateSharedState() { // setup String mockTntId = "mock-tntId"; - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), + Mockito.any())) .thenReturn(mockTntId); String mockThirdPartyId = "mock-thirdPartyId"; - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), + Mockito.any())) .thenReturn(mockThirdPartyId); targetState = new TargetState(mockedDataStore); @@ -899,15 +991,23 @@ public void testGenerateSharedState() { // verify Assert.assertEquals(2, sharedState.size()); Assert.assertEquals(mockTntId, sharedState.get(TargetTestConstants.EventDataKeys.TNT_ID)); - Assert.assertEquals(mockThirdPartyId, sharedState.get(TargetTestConstants.EventDataKeys.THIRD_PARTY_ID)); + Assert.assertEquals( + mockThirdPartyId, + sharedState.get(TargetTestConstants.EventDataKeys.THIRD_PARTY_ID)); } @Test public void testGenerateSharedState_WhenNullTntIdAndThirdPartyId() { // setup - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), + Mockito.any())) .thenReturn(null); - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), + Mockito.any())) .thenReturn(null); targetState = new TargetState(mockedDataStore); @@ -923,9 +1023,15 @@ public void testGenerateSharedState_WhenNullTntIdAndThirdPartyId() { @Test public void testGenerateSharedState_WhenEmptyTntIdAndThirdPartyId() { // setup - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.TNT_ID), + Mockito.any())) .thenReturn(""); - Mockito.when(mockedDataStore.getString(Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), Mockito.any())) + Mockito.when( + mockedDataStore.getString( + Mockito.eq(TargetTestConstants.DataStoreKeys.THIRD_PARTY_ID), + Mockito.any())) .thenReturn(""); targetState = new TargetState(mockedDataStore); @@ -944,18 +1050,20 @@ public void testPrefetchedMboxes() throws JSONException { Assert.assertTrue(targetState.getPrefetchedMbox().isEmpty()); // setup - String prefetchString = "{\n" + - " \"name\" : \"mboxName\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"myContent\"" + - " }]\n" + - " }"; + String prefetchString = + "{\n" + + " \"name\" : \"mboxName\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"myContent\"" + + " }]\n" + + " }"; JSONObject prefetchJsonObject = new JSONObject(prefetchString); - final Map prefetchMbox = new HashMap() { - { - put("mboxName", prefetchJsonObject); - } - }; + final Map prefetchMbox = + new HashMap() { + { + put("mboxName", prefetchJsonObject); + } + }; // test targetState.mergePrefetchedMboxJson(prefetchMbox); @@ -993,19 +1101,21 @@ public void testPrefetchedMboxes_EmptyOrNullPrefetchedMbox() throws JSONExceptio @Test public void testSaveLoadedMbox() throws JSONException { // setup - String mBoxesResponseString = "{\n" + - " \"name\" : \"mboxName\" , \n" + - " \"metrics\" : \"myMetrics\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"myContent\"" + - " }]\n" + - " }"; + String mBoxesResponseString = + "{\n" + + " \"name\" : \"mboxName\" , \n" + + " \"metrics\" : \"myMetrics\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"myContent\"" + + " }]\n" + + " }"; JSONObject mboxResponseObject = new JSONObject(mBoxesResponseString); - final Map mboxResponses = new HashMap() { - { - put("mboxName", mboxResponseObject); - } - }; + final Map mboxResponses = + new HashMap() { + { + put("mboxName", mboxResponseObject); + } + }; // test targetState.saveLoadedMbox(mboxResponses); @@ -1022,20 +1132,22 @@ public void testSaveLoadedMbox() throws JSONException { @Test public void testSaveLoadedMbox_WhenEmptyOrNullMboxName() throws JSONException { // setup - String mBoxesResponseString = "{\n" + - " \"name\" : \"mboxName\" , \n" + - " \"metrics\" : \"myMetrics\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"myContent\"" + - " }]\n" + - " }"; + String mBoxesResponseString = + "{\n" + + " \"name\" : \"mboxName\" , \n" + + " \"metrics\" : \"myMetrics\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"myContent\"" + + " }]\n" + + " }"; JSONObject mboxResponseObject = new JSONObject(mBoxesResponseString); - final Map mboxResponses = new HashMap() { - { - put("", mboxResponseObject); - put(null, mboxResponseObject); - } - }; + final Map mboxResponses = + new HashMap() { + { + put("", mboxResponseObject); + put(null, mboxResponseObject); + } + }; // test targetState.saveLoadedMbox(mboxResponses); @@ -1062,11 +1174,12 @@ public void testSaveLoadedMbox_WhenEmptyOrNullMboxResponse() { @Test public void testSaveLoadedMbox_WhenEmptyJsonInMboxResponse() { // setup - final Map mboxResponses = new HashMap() { - { - put("mboxName", new JSONObject()); - } - }; + final Map mboxResponses = + new HashMap() { + { + put("mboxName", new JSONObject()); + } + }; // test targetState.saveLoadedMbox(mboxResponses); @@ -1079,11 +1192,12 @@ public void testSaveLoadedMbox_WhenEmptyJsonInMboxResponse() { @Test public void testSaveLoadedMbox_WhenNullJsonInMboxResponse() { // setup - final Map mboxResponses = new HashMap() { - { - put("mboxName", null); - } - }; + final Map mboxResponses = + new HashMap() { + { + put("mboxName", null); + } + }; // test targetState.saveLoadedMbox(mboxResponses); @@ -1095,32 +1209,36 @@ public void testSaveLoadedMbox_WhenNullJsonInMboxResponse() { @Test public void testSaveLoadedMbox_WithPrefetchedMbox() throws JSONException { // setup - String prefetchString = "{\n" + - " \"name\" : \"mboxName\" , \n" + - " \"metrics\" : \"myMetrics\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"myContent\"" + - " }]\n" + - " }"; + String prefetchString = + "{\n" + + " \"name\" : \"mboxName\" , \n" + + " \"metrics\" : \"myMetrics\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"myContent\"" + + " }]\n" + + " }"; JSONObject prefetchJsonObject = new JSONObject(prefetchString); - final Map prefetchMbox = new HashMap() { - { - put("mboxName", prefetchJsonObject); - } - }; + final Map prefetchMbox = + new HashMap() { + { + put("mboxName", prefetchJsonObject); + } + }; targetState.mergePrefetchedMboxJson(prefetchMbox); - String mBoxesResponseString = "{\n" + - " \"name\" : \"mboxName1\" , \n" + - " \"metrics\" : \"myMetrics1\" \n" + - " }"; + String mBoxesResponseString = + "{\n" + + " \"name\" : \"mboxName1\" , \n" + + " \"metrics\" : \"myMetrics1\" \n" + + " }"; JSONObject mboxResponseObject = new JSONObject(mBoxesResponseString); - final Map mboxResponses = new HashMap() { - { - put("mboxName", prefetchJsonObject); - put("mboxName1", mboxResponseObject); - } - }; + final Map mboxResponses = + new HashMap() { + { + put("mboxName", prefetchJsonObject); + put("mboxName1", mboxResponseObject); + } + }; // test targetState.saveLoadedMbox(mboxResponses); @@ -1140,28 +1258,31 @@ public void testSaveLoadedMbox_WithPrefetchedMbox() throws JSONException { @Test public void testRemoveDuplicateLoadedMboxes() throws JSONException { // setup - String mboxString = "{\n" + - " \"name\" : \"mboxName\" , \n" + - " \"metrics\" : \"myMetrics\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"myContent\"" + - " }]\n" + - " }"; + String mboxString = + "{\n" + + " \"name\" : \"mboxName\" , \n" + + " \"metrics\" : \"myMetrics\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"myContent\"" + + " }]\n" + + " }"; JSONObject mboxJsonObject = new JSONObject(mboxString); - final Map mboxResponses = new HashMap() { - { - put("mboxName", mboxJsonObject); - } - }; + final Map mboxResponses = + new HashMap() { + { + put("mboxName", mboxJsonObject); + } + }; targetState.saveLoadedMbox(mboxResponses); - final Map prefetchMbox = new HashMap() { - { - put("mboxName", mboxJsonObject); - } - }; + final Map prefetchMbox = + new HashMap() { + { + put("mboxName", mboxJsonObject); + } + }; targetState.mergePrefetchedMboxJson(prefetchMbox); // test @@ -1179,20 +1300,22 @@ public void testNotifications() throws JSONException { Assert.assertTrue(targetState.getNotifications().isEmpty()); // setup - String mboxString = "{\n" + - " \"name\" : \"mboxName\" , \n" + - " \"metrics\" : \"myMetrics\" , \n" + - " \"options\" : [{\n" + - " \"content\" : \"myContent\"" + - " }]\n" + - " }"; + String mboxString = + "{\n" + + " \"name\" : \"mboxName\" , \n" + + " \"metrics\" : \"myMetrics\" , \n" + + " \"options\" : [{\n" + + " \"content\" : \"myContent\"" + + " }]\n" + + " }"; JSONObject mboxJsonObject = new JSONObject(mboxString); // test targetState.addNotification(mboxJsonObject); // verify - Assert.assertEquals(mboxJsonObject.toString(), targetState.getNotifications().get(0).toString()); + Assert.assertEquals( + mboxJsonObject.toString(), targetState.getNotifications().get(0).toString()); // test targetState.clearNotifications(); diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetTestConstants.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetTestConstants.java index 295e4ad..6b9d89b 100644 --- a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetTestConstants.java +++ b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetTestConstants.java @@ -1,5 +1,5 @@ /* - Copyright 2022 Adobe. All rights reserved. + Copyright 2023 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 @@ -7,7 +7,8 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ +*/ + package com.adobe.marketing.mobile.target; import java.util.HashMap; @@ -19,7 +20,8 @@ class TargetTestConstants { static final String OLD_API_COMPAT_PARAM = "__oldTargetSdkApiCompatParam__"; static final String API_URL_HOST_BASE = "%s.tt.omtrdc.net"; - static final String PREFETCH_API_URL_BASE = "https://%s/rest/v1/delivery/?client=%s&sessionId=%s"; + static final String PREFETCH_API_URL_BASE = + "https://%s/rest/v1/delivery/?client=%s&sessionId=%s"; static final String REQUEST_CONTENT_TYPE = "application/json"; // Target preview Constants @@ -35,32 +37,147 @@ class TargetTestConstants { static final String DEEPLINK_SCHEME_PATH_CONFIRM = "confirm"; static final String MBOX_AT_PROPERTY_KEY = "at_property"; + /** Base64 encoded button PNG */ + static final String ENCODED_BUTTON_BACKGROUND_PNG = + "iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAABGdBTUEAALGPC/xhBQAA" + + "ACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsTAAALEwEAmpwYAAABWWlUWHRYTUw6Y29tLm" + + "Fkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA" + + "8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRl" + + "c2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+C" + + "iAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3J" + + "kZjpSREY+CjwveDp4bXBtZXRhPgpMwidZAAAa4ElEQVRoBb1bB5gV1dn+Zub2e7dTlLoUKdI7iCiY34YB8xglMVGjKCAWFCuKBiVGTYwl" + + "GI0CgmLvEfmjMUQQC1VC73WX3WXZwu7e3dvvzP++Z+5ddpdFNJL/PHvunJlTv/5955zV5P8naalp1POhhx5Sr6mnlapLP1Ov/51HeiGne" + + "nSOqwEg/cwzz9Tr6ur0hhMcPHhQvXbs2LH+c+vWra3CwkJz6dKl5rvvvkvgzfrKU1g4lQArIF988UWjffv2+po1awwAnMRa48gEwEBWbV" + + "JPPNR31rGdajN9+nQn+ovD4TArKyuTqTFYd0rSqQBYu+KKK/RRo0Y53G63MWXKlARWRupoN9xwQ+vbb7+9YyAQaO1yufI9Hk8rwzC8uq7" + + "7kBNIoVgsVhuJRApQLtq/f3/JeeeddwB965BlxIgRTowtO3bsSMydOzeNlB8F/I8BmH11UMCZehJQeeutt/JHjhx5bm5u7hCn09kDAHYE" + + "cFmo+s65LMsiAg6bprkXCNhcVFT0Va9evVajXzWyE5yjf/vtt/FTBTjG/N5JAQrMu5544gk/ehFg37p168bU1NQ8BYqtx+KrkGuQjyIfR" + + "j6ksmkespABlHqyXF9nWUUoH0GuRg6iTTEA//jw4cO3zpkzpwvmoEh4AbgPTwfydyIQ9ackcRLjqaee8uLJ7Nq4ceN5tbW1C5LJZAEWWo" + + "tcjkxACs1kkoARkOIGme/pfOw7AET7IrQvZN9UewJfAySuOXLkyIzHHnssn/M/99xzASIc5UbKEO+nNBFYx6JFi0hV1/jx49tUVFQ8DEAP" + + "YFFB5BLkQkU1LB5lZgJG4IusZLIYTFtshsMliaLi0mR5+WEzHi/hN1XXsC36AvjiBsATiUFQ/AvI83jM70H2QZz4JNDfm9rft6E2aNAgx8" + + "SJE90333xzZPny5QOGDx/+eyipEZiMVE1gIHtiTaNSsSSZ1OMHCxzRA/tdsVVrXMniEt0MBg2zNqhbRSWaFvBbWssWlh7IMLVAwHT27Z1w" + + "9+8fdbdvF9dbtEgrKF0spaNMSxP8aT7OVVVVNQ864inMEwLQ1CNRlNnnlCRt8uTJTgwawGiOffv2XQGq7sLElM8CxbI2RRU14wWFR46+tK" + + "C2dPLUWFHbrmYhgD/UKAesQ6d1tA5lt8F3o1Ed25Zc/NNE2cwHw7VL/3UU3EAuIYeQ2sVK9m1OqAmFQu/MmDEjH2typeSaMn7SdDIKK8r+" + + "8pe/dN19991xaM6r27Rp8zuMSkUVAfYN0dQQpllW5ggu+cRfN/sxv3lgh/21U3eRTOApBlNMSqWziTK7aWAK9cSPA3qI5T1AT7hMGWXXtd" + + "fHA5Mm1vqGDYuIYVjoDyIrDqLZy45Go6sWL15824QJE/YAaAdMIinNOsUWeB6XOMWJEuuoIDxg42hxcfH1p5122iOappF1YilgLYlGtZrF" + + "HwfqnnzGn1z9ta617yJadpZlxeOaJNA0+QM4jWhygFAE3gAyNv/bBvy26bHsGyYGXb17EyAwNxGm0QwS6E1LliyZcvnll++GMjXuuOOOGL" + + "6fcNLvYgMqKPekSZOiYOMr27Vr9ziBBXtRXklZC4rHqHhodk7ozuk+iWua3qUryahJJKopQG35w/w/IJkgUAKwkCtObyva6W3EXPyhEfrr" + + "X33agIGWu0f3GOYm0DqeIXhkHTt37twPn5bPnDkzCNEzoGNOSOUTUVgHi3jAIrFt27aN7tGjxwIM6AawIBuUE4CN793nrLzz7pzERx84ZO" + + "BQqC44R1ykzcw/AMKTN6WCsyIRTXZvE98Lc+tA7RrNAK2OUToH/vrf4dFNgcjF4Pgk4I+nXdpGE1CzNk3arbfe6gSwJryazl27dn0UwNIU" + + "1bNxdNduV1nfUXkK2H6DRCqr4DGDKk2B5YK4MLLnyahNVm7aP7UyK1hrE6b/YKm7cbK/8vE/Zgs5ge0tC/wvVX6//6KjR4/eDtEzhw4dSh" + + "3TLPceBzD94g4dOnAQ/corr7wL7mFPlOswsKHpupmsqDCq7p6RbYWKda3fYEuqgs0vlABCFq19xWJV18JyuqFO8K255HKJtbcYSDsBhxAw" + + "6oOaWtEHD7PCD9zvrX719QwMZaWQRDjqsrKyboSdHg0FG4M8E2gbUQ3mbAqwNnbsWCc7oOP/gEVo5OkiOjiwFUtoxG5i8QcOrf9gOJA1mu" + + "hNxuTidAwLylol5eL82fmid8kXa8dmkQx4haRMwwREWDs3i2PceaK1yBOJQuekx2jYjmUg0aqs1rQ+AyR47TWBuuVf0M008Z2LSIITXfn5" + + "+begnPX6669ro0ePPo7KjQCmwF933XXsnI2ON+MJsoiJgfAAoV55OTP6pz+6tQFDjgc2zb5ueHxUOk4wSd0R0XKyJeueO0Ufc75YWzZgKZ" + + "k20Bwz4Bdz+ybxPjRbfON+Kua/UU9O4FhEJMtNE+uicdHadpbqMZdlRXfvcQNBNFkErg7O0Nlg658j0IjedNNNpHIjGBu+aAjIycqxQ4cO" + + "XYxwDpoIrGyaHMiK7tzpqps8ya/17CNWDWTKRgKqWEv2BUWPVIoFADQ3FhqJitazr0Rfmiehb1ZK1rRbxLhkvJibvgU6ETx5PWJuXi++WQ" + + "+Lp18/qX1pAdALZBBQIgsKimMpbrFnOfYbAxe0yAE/V2o18+ZnqPm5nhSl8/LyroEeOh322YLT1IjK9QCnqCu9e/dugfRrUBUjYEyyJ1Lw" + + "tTfoaYFVsZimtpUKBxpay/BLLoDz3XeXmAd2YeFO0c/sJ5E//UHqFi+WzKlTxH3TLWJuXCfm1g3if+RRcffpLdWzHxFz5VeidWlrszRkPv" + + "eLFeL/8xzI9nb4UiRUg8SlQZ6l9wCJPfEHd2jVagYylBUuNgRi9b7//vvHoRyHhSERCYtKfGHS4JsSE4l33nmnDzoMQDkEd04pqvC6b72R" + + "R2Z7NCxeQmG0ru/Pvja19mwX/2N/EN+I4aKDwliOjZhwRPQ+AyW68CUxq6olcNWvRM/OEaNVSzEyM6R66u1ildWIGhtIs8qqxRjeT7znjB" + + "JXjx4S+ctcScLkaT6IK0WlYTJt/6J24csB38ABESFnkduwvpycnAvR9K2VK1dGqIhhplTjNIU1BN8sa7BjF4C4jEKS0MqcRA++8WagHkQO" + + "2DSB4qyP79snsJfi6naGGGePhhNdqpSXgAV1mJTYh+9J7ZznJfPS8eI7e6QEJ14vZlmhaAO6gUPApmBlC26la+gQNUOiplrM3VvAOWCups" + + "qOLcJwvKDAYvNedNZ9s7IhlcOwLgPWr1/fg/YYANeztQIY7KzDJbOwTdPC5/NRdpOgLmGwEgWFjsTCt53SpYe9KE7UNEGzUl4T816UeEmJ" + + "6IGAOMGqUn0Yiskn5s4tYm1YJ4FHHxf/1ElS+bvfS/XClyXrww/Fe+99UFZrxdqzny6pGtmRAjheWKj4VLF0cwCzddJUyI6s+IpEom6hF5" + + "bALksO9sZGsklqE1HRTAHMnUV8jz377LNdsCXTGeVIWoYje/e4rKpDmvjhe2DwRonEpoIBgJKVoRzY2MEC1cR57ii8Q3kCUPcNUyTrtTdE" + + "z82R4BNPSWLJ3yT23LMSnDdfXL16Sebc+eK45AJJrvxS9XW0bqWe8XXr1VO8IB40+nGixFqyubuFxNesddJHwBeuSrEhzCq8InHCIdFA1H" + + "qAtfQ2KrRbT7X/ZFngUSWoWnT5Cts20ClomJRmRrhaXmUroVVfq30XqQupVo42bcRz8TgFqPfccyT06T8keOMUsPlh0Xr0UTKb/PsKqbnm" + + "Kont2CmB634jGc/9VRxnDhDDR8cOGignR1HPXP210uhKPlVNgx86JN06SOLvi43o/gPcBbGjKkgYiQcXuQ24l/KriNtQgzkyMjIgTPXJMi" + + "sqDQbvkn368QrDga5Ha8To1llc424RD9jQM2iQGLC7TJ5u3SR5+WUSXrVKYn+Zo75RYyvHgs4FaKCd0Q4y3kEiTz0hsU/6iufnP5PAwzPF3" + + "etM1T7rhoniu+gCCX+zSqJr10rstXexz0GYQKy0LuHTsjkvtnGTyzd4UDhlWWIILNrA+WiDDvvAxUrVO0Bq2bRpE8lteL3ejpwJnpUicKy" + + "42GF9vkwTLL4RO9vKDPPqkrdogbjO6MpuCinR7TskvPwLcWRlSe0bb0ryX58p06RYDxq7PnFGsiP+dFCcSqvukdmSmHYbcNBeEoWHxHfOO" + + "eJs106cEy4XQa7q0V2CN1yvFKBUw6VNJ1CZw8W3bHVAucH7U8Sk55UJR0TJB9ibTcSxdetWbe3ateR5Pxqwsl5QrVAILgwCJNhTSTRYLAa" + + "0DpWJ49yhiqKxXbslvGaNRGE7Y/PnqgGyIbMGEGECYAUYg4sTJVIc/jSXibhToitXS83t06S2ez9xXzVBXH372MBDTNSqmyqwFLWt2losr" + + "PEkMLEw7qKXlpayq+bA3q8G1W3ee++9iMEsajqlnvG0kuGQrc7pWKRZCBXK8WiZKebRo1I29lJJrP1GzaNGHHaWaKu/EWnZAuaE/j1SU7t" + + "tf238mwYi5dTY2icpoQdnCrVCjQG7PaqfaJ1hLeh0NBxTAekUM1gDgEkvoI7rRRuYJ6p+hSdOSBlWqVOnTm5QmO/pCETMUFjnWAjt7UbpX" + + "7I8I5ziUknQJFEJ0e9lPAw/VyW18CboTvdv7plakubxillcYiMQAYjO8JMJLJzYuA2mC0hsCCzrCGRea65HAxF0vWVL2yNBFRQX7XMaYE0" + + "//fTT+WJlZmYSqTZFUWCyYti5QLL3VFhqkIhBmCQYPggP2JXvpFJ6aBVFpV8a9DtJUYP4WFH44WxHpBGJfFJOvUBqU2DZjnj1oF9trWZFY" + + "00nJRHrv+klJSVsriG6gM8ox/aM8GJkZStMoUF9B3y2E2NbUFnrdQYwWw7T9K2YDAGhmNhYB1dYye+Q2/Q46SdXgWRW1wi2ae0XAMtoymS" + + "UlZctWnsoXJqhponILSoXLb+Dpefl1usgNsMOK7Vb+ptFpaUAfvLJJ8PY2Yf2EJuNWXC5bHkmholZUpEJOxgWdjmMof3Ef+01Yo0/Iibcv" + + "8TmzRJb8bVCuHngIGx0JRrTLUz1U51P8GNrVhV1CUJMrtDRuqV4J1wmRuvWYsDxSVRWSui+GTBnMFsN/WpF9SAIlJVEpKbgQXc1KVxmqoD" + + "6BVBpWdig059++mluqFehMi2wmu712pjh4CRbuhvdubwsuIx7JTjlTnFcer44+vcVZ+fO4hl1tiRLyxActAJ1dqJLLawXOjPiIXs2TVwsO" + + "EXgg3OyZCQsnv79JAOBiKNTviT2HZBkRblE/rYYXLRDtC7dGwPbcDyvD05H6kOK9XlAhy/HKEw7jMxmJo4yDkGN29TEB2fbNkl9xCic5x3" + + "UJYuUasBOpDYoLa2yJP76Iom9buNEg9nzPDpDvJ07SWDazRLbfI5E/vi4WoWKiGiC0hqZ5g4Kx9yxCbZ1iPjuuU+8PxkDiraS0L79En7jb" + + "UkiZmbS8tphRwTxcnPc4rB1r6tXzzjWBLpZ0L8aC2F4kSXsHwwGFSqUVk6dxCdQuRvKK4Ub0cBKCcewofHYyi/dkgvnoDn54WK69VJam8q" + + "FMpfYvEXCuXkSfuVV8f/manG/+baEv/xSos//RfRWHZQ8UkSsbRvR2xDvPTMQF/eRRHm51L33gbi7dkUE9IJIh662U0J2ZzTV1JcnJFwtE" + + "Y/kGjyQIknXkt9doG7xgQMHELKJAQdEUVm1TEFv4hRwC7GCxjqiJY5heX4yJqpQ0zQIZy0TB6eWpg8NgMn5jpatJblnr8SXL5Vq+Mihz/4" + + "p9KczX5grWse2aieDwDqv+o1kvrZI6HcjppXa6bcpQDVsAzmu/LVIQaGNZHpozQHL+bkrWlQq+qjzTHd+PgEmdbl4F45mDlx00UWFvFUA5" + + "azYkwBbvFqAp3PFihX7gZUClN1YODtprq5dYmhkKQynFQsqmk00KaigPCeLi5UyYBwcXzhfqn8xQZJQOpkz7xPH+WPFc/8D4rtkrIT/uVS" + + "C8KqSazeJMWyk6m8hTNRzczESjIYyb83OZn+kU1RRJI6zhsXBkYQjvf2k4fxpC95Dffv2tVJiaysovJg8psAVhUKcxZLPsDdjK2tgLW786q" + + "qk7EBfhoInSlwYPCCjJ7wh2NFEURF2QuCp4pvWvbdoQ8+S2vtnSOiDD6Ul/G//BedL1ZW/kPgrC0UfNEy0ltijwo4IU2L9BmhoOBJ8OQmS" + + "YbfJY+IZMZwmlfKrepFTy8rKvuK3FAfbFaxFsrD3Q4om0OiffCLb/obHY/qv+nWdav1dAIO6ZuEecY4fqxaa/OwTUdEQRQPxrLnmG/Fcc5" + + "3kPDxLjNNaqy2cnI+X2Mp/+35EQfBqIRoUiXjBQXEiTmZZpbRWSb+nn+SofYc0x+jzk9hBoR/BNRMOHwi3Y9asWSSeI8XBqpeSYZQs3Loh" + + "Ozg+/fTT1fF4fC/K9VsmgTGjQ65rro3zcKvZrVMOlZJfDbIc20JOQqKbyR2PDWvFO+N+afHnp8WZ31Fi+/bDbQ1J4KeXSO7KVbT39hYu3F" + + "OtXRdo5m0M6EU/6xyxEIIeg9weVv2SkvS8akvFf8e0OiMvLwFgoX0UZzrC4fDnuG9yBHt0PD8mElRKAyz8iGDZmDp1ahHuaryHWrhRar8X" + + "QILK109UN2uO20FMDaRcvy49JfrOh9jNeEX0rnAO6KDAS/I+OEvyEATokM0QQseyLp2lAjKcRPDhHT5Mcr/8RJkl60iFTWkgLTz/VXhw2" + + "Cwg5ZuaIgLrAz3g3TkuuyIROG8MnQssVjGXG3qoEAR8H98MnI2RkKiyUz3AqY/0DPT333//PXTahbIXQBM7un/kWWH3g7MinETLDFjHLQ" + + "KNlH0FRaU9XEOwPzWx+/rJknfv3WrXse6TT6VyzGgR7G1H5jwj5RMnSeLwYfH07i3Zz/xJpPwQeAx6gnKbfYItHc7DevA7oci4a3pQ8/v" + + "V6QO0M4Hzwtq8d+GFF+4kAUFIimc9wFBxxxLOWQWNXDhIq8SuPW4iBC5AbRSsolOJufv2iUW27/KYK5YZ0q697Tk1J1+kAKiiuQOYyZQE5" + + "Di6dasEJ1whkt8NBh5Rb8d8SSxbKrGyCknCxob/9xMxC2AyDUKC/vVLPLY+VUKdlp1pWZvWaxmLXqvNuGQsOY+amYTxgFD7wMa//eijj4K" + + "DBw9OLl++nEioT/V6If2F1xsQSDD74Hm9BoM9HHVBLEKdCUd37XKVd++XJ/kdNJ4eMFjAZOnux55cNM+XoKUtbMUy6djZVDabrirZFBt/1" + + "uaNgM223xpEot4LOzbSsRKR2DLHstat1tyzHo60mPVgJea2latN3QycmtyN3coFIJwbhMPi6t1KNU4zKxVt4cKFbpwxmRs2bBjZp0+fhdj" + + "YA2TQ3PYhtFm3fLm/asyYbLV1yzi4rpnN+fQyiQycSKjrDTUIXIiIdCLQVDyUR27w43imWeSl2+cgll+/Rslty/nzyvWcLMXKGEVt58BTX" + + "AKuvOnqq69O4N5mFNQlOzdKDWU4XWEB2DhO/539+/f/Elsjj6GCAJNtuFrdP3p0KHvZ8irZu8OSrdsVpdKdj3sSQFBZEPY1ApYNabvpWx+F" + + "/eXzRJxCc4i7IhaAdd56W6zFC89V1AMLyoLIAViWHc8///xvMWp0yJAhiaasnF5XcxRmnbrMMm7cODeEnp7Ygzi6mIrvjC3Zh9nEhp376C" + + "235yQ//4chfQfa7EoqnaoELY8jFsuqqNSkaL/4npkTyr5xcrUKAXlwllJScCErcUFu0sCBA78BK/Mw/zhWTi+pOQqzzoIMkx3om1o4d/o9" + + "NB/iIeH+EJ1zZt3ds0es1ZuvlrtnPhCFEhHhaZ8fWppsnnLo0f6HJVKZmpraHv6ztelbTcPdg8zFH9fk3HZrVVNgsZTQ3r177wCwX4ErqX" + + "CVx3WiSU9E4XR7DfccXdOmTSNiPNXV1bMRTV2DMjWjmT5sw8K00Nq1ntoFL/vj815AfInEoxmeFqTDQXpclFmqXz6YCBwzWZtPhossF5bC" + + "zYQvbrSwvHNmhzN/dmmt0aaNMpkUC3QnG/tA2aN79uy5q3v37ktSt41I2ePkVs2V+sHoJ00a2JqszbYGXM97cJx6C8pcQPreBweB7YnpdS" + + "tXeuvefc+feHuxw6oosMc3ckXa5dnKiUCR+pRteGcKIdxjLj1sD4dfY8z5pnvc2CgBdXTqxHnYnmNBTStbmwXzs3/nzp3Tcby7AsB6eUMQ" + + "9TRBaXSieHz6PgCzlw5KO2GnHZ999lmyoKDgV23btn2QB1aog8miTKtrRGyLiN7U4/sPOCJ79rijny9zx7dtc1q792u42qC0Hhulky4eS4" + + "YPFqNjh6T73HOi7iGDYwzz9BZ5afupMVSFy8h38LoE4DYu++KLLx64+OKLtzWg7EmB5ZzfF2C21XHsyC0hF6gdgYyPwPHFvbj0fTbqyEZh" + + "yBNtIvbvlGogppk1C/8CkCw9YsQrKw0TZTMWRRvD0uGych/KkZdnGnm4X+ly1PdRFCX36sqhoIPEfXOcix1dhDOwZ/FeQ08qJbN0Or6Tsqj" + + "/jxIR5EzfqEU5D4H1VJiEtVgMr/ry/iXvXKqrw+pG7LFbtfyu7mPiyfuT9i1b+xu/2/cpG18hLsV33p0uhdJ8E3eyiVzqCF/qCjMR8UOIh" + + "uY/PHECA86JB2YLqlScvMeM+8w3IyRbisXxkjevE1cil4Ad7UvhuDvN+9PMuC6scvodfewL4zYS0pfEa7DFuhuAvrR9+3a6uNjQEnUpnd4" + + "gyieyMKj67ySdE6cwTcfEGDZsWGtEJ2MRcD8Ht/QrLJhU5LUnUp+ZN+XJBUQGM9/TdYpDwC3b0PdjODx3Llu2rD/GJVId2KbxQpTUPHj/j" + + "6n6H3fEpEzsz+vFBi+P8BYB3inPvM3XGqFm5+zs7J6Q8864KdcRpgRhlFI8pBDlDjc0tTAALIYiOoi8E/c6d48ZM+YA6ujkMNpxwA9Ifv" + + "DBB+lA4EfJ6o8FGGuqTwy0sRWVa8Bk8AqFAihVS+1KFiSgnssuu8xNAFCmKaGjwDIz+1A5OvEfLYK4PImDgiQP+/D9RwGK/iqdSoAbjkn" + + "brYDHIbuag2fQiGQEi+fC1eJHjx6tdevWTQf1LW60cQD8E5d5qoFML4zP/wbADcdPz0EECM+i+YFHtDBpFoBnWQGKevVEdfrJpqc8/R8Z" + + "F6/MWQLqvQAAAABJRU5ErkJggg=="; + static final HashMap MAP_TO_CONTEXT_DATA_KEYS = createMap(); static HashMap createMap() { final HashMap map = new HashMap(); - map.put(EventDataKeys.Identity.ADVERTISING_IDENTIFIER, ContextDataKeys.ADVERTISING_IDENTIFIER); + map.put( + EventDataKeys.Identity.ADVERTISING_IDENTIFIER, + ContextDataKeys.ADVERTISING_IDENTIFIER); map.put(EventDataKeys.Lifecycle.APP_ID, ContextDataKeys.APPLICATION_IDENTIFIER); map.put(EventDataKeys.Lifecycle.CARRIER_NAME, ContextDataKeys.CARRIER_NAME); map.put(EventDataKeys.Lifecycle.CRASH_EVENT, ContextDataKeys.CRASH_EVENT_KEY); - map.put(EventDataKeys.Lifecycle.DAILY_ENGAGED_EVENT, ContextDataKeys.DAILY_ENGAGED_EVENT_KEY); + map.put( + EventDataKeys.Lifecycle.DAILY_ENGAGED_EVENT, + ContextDataKeys.DAILY_ENGAGED_EVENT_KEY); map.put(EventDataKeys.Lifecycle.DAY_OF_WEEK, ContextDataKeys.DAY_OF_WEEK); - map.put(EventDataKeys.Lifecycle.DAYS_SINCE_FIRST_LAUNCH, ContextDataKeys.DAYS_SINCE_FIRST_LAUNCH); - map.put(EventDataKeys.Lifecycle.DAYS_SINCE_LAST_LAUNCH, ContextDataKeys.DAYS_SINCE_LAST_LAUNCH); - map.put(EventDataKeys.Lifecycle.DAYS_SINCE_LAST_UPGRADE, ContextDataKeys.DAYS_SINCE_LAST_UPGRADE); + map.put( + EventDataKeys.Lifecycle.DAYS_SINCE_FIRST_LAUNCH, + ContextDataKeys.DAYS_SINCE_FIRST_LAUNCH); + map.put( + EventDataKeys.Lifecycle.DAYS_SINCE_LAST_LAUNCH, + ContextDataKeys.DAYS_SINCE_LAST_LAUNCH); + map.put( + EventDataKeys.Lifecycle.DAYS_SINCE_LAST_UPGRADE, + ContextDataKeys.DAYS_SINCE_LAST_UPGRADE); map.put(EventDataKeys.Lifecycle.DEVICE_NAME, ContextDataKeys.DEVICE_NAME); map.put(EventDataKeys.Lifecycle.DEVICE_RESOLUTION, ContextDataKeys.DEVICE_RESOLUTION); map.put(EventDataKeys.Lifecycle.HOUR_OF_DAY, ContextDataKeys.HOUR_OF_DAY); - map.put(EventDataKeys.Lifecycle.IGNORED_SESSION_LENGTH, ContextDataKeys.IGNORED_SESSION_LENGTH); + map.put( + EventDataKeys.Lifecycle.IGNORED_SESSION_LENGTH, + ContextDataKeys.IGNORED_SESSION_LENGTH); map.put(EventDataKeys.Lifecycle.INSTALL_DATE, ContextDataKeys.INSTALL_DATE); map.put(EventDataKeys.Lifecycle.INSTALL_EVENT, ContextDataKeys.INSTALL_EVENT_KEY); map.put(EventDataKeys.Lifecycle.LAUNCH_EVENT, ContextDataKeys.LAUNCH_EVENT_KEY); map.put(EventDataKeys.Lifecycle.LAUNCHES, ContextDataKeys.LAUNCHES); - map.put(EventDataKeys.Lifecycle.LAUNCHES_SINCE_UPGRADE, ContextDataKeys.LAUNCHES_SINCE_UPGRADE); + map.put( + EventDataKeys.Lifecycle.LAUNCHES_SINCE_UPGRADE, + ContextDataKeys.LAUNCHES_SINCE_UPGRADE); map.put(EventDataKeys.Lifecycle.LOCALE, ContextDataKeys.LOCALE); - map.put(EventDataKeys.Lifecycle.MONTHLY_ENGAGED_EVENT, ContextDataKeys.MONTHLY_ENGAGED_EVENT_KEY); + map.put( + EventDataKeys.Lifecycle.MONTHLY_ENGAGED_EVENT, + ContextDataKeys.MONTHLY_ENGAGED_EVENT_KEY); map.put(EventDataKeys.Lifecycle.OPERATING_SYSTEM, ContextDataKeys.OPERATING_SYSTEM); - map.put(EventDataKeys.Lifecycle.PREVIOUS_SESSION_LENGTH, ContextDataKeys.PREVIOUS_SESSION_LENGTH); + map.put( + EventDataKeys.Lifecycle.PREVIOUS_SESSION_LENGTH, + ContextDataKeys.PREVIOUS_SESSION_LENGTH); map.put(EventDataKeys.Lifecycle.RUN_MODE, ContextDataKeys.RUN_MODE); map.put(EventDataKeys.Lifecycle.UPGRADE_EVENT, ContextDataKeys.UPGRADE_EVENT_KEY); @@ -94,8 +211,7 @@ static final class ContextDataKeys { static final String RUN_MODE = "a.RunMode"; static final String IGNORED_SESSION_LENGTH = "a.ignoredSessionLength"; - private ContextDataKeys() { - } + private ContextDataKeys() {} } // datastore keys @@ -108,15 +224,13 @@ static class DataStoreKeys { static final String SESSION_TIMESTAMP = "SESSION_TIMESTAMP"; static final String EDGE_HOST = "EDGE_HOST"; - private DataStoreKeys() { - } + private DataStoreKeys() {} } static final int DEFAULT_NETWORK_TIMEOUT = 2; static final int DEFAULT_TARGET_SESSION_TIMEOUT_SEC = 30 * 60; // 30 mins - private TargetTestConstants() { - } + private TargetTestConstants() {} static final class Events { static final String TARGET_VIEW_PREFETCH = "TargetViewPrefetchRequest"; @@ -124,22 +238,19 @@ static final class Events { static final String TARGET_RAW_REQUEST = "TargetRawRequest"; static final String TARGET_RAW_NOTIFICATIONS = "TargetRawNotifications"; - private Events() { - } + private Events() {} } static final class EventDataKeys { - private EventDataKeys() { - } + private EventDataKeys() {} static final class Analytics { static final String TRACK_INTERNAL = "trackinternal"; static final String TRACK_ACTION = "action"; static final String CONTEXT_DATA = "contextdata"; - private Analytics() { - } + private Analytics() {} } static final class Audience { @@ -148,8 +259,7 @@ static final class Audience { static final String DPUUID = "dpuuid"; static final String UUID = "uuid"; - private Audience() { - } + private Audience() {} } static final class Configuration { @@ -160,8 +270,7 @@ static final class Configuration { static final String TARGET_ENVIRONMENT_ID = "target.environmentId"; static final String TARGET_SERVER = "target.server"; - private Configuration() { - } + private Configuration() {} } static final class Identity { @@ -172,8 +281,7 @@ static final class Identity { static final String VISITOR_IDS_LIST = "visitoridslist"; static final String ADVERTISING_IDENTIFIER = "advertisingidentifier"; - private Identity() { - } + private Identity() {} } static final class Lifecycle { @@ -204,8 +312,7 @@ static final class Lifecycle { static final String RUN_MODE = "runmode"; static final String UPGRADE_EVENT = "upgradeevent"; - private Lifecycle() { - } + private Lifecycle() {} } static final String EXTENSION_NAME = "com.adobe.module.target"; @@ -249,7 +356,5 @@ private Lifecycle() { static final String IS_RAW_EVENT = "israwevent"; static final String NOTIFICATION = "notification"; static final String RESPONSE_DATA = "responsedata"; - } } - diff --git a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetTests.java b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetTests.java index f7b9e02..ccb5210 100644 --- a/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetTests.java +++ b/code/target/src/test/java/com/adobe/marketing/mobile/target/TargetTests.java @@ -1,17 +1,26 @@ /* - Copyright 2022 Adobe. All rights reserved. - This file is licensed to you under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. You may obtain a copy - of the License at http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software distributed under - the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - OF ANY KIND, either express or implied. See the License for the specific language - governing permissions and limitations under the License. - */ + Copyright 2022 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. +*/ package com.adobe.marketing.mobile.target; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +import android.net.Uri; import com.adobe.marketing.mobile.AdobeCallback; import com.adobe.marketing.mobile.AdobeCallbackWithError; import com.adobe.marketing.mobile.AdobeError; @@ -20,32 +29,20 @@ import com.adobe.marketing.mobile.Target; import com.adobe.marketing.mobile.services.Log; import com.fasterxml.jackson.databind.ObjectMapper; - +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.junit.After; -import org.junit.runner.RunWith; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.when; - -import android.net.Uri; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; @RunWith(MockitoJUnitRunner.Silent.class) @SuppressWarnings("unchecked") @@ -54,12 +51,10 @@ public class TargetTests { private Map responseMap; private AdobeError responseError; - @Mock - private Uri uri; + @Mock private Uri uri; @Before - public void setup() throws Exception { - } + public void setup() throws Exception {} @After public void teardown() { @@ -72,36 +67,49 @@ public void teardown() { public void test_extensionVersion() { // test final String extensionVersion = Target.extensionVersion(); - assertEquals("extensionVersion API should return the correct version string.", "2.0.3", + assertEquals( + "extensionVersion API should return the correct version string.", + "3.0.0", extensionVersion); } @Test public void testPrefetchContent_validprefetchList() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { // test final List prefetchList = new ArrayList<>(); prefetchList.add(new TargetPrefetch("mbox1", null)); prefetchList.add(new TargetPrefetch("mbox2", null)); - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); + + Target.prefetchContent( + prefetchList, + targetParameters, + new AdobeCallback() { + @Override + public void call(String value) { + response = value; } - }).build(); - - Target.prefetchContent(prefetchList, targetParameters, new AdobeCallback() { - @Override - public void call(String value) { - response = value; - } - }); + }); // verify final ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(Event.class); - final ArgumentCaptor> callbackCaptor = ArgumentCaptor.forClass(AdobeCallbackWithError.class); - mobileCoreMockedStatic.verify(() -> MobileCore.dispatchEventWithResponseCallback(eventCaptor.capture(), anyLong(), callbackCaptor.capture())); + final ArgumentCaptor> callbackCaptor = + ArgumentCaptor.forClass(AdobeCallbackWithError.class); + mobileCoreMockedStatic.verify( + () -> + MobileCore.dispatchEventWithResponseCallback( + eventCaptor.capture(), anyLong(), callbackCaptor.capture())); final Event event = eventCaptor.getValue(); final AdobeCallbackWithError callbackWithError = callbackCaptor.getValue(); @@ -111,7 +119,8 @@ public void call(String value) { assertEquals("com.adobe.eventSource.requestContent", event.getSource()); final Map eventData = event.getEventData(); - List> prefetchData = (List>) eventData.get("prefetch"); + List> prefetchData = + (List>) eventData.get("prefetch"); assertNotNull(prefetchData); final Map prefetchMbox1 = prefetchData.get(0); assertNotNull(prefetchMbox1); @@ -119,16 +128,23 @@ public void call(String value) { final Map prefetchMbox2 = prefetchData.get(1); assertNotNull(prefetchMbox2); assertEquals("mbox2", prefetchMbox2.get("name")); - final Map targetParams = (Map) eventData.get("targetparams"); + final Map targetParams = + (Map) eventData.get("targetparams"); assertNotNull(targetParams); - final Map mboxParameters = (Map) targetParams.get("parameters"); + final Map mboxParameters = + (Map) targetParams.get("parameters"); assertNotNull(mboxParameters); assertEquals("mbox_parameter_value", mboxParameters.get("mbox_parameter_key")); final Map responseEventData = new HashMap<>(); responseEventData.put("prefetcherror", null); - final Event responseEvent = new Event.Builder("TargetRequestResponse", "com.adobe.eventType.target", "com.adobe.eventSource.responseContent") - .setEventData(responseEventData).build(); + final Event responseEvent = + new Event.Builder( + "TargetRequestResponse", + "com.adobe.eventType.target", + "com.adobe.eventSource.responseContent") + .setEventData(responseEventData) + .build(); callbackWithError.call(responseEvent); assertNull(response); @@ -142,19 +158,25 @@ public void testPrefetchContent_invalidPrefetchList() { final List prefetchList = new ArrayList<>(); prefetchList.add(null); - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); + + Target.prefetchContent( + prefetchList, + targetParameters, + new AdobeCallback() { + @Override + public void call(String value) { + response = value; } - }).build(); - - Target.prefetchContent(prefetchList, targetParameters, new AdobeCallback() { - @Override - public void call(String value) { - response = value; - } - }); + }); // verify logMockedStatic.verify(() -> Log.warning(anyString(), anyString(), anyString(), any())); @@ -169,24 +191,30 @@ public void testPrefetchContent_invalidPrefetchListWithErrorCallback() { final List prefetchList = new ArrayList<>(); prefetchList.add(null); - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); + + Target.prefetchContent( + prefetchList, + targetParameters, + new AdobeCallbackWithError() { + @Override + public void fail(AdobeError error) { + responseError = error; } - }).build(); - Target.prefetchContent(prefetchList, targetParameters, new AdobeCallbackWithError() { - @Override - public void fail(AdobeError error) { - responseError = error; - } - - @Override - public void call(String value) { - response = value; - } - }); + @Override + public void call(String value) { + response = value; + } + }); // verify logMockedStatic.verify(() -> Log.warning(anyString(), anyString(), anyString(), any())); @@ -199,19 +227,25 @@ public void testPrefetchContent_emptyPrefetchList() { try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { // test final List prefetchList = new ArrayList<>(); - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); + + Target.prefetchContent( + prefetchList, + targetParameters, + new AdobeCallback() { + @Override + public void call(String value) { + response = value; } - }).build(); - - Target.prefetchContent(prefetchList, targetParameters, new AdobeCallback() { - @Override - public void call(String value) { - response = value; - } - }); + }); // verify logMockedStatic.verify(() -> Log.warning(anyString(), anyString(), anyString(), any())); @@ -224,24 +258,30 @@ public void testPrefetchContent_emptyPrefetchListWithErrorCallback() { try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { // test final List prefetchList = new ArrayList<>(); - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); + + Target.prefetchContent( + prefetchList, + targetParameters, + new AdobeCallbackWithError() { + @Override + public void fail(AdobeError error) { + responseError = error; } - }).build(); - - Target.prefetchContent(prefetchList, targetParameters, new AdobeCallbackWithError() { - @Override - public void fail(AdobeError error) { - responseError = error; - } - @Override - public void call(String value) { - response = value; - } - }); + @Override + public void call(String value) { + response = value; + } + }); // verify logMockedStatic.verify(() -> Log.warning(anyString(), anyString(), anyString(), any())); @@ -251,26 +291,38 @@ public void call(String value) { @Test public void testRetrieveLocationContent_validRequestList() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { // test final List requestList = new ArrayList<>(); - requestList.add(new TargetRequest("mbox1", null, "defaultContent1", new AdobeCallback() { - @Override - public void call(String value) { - } - })); - requestList.add(new TargetRequest("mbox2", null, "defaultContent2", new AdobeCallback() { - @Override - public void call(String value) { - } - })); - - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); - } - }).build(); + requestList.add( + new TargetRequest( + "mbox1", + null, + "defaultContent1", + new AdobeCallback() { + @Override + public void call(String value) {} + })); + requestList.add( + new TargetRequest( + "mbox2", + null, + "defaultContent2", + new AdobeCallback() { + @Override + public void call(String value) {} + })); + + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); Target.retrieveLocationContent(requestList, targetParameters); @@ -285,7 +337,8 @@ public void call(String value) { assertEquals("com.adobe.eventSource.requestContent", event.getSource()); final Map eventData = event.getEventData(); - List> requestData = (List>) eventData.get("request"); + List> requestData = + (List>) eventData.get("request"); assertNotNull(requestData); final Map requestMbox1 = requestData.get(0); assertNotNull(requestMbox1); @@ -299,9 +352,11 @@ public void call(String value) { assertEquals("defaultContent2", requestMbox2.get("defaultContent")); assertNotNull(requestMbox2.get("responsePairId")); assertNull(requestMbox2.get("targetparams")); - final Map targetParams = (Map) eventData.get("targetparams"); + final Map targetParams = + (Map) eventData.get("targetparams"); assertNotNull(targetParams); - final Map mboxParameters = (Map) targetParams.get("parameters"); + final Map mboxParameters = + (Map) targetParams.get("parameters"); assertNotNull(mboxParameters); assertEquals("mbox_parameter_value", mboxParameters.get("mbox_parameter_key")); } @@ -313,12 +368,15 @@ public void testRetrieveLocationContent_invalidRequestList() { // test final List requestList = new ArrayList<>(); requestList.add(null); - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); - } - }).build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); Target.retrieveLocationContent(requestList, targetParameters); @@ -332,12 +390,15 @@ public void testRetrieveLocationContent_emptyRequestList() { try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { // test final List requestList = new ArrayList<>(); - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); - } - }).build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); Target.retrieveLocationContent(requestList, targetParameters); @@ -351,23 +412,32 @@ public void testRetrieveLocationContent_emptyMboxNameInRequestList() { try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { // test final List requestList = new ArrayList<>(); - requestList.add(new TargetRequest("", null, "defaultContent", new AdobeCallback() { - @Override - public void call(String value) { - response = value; - } - })); - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); - } - }).build(); + requestList.add( + new TargetRequest( + "", + null, + "defaultContent", + new AdobeCallback() { + @Override + public void call(String value) { + response = value; + } + })); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); Target.retrieveLocationContent(requestList, targetParameters); // verify - logMockedStatic.verify(() -> Log.warning(anyString(), anyString(), anyString(), any()), + logMockedStatic.verify( + () -> Log.warning(anyString(), anyString(), anyString(), any()), Mockito.times(2)); assertEquals("defaultContent", response); } @@ -378,28 +448,37 @@ public void testRetrieveLocationContent_emptyMboxNameInRequestListWithErrorCallb try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { // test final List requestList = new ArrayList<>(); - requestList.add(new TargetRequest("", null, "defaultContent", new AdobeCallbackWithError() { - @Override - public void fail(AdobeError adobeError) { - responseError = adobeError; - } - - @Override - public void call(String value) { - response = value; - } - })); - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); - } - }).build(); + requestList.add( + new TargetRequest( + "", + null, + "defaultContent", + new AdobeCallbackWithError() { + @Override + public void fail(AdobeError adobeError) { + responseError = adobeError; + } + + @Override + public void call(String value) { + response = value; + } + })); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); Target.retrieveLocationContent(requestList, targetParameters); // verify - logMockedStatic.verify(() -> Log.warning(anyString(), anyString(), anyString(), any()), + logMockedStatic.verify( + () -> Log.warning(anyString(), anyString(), anyString(), any()), Mockito.times(2)); assertNull(responseError); assertEquals("defaultContent", response); @@ -411,29 +490,38 @@ public void testRetrieveLocationContent_emptyMboxNameInRequestListWithDataCallba try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { // test final List requestList = new ArrayList<>(); - requestList.add(new TargetRequest("", null, "defaultContent", new AdobeTargetDetailedCallback() { - @Override - public void call(String content, Map data) { - response = content; - responseMap = data; - } - - @Override - public void fail(AdobeError error) { - responseError = error; - } - })); - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); - } - }).build(); + requestList.add( + new TargetRequest( + "", + null, + "defaultContent", + new AdobeTargetDetailedCallback() { + @Override + public void call(String content, Map data) { + response = content; + responseMap = data; + } + + @Override + public void fail(AdobeError error) { + responseError = error; + } + })); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); Target.retrieveLocationContent(requestList, targetParameters); // verify - logMockedStatic.verify(() -> Log.warning(anyString(), anyString(), anyString(), any()), + logMockedStatic.verify( + () -> Log.warning(anyString(), anyString(), anyString(), any()), Mockito.times(2)); assertNull(responseError); assertNull(responseMap); @@ -443,18 +531,22 @@ public void fail(AdobeError error) { @Test public void testDisplayedLocations_validMboxesList() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { // test final List mboxes = new ArrayList(); mboxes.add("mbox1"); mboxes.add("mbox2"); - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); - } - }).build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); Target.displayedLocations(mboxes, targetParameters); // verify @@ -473,9 +565,11 @@ public void testDisplayedLocations_validMboxesList() { assertEquals(2, mboxesList.size()); assertEquals("mbox1", mboxesList.get(0)); assertEquals("mbox2", mboxesList.get(1)); - final Map targetParams = (Map) eventData.get("targetparams"); + final Map targetParams = + (Map) eventData.get("targetparams"); assertNotNull(targetParams); - final Map mboxParameters = (Map) targetParams.get("parameters"); + final Map mboxParameters = + (Map) targetParams.get("parameters"); assertNotNull(mboxParameters); assertEquals(1, mboxParameters.size()); assertEquals("mbox_parameter_value", mboxParameters.get("mbox_parameter_key")); @@ -487,12 +581,15 @@ public void testDisplayedLocations_nullMboxesList() { try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { // test final List mboxes = null; - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); - } - }).build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); Target.displayedLocations(mboxes, targetParameters); // verify @@ -505,12 +602,15 @@ public void testDisplayedLocations_emptyMboxesList() { try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { // test final List mboxes = new ArrayList<>(); - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); - } - }).build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); Target.displayedLocations(mboxes, targetParameters); // verify @@ -520,15 +620,19 @@ public void testDisplayedLocations_emptyMboxesList() { @Test public void testClickedLocation_validMbox() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { // test final String mbox = "mbox1"; - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); - } - }).build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); Target.clickedLocation(mbox, targetParameters); // verify @@ -546,9 +650,11 @@ public void testClickedLocation_validMbox() { final String mboxName = (String) eventData.get("name"); assertNotNull(mboxName); assertEquals("mbox1", mboxName); - final Map targetParams = (Map) eventData.get("targetparams"); + final Map targetParams = + (Map) eventData.get("targetparams"); assertNotNull(targetParams); - final Map mboxParameters = (Map) targetParams.get("parameters"); + final Map mboxParameters = + (Map) targetParams.get("parameters"); assertNotNull(mboxParameters); assertEquals(1, mboxParameters.size()); assertEquals("mbox_parameter_value", mboxParameters.get("mbox_parameter_key")); @@ -560,12 +666,15 @@ public void testClickedLocation_nullMbox() { try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { // test final String mbox = null; - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); - } - }).build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); Target.clickedLocation(mbox, targetParameters); // verify @@ -578,12 +687,15 @@ public void testClickedLocation_emptyMbox() { try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { // test final String mbox = ""; - final TargetParameters targetParameters = new TargetParameters.Builder() - .parameters(new HashMap() { - { - put("mbox_parameter_key", "mbox_parameter_value"); - } - }).build(); + final TargetParameters targetParameters = + new TargetParameters.Builder() + .parameters( + new HashMap() { + { + put("mbox_parameter_key", "mbox_parameter_value"); + } + }) + .build(); Target.clickedLocation(mbox, targetParameters); // verify @@ -593,24 +705,30 @@ public void testClickedLocation_emptyMbox() { @Test public void testGetThirdPartyId() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { // test - Target.getThirdPartyId(new AdobeCallbackWithError() { - @Override - public void fail(AdobeError adobeError) { - responseError = adobeError; - } - - @Override - public void call(String value) { - response = value; - } - }); + Target.getThirdPartyId( + new AdobeCallbackWithError() { + @Override + public void fail(AdobeError adobeError) { + responseError = adobeError; + } + + @Override + public void call(String value) { + response = value; + } + }); // verify final ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(Event.class); - final ArgumentCaptor> callbackCaptor = ArgumentCaptor.forClass(AdobeCallbackWithError.class); - mobileCoreMockedStatic.verify(() -> MobileCore.dispatchEventWithResponseCallback(eventCaptor.capture(), anyLong(), callbackCaptor.capture())); + final ArgumentCaptor> callbackCaptor = + ArgumentCaptor.forClass(AdobeCallbackWithError.class); + mobileCoreMockedStatic.verify( + () -> + MobileCore.dispatchEventWithResponseCallback( + eventCaptor.capture(), anyLong(), callbackCaptor.capture())); final Event event = eventCaptor.getValue(); final AdobeCallbackWithError callbackWithError = callbackCaptor.getValue(); @@ -621,8 +739,13 @@ public void call(String value) { final Map responseEventData = new HashMap<>(); responseEventData.put("thirdpartyid", "someThirdPartryId"); - final Event responseEvent = new Event.Builder("TargetIdentity", "com.adobe.eventType.target", "com.adobe.eventSource.responseIdentity") - .setEventData(responseEventData).build(); + final Event responseEvent = + new Event.Builder( + "TargetIdentity", + "com.adobe.eventType.target", + "com.adobe.eventSource.responseIdentity") + .setEventData(responseEventData) + .build(); callbackWithError.call(responseEvent); assertNull(responseError); @@ -632,7 +755,8 @@ public void call(String value) { @Test public void testSetThirdPartyId() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { // test final String thirdPartyId = "myThirdPartyId"; Target.setThirdPartyId(thirdPartyId); @@ -654,24 +778,30 @@ public void testSetThirdPartyId() { @Test public void testGetTntId() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { // test - Target.getTntId(new AdobeCallbackWithError() { - @Override - public void fail(AdobeError adobeError) { - responseError = adobeError; - } - - @Override - public void call(String value) { - response = value; - } - }); + Target.getTntId( + new AdobeCallbackWithError() { + @Override + public void fail(AdobeError adobeError) { + responseError = adobeError; + } + + @Override + public void call(String value) { + response = value; + } + }); // verify final ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(Event.class); - final ArgumentCaptor> callbackCaptor = ArgumentCaptor.forClass(AdobeCallbackWithError.class); - mobileCoreMockedStatic.verify(() -> MobileCore.dispatchEventWithResponseCallback(eventCaptor.capture(), anyLong(), callbackCaptor.capture())); + final ArgumentCaptor> callbackCaptor = + ArgumentCaptor.forClass(AdobeCallbackWithError.class); + mobileCoreMockedStatic.verify( + () -> + MobileCore.dispatchEventWithResponseCallback( + eventCaptor.capture(), anyLong(), callbackCaptor.capture())); final Event event = eventCaptor.getValue(); final AdobeCallbackWithError callbackWithError = callbackCaptor.getValue(); @@ -682,8 +812,13 @@ public void call(String value) { final Map responseEventData = new HashMap<>(); responseEventData.put("tntid", "someTntId"); - final Event responseEvent = new Event.Builder("TargetIdentity", "com.adobe.eventType.target", "com.adobe.eventSource.responseIdentity") - .setEventData(responseEventData).build(); + final Event responseEvent = + new Event.Builder( + "TargetIdentity", + "com.adobe.eventType.target", + "com.adobe.eventSource.responseIdentity") + .setEventData(responseEventData) + .build(); callbackWithError.call(responseEvent); assertNull(responseError); @@ -693,7 +828,8 @@ public void call(String value) { @Test public void testSetTntId() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { // test final String tntId = "myTntId"; Target.setTntId(tntId); @@ -715,24 +851,30 @@ public void testSetTntId() { @Test public void testGetSessionId() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { // test - Target.getSessionId(new AdobeCallbackWithError() { - @Override - public void fail(AdobeError adobeError) { - responseError = adobeError; - } - - @Override - public void call(String value) { - response = value; - } - }); + Target.getSessionId( + new AdobeCallbackWithError() { + @Override + public void fail(AdobeError adobeError) { + responseError = adobeError; + } + + @Override + public void call(String value) { + response = value; + } + }); // verify final ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(Event.class); - final ArgumentCaptor> callbackCaptor = ArgumentCaptor.forClass(AdobeCallbackWithError.class); - mobileCoreMockedStatic.verify(() -> MobileCore.dispatchEventWithResponseCallback(eventCaptor.capture(), anyLong(), callbackCaptor.capture())); + final ArgumentCaptor> callbackCaptor = + ArgumentCaptor.forClass(AdobeCallbackWithError.class); + mobileCoreMockedStatic.verify( + () -> + MobileCore.dispatchEventWithResponseCallback( + eventCaptor.capture(), anyLong(), callbackCaptor.capture())); final Event event = eventCaptor.getValue(); final AdobeCallbackWithError callbackWithError = callbackCaptor.getValue(); @@ -743,8 +885,13 @@ public void call(String value) { final Map responseEventData = new HashMap<>(); responseEventData.put("sessionid", "someSessionId"); - final Event responseEvent = new Event.Builder("TargetIdentity", "com.adobe.eventType.target", "com.adobe.eventSource.responseIdentity") - .setEventData(responseEventData).build(); + final Event responseEvent = + new Event.Builder( + "TargetIdentity", + "com.adobe.eventType.target", + "com.adobe.eventSource.responseIdentity") + .setEventData(responseEventData) + .build(); callbackWithError.call(responseEvent); assertNull(responseError); @@ -754,7 +901,8 @@ public void call(String value) { @Test public void testSetSessionId() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { // test final String sessionId = "mySessionId"; Target.setSessionId(sessionId); @@ -776,7 +924,8 @@ public void testSetSessionId() { @Test public void testResetExperience() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { // test Target.resetExperience(); @@ -797,7 +946,8 @@ public void testResetExperience() { @Test public void testClearPrefetchCache() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { // test Target.clearPrefetchCache(); @@ -818,7 +968,8 @@ public void testClearPrefetchCache() { @Test public void testSetPreviewRestartDeepLink() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { // test when(uri.toString()).thenReturn("my://deeplink"); Target.setPreviewRestartDeepLink(uri); @@ -840,15 +991,18 @@ public void testSetPreviewRestartDeepLink() { @Test public void testExecuteRawRequest_validRequest() throws IOException { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { final Map executeMbox = new HashMap<>(); executeMbox.put("index", 0); - executeMbox.put("mbox", new HashMap() { - { - put("name", "mbox1"); - } - }); + executeMbox.put( + "mbox", + new HashMap() { + { + put("name", "mbox1"); + } + }); final Map mboxParameters = new HashMap<>(); mboxParameters.put("mbox_parameter_key", "mbox_parameter_value"); @@ -866,40 +1020,50 @@ public void testExecuteRawRequest_validRequest() throws IOException { final Map orderParameters = new HashMap<>(); orderParameters.put("id", "oId"); orderParameters.put("total", 100.34); - orderParameters.put("purchasedProductIds", new ArrayList() { - { - add("pId"); - } - }); + orderParameters.put( + "purchasedProductIds", + new ArrayList() { + { + add("pId"); + } + }); executeMbox.put("order", orderParameters); final List> executeMboxes = new ArrayList>(); executeMboxes.add(executeMbox); final Map request = new HashMap(); - request.put("execute", new HashMap() { - { - put("mboxes", executeMboxes); - } - }); + request.put( + "execute", + new HashMap() { + { + put("mboxes", executeMboxes); + } + }); // test - Target.executeRawRequest(request, new AdobeCallbackWithError>() { - @Override - public void fail(AdobeError adobeError) { - responseError = adobeError; - } - - @Override - public void call(Map value) { - responseMap = value; - } - }); + Target.executeRawRequest( + request, + new AdobeCallbackWithError>() { + @Override + public void fail(AdobeError adobeError) { + responseError = adobeError; + } + + @Override + public void call(Map value) { + responseMap = value; + } + }); // verify final ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(Event.class); - final ArgumentCaptor> callbackCaptor = ArgumentCaptor.forClass(AdobeCallbackWithError.class); - mobileCoreMockedStatic.verify(() -> MobileCore.dispatchEventWithResponseCallback(eventCaptor.capture(), anyLong(), callbackCaptor.capture())); + final ArgumentCaptor> callbackCaptor = + ArgumentCaptor.forClass(AdobeCallbackWithError.class); + mobileCoreMockedStatic.verify( + () -> + MobileCore.dispatchEventWithResponseCallback( + eventCaptor.capture(), anyLong(), callbackCaptor.capture())); final Event event = eventCaptor.getValue(); final AdobeCallbackWithError callbackWithError = callbackCaptor.getValue(); @@ -913,22 +1077,35 @@ public void call(Map value) { expectedRequest.put("israwevent", true); assertTrue(actualRequest.equals(expectedRequest)); - final Map responseData = new ObjectMapper().readValue(getClass().getClassLoader().getResource("json/TARGET_RAW_RESPONSE_EXECUTE.json"), HashMap.class); - final Event responseEvent = new Event.Builder("TargetRawResponse", "com.adobe.eventType.target", "com.adobe.eventSource.responseContent") - .setEventData(responseData).build(); + final Map responseData = + new ObjectMapper() + .readValue( + getClass() + .getClassLoader() + .getResource("json/TARGET_RAW_RESPONSE_EXECUTE.json"), + HashMap.class); + final Event responseEvent = + new Event.Builder( + "TargetRawResponse", + "com.adobe.eventType.target", + "com.adobe.eventSource.responseContent") + .setEventData(responseData) + .build(); callbackWithError.call(responseEvent); assertNull(responseError); assertNotNull(responseMap); final Map execute = (Map) responseMap.get("execute"); assertNotNull(execute); - final List> mboxes = (List>) execute.get("mboxes"); + final List> mboxes = + (List>) execute.get("mboxes"); assertNotNull(mboxes); assertEquals(1, mboxes.size()); final Map mbox1 = mboxes.get(0); assertNotNull(mbox1); assertEquals("mbox1", mbox1.get("name")); - final List> options = (List>) mbox1.get("options"); + final List> options = + (List>) mbox1.get("options"); assertNotNull(options); final Map mbox1Options = options.get(0); assertEquals("html", mbox1Options.get("type")); @@ -943,12 +1120,14 @@ public void testExecuteRawRequest_invalidRequest() { request.put("someKey", "someValue"); // test - Target.executeRawRequest(request, new AdobeCallback>() { - @Override - public void call(Map value) { - responseMap = value; - } - }); + Target.executeRawRequest( + request, + new AdobeCallback>() { + @Override + public void call(Map value) { + responseMap = value; + } + }); // verify logMockedStatic.verify(() -> Log.warning(anyString(), anyString(), anyString())); @@ -963,17 +1142,19 @@ public void testExecuteRawRequest_invalidRequestWithErrorCallback() { request.put("someKey", "someValue"); // test - Target.executeRawRequest(request, new AdobeCallbackWithError>() { - @Override - public void fail(AdobeError adobeError) { - responseError = adobeError; - } - - @Override - public void call(Map value) { - responseMap = value; - } - }); + Target.executeRawRequest( + request, + new AdobeCallbackWithError>() { + @Override + public void fail(AdobeError adobeError) { + responseError = adobeError; + } + + @Override + public void call(Map value) { + responseMap = value; + } + }); // verify logMockedStatic.verify(() -> Log.warning(anyString(), anyString(), anyString())); @@ -987,12 +1168,14 @@ public void testExecuteRawRequest_emptyRequest() { final Map request = new HashMap(); // test - Target.executeRawRequest(request, new AdobeCallback>() { - @Override - public void call(Map value) { - responseMap = value; - } - }); + Target.executeRawRequest( + request, + new AdobeCallback>() { + @Override + public void call(Map value) { + responseMap = value; + } + }); // verify logMockedStatic.verify(() -> Log.warning(anyString(), anyString(), anyString(), any())); @@ -1006,17 +1189,19 @@ public void testExecuteRawRequest_emptyRequestWithErrorCallback() { final Map request = new HashMap(); // test - Target.executeRawRequest(request, new AdobeCallbackWithError>() { - @Override - public void fail(AdobeError adobeError) { - responseError = adobeError; - } - - @Override - public void call(Map value) { - responseMap = value; - } - }); + Target.executeRawRequest( + request, + new AdobeCallbackWithError>() { + @Override + public void fail(AdobeError adobeError) { + responseError = adobeError; + } + + @Override + public void call(Map value) { + responseMap = value; + } + }); // verify logMockedStatic.verify(() -> Log.warning(anyString(), anyString(), anyString(), any())); @@ -1026,21 +1211,26 @@ public void call(Map value) { @Test public void testSendRawNotifications_validRequest() { - try (MockedStatic mobileCoreMockedStatic = Mockito.mockStatic(MobileCore.class)) { + try (MockedStatic mobileCoreMockedStatic = + Mockito.mockStatic(MobileCore.class)) { final Map notification = new HashMap<>(); notification.put("id", "0"); notification.put("timestamp", (long) (System.currentTimeMillis())); notification.put("type", "click"); - notification.put("mbox", new HashMap() { - { - put("name", "mbox1"); - } - }); - notification.put("tokens", new ArrayList() { - { - add("LgG0+YDMHn4X5HqGJVoZ5g=="); - } - }); + notification.put( + "mbox", + new HashMap() { + { + put("name", "mbox1"); + } + }); + notification.put( + "tokens", + new ArrayList() { + { + add("LgG0+YDMHn4X5HqGJVoZ5g=="); + } + }); final Map parameters = new HashMap<>(); parameters.put("mbox_parameter_key", "mbox_parameter_value"); @@ -1058,21 +1248,24 @@ public void testSendRawNotifications_validRequest() { final Map orderParameters = new HashMap<>(); orderParameters.put("id", "oId"); orderParameters.put("total", 100.34); - orderParameters.put("purchasedProductIds", new ArrayList() { - { - add("pId"); - } - }); + orderParameters.put( + "purchasedProductIds", + new ArrayList() { + { + add("pId"); + } + }); notification.put("order", orderParameters); final List> notifications = new ArrayList<>(); notifications.add(notification); - final Map request = new HashMap() { - { - put("notifications", notifications); - } - }; + final Map request = + new HashMap() { + { + put("notifications", notifications); + } + }; // test Target.sendRawNotifications(request); @@ -1098,11 +1291,12 @@ public void testSendRawNotifications_validRequest() { public void testSendRawNotifications_invalidRequest() { try (MockedStatic logMockedStatic = Mockito.mockStatic(Log.class)) { // test - final Map request = new HashMap() { - { - put("someKey", "someValue"); - } - }; + final Map request = + new HashMap() { + { + put("someKey", "someValue"); + } + }; Target.sendRawNotifications(request); // verify diff --git a/code/testapp/build.gradle b/code/testapp/build.gradle deleted file mode 100644 index f67bd27..0000000 --- a/code/testapp/build.gradle +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright 2023 Adobe. All rights reserved. - * This file is licensed to you under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. You may obtain a copy - * of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - * OF ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - */ - -apply plugin: 'com.android.application' - -android { - compileSdkVersion 33 - - defaultConfig { - applicationId "com.adobe.targettestapp" - minSdkVersion 19 - targetSdkVersion 33 - versionCode 1 - versionName "1.0" - - //This says that my test app only wants to use the Phone variant - missingDimensionStrategy 'target', 'phone' - - testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' - - } - - buildTypes { - debug { - debuggable true - } - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -dependencies { - implementation fileTree(include: ['*.jar'], dir: 'libs') - - implementation project(':target') - implementation 'com.adobe.marketing.mobile:core:2.6.1' - implementation 'com.adobe.marketing.mobile:identity:2.0.3' - implementation 'com.adobe.marketing.mobile:lifecycle:2.0.4' - implementation 'com.adobe.marketing.mobile:assurance:2.2.0' - - implementation 'androidx.appcompat:appcompat:1.6.0' - implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.4' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0' -} diff --git a/code/testapp/build.gradle.kts b/code/testapp/build.gradle.kts new file mode 100644 index 0000000..199f53d --- /dev/null +++ b/code/testapp/build.gradle.kts @@ -0,0 +1,48 @@ +/* + * Copyright 2024 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import com.adobe.marketing.mobile.gradle.BuildConstants + +plugins { + id("com.android.application") +} + +val mavenCoreVersion: String by project + +android { + namespace = "com.adobe.targettestapp" + + defaultConfig { + applicationId = "com.adobe.targettestapp" + compileSdk = BuildConstants.Versions.COMPILE_SDK_VERSION + minSdk = BuildConstants.Versions.MIN_SDK_VERSION + targetSdk = BuildConstants.Versions.TARGET_SDK_VERSION + versionCode = BuildConstants.Versions.VERSION_CODE + versionName = BuildConstants.Versions.VERSION_NAME + } + + buildTypes { + getByName(BuildConstants.BuildTypes.RELEASE) { + isMinifyEnabled = false + } + } +} + +dependencies { + implementation(project(":target")) + implementation("com.adobe.marketing.mobile:core:$mavenCoreVersion") + implementation("com.adobe.marketing.mobile:lifecycle:3.0.0") + implementation("com.adobe.marketing.mobile:identity:3.0.0") + implementation("com.adobe.marketing.mobile:assurance:3.0.0") + + implementation("androidx.appcompat:appcompat:1.6.1") + implementation("androidx.constraintlayout:constraintlayout:2.1.4") +} \ No newline at end of file diff --git a/code/testapp/proguard-rules.pro b/code/testapp/proguard-rules.pro deleted file mode 100644 index f1b4245..0000000 --- a/code/testapp/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/code/testapp/src/main/AndroidManifest.xml b/code/testapp/src/main/AndroidManifest.xml index d5878ae..36d5af8 100644 --- a/code/testapp/src/main/AndroidManifest.xml +++ b/code/testapp/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + + diff --git a/code/testapp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/code/testapp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index eca70cf..3ba37b5 100644 --- a/code/testapp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/code/testapp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,4 +1,17 @@ + diff --git a/code/testapp/src/main/res/values/colors.xml b/code/testapp/src/main/res/values/colors.xml index 3ab3e9c..488ac07 100644 --- a/code/testapp/src/main/res/values/colors.xml +++ b/code/testapp/src/main/res/values/colors.xml @@ -1,4 +1,17 @@ + #3F51B5 #303F9F diff --git a/code/testapp/src/main/res/values/strings.xml b/code/testapp/src/main/res/values/strings.xml index 2b8e3ea..1424313 100644 --- a/code/testapp/src/main/res/values/strings.xml +++ b/code/testapp/src/main/res/values/strings.xml @@ -1,3 +1,16 @@ + TargetTestApp Set Tnt Id diff --git a/code/testapp/src/main/res/values/styles.xml b/code/testapp/src/main/res/values/styles.xml index 5885930..6ec2f40 100644 --- a/code/testapp/src/main/res/values/styles.xml +++ b/code/testapp/src/main/res/values/styles.xml @@ -1,3 +1,16 @@ + diff --git a/config/formatter/header.txt b/config/formatter/header.txt deleted file mode 100644 index c87aba3..0000000 --- a/config/formatter/header.txt +++ /dev/null @@ -1,9 +0,0 @@ -Copyright ${year} Adobe. All rights reserved. -This file is licensed to you under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. You may obtain a copy -of the License at http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under -the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -OF ANY KIND, either express or implied. See the License for the specific language -governing permissions and limitations under the License. \ No newline at end of file diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000..7347fd9 --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,21 @@ +# +# Copyright 2022 Adobe. All rights reserved. +# This file is licensed to you under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +# OF ANY KIND, either express or implied. See the License for the specific language +# governing permissions and limitations under the License. +# + +jdk: + - openjdk17 +# before_install: +# - ./custom_setup.sh +install: + - echo "Running a custom install command" + - make ci-publish-maven-local-jitpack +# env: +# MYVAR: "custom environment variable" diff --git a/scripts/version.sh b/scripts/version.sh new file mode 100755 index 0000000..829f9a7 --- /dev/null +++ b/scripts/version.sh @@ -0,0 +1,128 @@ +#!/bin/bash + +# Make this script executable from terminal: +# chmod 755 version.sh +set -e # Any subsequent(*) commands which fail will cause the shell script to exit immediately + +ROOT_DIR=$(git rev-parse --show-toplevel) +LINE="================================================================================" +VERSION_REGEX="[0-9]+\.[0-9]+\.[0-9]+" + +GRADLE_PROPERTIES_FILE=$ROOT_DIR"/code/gradle.properties" +CONSTANTS_FILE=$ROOT_DIR"/code/target/src/phone/java/com/adobe/marketing/mobile/Target.java" +EXTENSION_VERSION_REGEX="^.*String EXTENSION_VERSION *= *" + +help() +{ + echo "" + echo "Usage: $0 -v VERSION -d DEPENDENCIES" + echo "" + echo -e " -v\t- Version to update or verify for the extension. \n\t Example: 3.0.2\n" + echo -e " -d\t- Comma seperated dependecies to update along with their version. \n\t Example: "Core 3.1.1, Edge 3.2.1"\n" + echo -e " -u\t- Updates the version. If this flag is absent, the script verifies if the version is correct\n" + exit 1 # Exit script after printing help +} + +sed_platform() { + # Ensure sed works properly in linux and mac-os. + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' "$@" + else + sed -i "$@" + fi +} + +update() { + echo "Changing version to $VERSION" + + # Replace version in Constants file + echo "Changing 'EXTENSION_VERSION' to '$VERSION' in '$CONSTANTS_FILE'" + sed_platform -E "/$EXTENSION_VERSION_REGEX/{s/$VERSION_REGEX/$VERSION/;}" $CONSTANTS_FILE + + # Replace version in gradle.properties + echo "Changing 'moduleVersion' to '$VERSION' in '$GRADLE_PROPERTIES_FILE'" + sed_platform -E "/^moduleVersion/{s/$VERSION_REGEX/$VERSION/;}" $GRADLE_PROPERTIES_FILE + + # Replace dependencies in gradle.properties + if [ "$DEPENDENCIES" != "none" ]; then + IFS="," + dependenciesArray=($(echo "$DEPENDENCIES")) + + IFS=" " + for dependency in "${dependenciesArray[@]}"; do + dependencyArray=(${dependency// / }) + dependencyName=${dependencyArray[0]} + dependencyVersion=${dependencyArray[1]} + + if [ "$dependencyVersion" != "" ]; then + echo "Changing 'maven${dependencyName}Version' to '$dependencyVersion' in '$GRADLE_PROPERTIES_FILE'" + sed_platform -E "/^maven${dependencyName}Version/{s/$VERSION_REGEX/$dependencyVersion/;}" $GRADLE_PROPERTIES_FILE + fi + done + fi +} + +verify() { + echo "Verifing version is $VERSION" + + if ! grep -E "$EXTENSION_VERSION_REGEX\"$VERSION\"" "$CONSTANTS_FILE" >/dev/null; then + echo "'EXTENSION_VERSION' does not match '$VERSION' in '$CONSTANTS_FILE'" + exit 1 + fi + + if ! grep -E "^moduleVersion=.*$VERSION" "$GRADLE_PROPERTIES_FILE" >/dev/null; then + echo "'moduleVersion' does not match '$VERSION' in '$GRADLE_PROPERTIES_FILE'" + exit 1 + fi + + if [ "$DEPENDENCIES" != "none" ]; then + IFS="," + dependenciesArray=($(echo "$DEPENDENCIES")) + + IFS=" " + for dependency in "${dependenciesArray[@]}"; do + dependencyArray=(${dependency// / }) + dependencyName=${dependencyArray[0]} + dependencyVersion=${dependencyArray[1]} + + if [ "$dependencyVersion" != "" ]; then + if ! grep -E "^maven${dependencyName}Version=.*$dependencyVersion" "$GRADLE_PROPERTIES_FILE" >/dev/null; then + echo "maven${dependencyName}Version does not match '$dependencyVersion' in '$GRADLE_PROPERTIES_FILE'" + exit 1 + fi + fi + done + fi + + echo "Success" +} + + +while getopts "v:d:u" opt +do + case "$opt" in + v ) VERSION="$OPTARG" ;; + d ) DEPENDENCIES="$OPTARG" ;; + u ) UPDATE="true" ;; + ? ) help ;; # Print help in case parameter is non-existent + esac +done + +# Print help in case parameters are empty +if [ -z "$VERSION" ] +then + echo "********** USAGE ERROR **********" + echo "Some or all of the parameters are empty. See usage below:"; + help +fi + + + +echo "$LINE" +if [[ ${UPDATE} = "true" ]]; +then + update +else + verify +fi +echo "$LINE" \ No newline at end of file