Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions IntegrationTests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ Before getting started, install Tuist:
brew install tuist
```

### Environment Variables

mParticle API credentials are required **only for recording** new API interactions:

```bash
export MPARTICLE_API_KEY="your-api-key"
export MPARTICLE_API_SECRET="your-api-secret"
```

**Recording mode (`run_wiremock_recorder.sh`):** Real API keys are required to record actual API responses from mParticle servers.

**Verification mode (`run_clean_integration_tests.sh`):** API keys are **optional**. If not set, the tests will automatically use fake keys (`us1-00000000000000000000000000000000`) that match the WireMock URL patterns. This allows running integration tests without exposing real credentials.

**Note:** Fake keys must match the pattern `us1-[a-f0-9]+` to work with WireMock mappings.

Then generate the Xcode project:

```bash
Expand Down
330 changes: 322 additions & 8 deletions IntegrationTests/Sources/main.swift

Large diffs are not rendered by default.

58 changes: 57 additions & 1 deletion IntegrationTests/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,18 @@ install_application() {

launch_application() {
echo "▶️ Launching application..."

# Launch with environment variables using SIMCTL_CHILD_ prefix
# If not set, the app will use fake keys for verification mode
local launch_cmd="xcrun simctl launch \"$DEVICE_ID\" \"$BUNDLE_ID\""

if [ -n "$MPARTICLE_API_KEY" ]; then
export SIMCTL_CHILD_MPARTICLE_API_KEY="$MPARTICLE_API_KEY"
fi
if [ -n "$MPARTICLE_API_SECRET" ]; then
export SIMCTL_CHILD_MPARTICLE_API_SECRET="$MPARTICLE_API_SECRET"
fi

LAUNCH_OUTPUT=$(xcrun simctl launch "$DEVICE_ID" "$BUNDLE_ID")
APP_PID=$(echo "$LAUNCH_OUTPUT" | awk -F': ' '{print $2}')

Expand All @@ -171,7 +183,7 @@ launch_application() {

wait_for_app_completion() {
echo "⏳ Waiting for app to complete execution..."
local MAX_WAIT=60
local MAX_WAIT=120
local WAIT_COUNT=0
while kill -0 "$APP_PID" 2>/dev/null; do
sleep 1
Expand Down Expand Up @@ -262,3 +274,47 @@ stop_wiremock_with_logs() {
stop_wiremock
}

create_proxy_mappings() {
echo "📝 Creating proxy mappings for recording mode..."

local PROXY_DIR="${MAPPINGS_DIR}/mappings"
mkdir -p "$PROXY_DIR"

# Create proxy-identify.json
cat > "${PROXY_DIR}/proxy-identify.json" << 'EOF'
{
"priority": 1,
"request": {
"urlPathPattern": "/v1/identify"
},
"response": {
"proxyBaseUrl": "https://identity.mparticle.com"
}
}
EOF

# Create proxy-events.json
cat > "${PROXY_DIR}/proxy-events.json" << 'EOF'
{
"priority": 1,
"request": {
"urlPathPattern": "/v2/events"
},
"response": {
"proxyBaseUrl": "https://nativesdks.mparticle.com"
}
}
EOF

echo "✅ Proxy mappings created"
}

remove_proxy_mappings() {
echo "🗑️ Removing proxy mappings for verification mode..."

rm -f "${MAPPINGS_DIR}/mappings/proxy-identify.json" 2>/dev/null || true
rm -f "${MAPPINGS_DIR}/mappings/proxy-events.json" 2>/dev/null || true

echo "✅ Proxy mappings removed"
}

1 change: 1 addition & 0 deletions IntegrationTests/run_clean_integration_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ find_app_path
reset_simulators
find_available_device
find_device
remove_proxy_mappings
escape_mapping_bodies
start_wiremock "verify"
wait_for_wiremock
Expand Down
10 changes: 10 additions & 0 deletions IntegrationTests/run_wiremock_recorder.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ TARGET_URL=${4:-"https://config2.mparticle.com"}
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/common.sh"

# === Check required environment variables for recording ===
if [ -z "$MPARTICLE_API_KEY" ] || [ -z "$MPARTICLE_API_SECRET" ]; then
echo "❌ Error: MPARTICLE_API_KEY and MPARTICLE_API_SECRET environment variables must be set for recording mode"
echo " Real API keys are required to record actual API responses from mParticle servers"
exit 1
fi

# === Build framework and generate project ===
build_framework

Expand All @@ -23,6 +30,9 @@ CONTAINER_NAME="wiremock-recorder"
mkdir -p "${MAPPINGS_DIR}/mappings"
mkdir -p "${MAPPINGS_DIR}/__files"

# Create proxy mappings for recording
create_proxy_mappings

# Trap to ensure cleanup on exit
trap stop_wiremock EXIT INT TERM

Expand Down
2 changes: 2 additions & 0 deletions IntegrationTests/transform_mapping_body.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@
'dlc', # Device Locale
'dn', # Device Name
'dosv', # Device OS Version
'el', # Event Length (duration in milliseconds for timed events)
'en', # Event Number (position in session, e.g., 0, 1, 2...)
'est', # Event Start Time
'iba', # Instruction Base Address (memory address for errors)
'ict', # Init Config Time
'id', # ID (various message/event IDs)
'lud', # Last Update Date
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dt":"rh","id":"e3d7fc9b-15d2-4109-b90b-1dc892641c97","ct":1764796657912,"msgs":[],"ci":{"mpid":6504934091054997508,"ck":{"uid":{"c":"g=7f6d2e60-d81a-4edf-a5d6-996c6f15fa70","e":"2035-11-04T19:37:06.7933933Z"}},"das":"7f6d2e60-d81a-4edf-a5d6-996c6f15fa70"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dt":"rh","id":"a7c8f4d7-aeb2-4f55-91e5-91a267afc382","ct":1764858535905,"err":[{"dt":"err","id":"92e1921b-09d0-434c-a3ef-0484baa5c2c3","ct":1764858535905,"msg":"Invalid Consent State provided - please verify the Consent Purposes that you have defined for this workspace.","code":"invalid_consent"}]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"audience_memberships":[{"audience_id":12345,"audience_name":"Test Audience 1"},{"audience_id":67890,"audience_name":"Test Audience 2"}]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dt":"rh","id":"71a50897-9ff8-4b56-9a73-9ff4281cf33a","ct":1764789344543,"msgs":[],"ci":{"mpid":6504934091054997508,"ck":{"uid":{"c":"g=a6af0b2e-86ae-4d5f-a0d2-2e5d6d71fcb4","e":"2035-11-04T19:37:06.7933933Z"}},"das":"a6af0b2e-86ae-4d5f-a0d2-2e5d6d71fcb4"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dt":"rh","id":"a177f742-06d8-49f7-a8e3-87ef73107560","ct":1764789344635,"msgs":[],"ci":{"mpid":6504934091054997508,"ck":{"uid":{"c":"g=a6af0b2e-86ae-4d5f-a0d2-2e5d6d71fcb4","e":"2035-11-04T19:37:06.7933933Z"}},"das":"a6af0b2e-86ae-4d5f-a0d2-2e5d6d71fcb4"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dt":"rh","id":"109b9248-c587-4f3e-8bcc-f2b294707b6c","ct":1764620922698,"msgs":[],"ci":{"mpid":6504934091054997508,"ck":{"uid":{"c":"g=0b876fb7-59a2-4b88-94c7-0ad23ca58452","e":"2035-11-04T19:37:06.7933933Z"}},"das":"0b876fb7-59a2-4b88-94c7-0ad23ca58452"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dt":"rh","id":"5943ab4c-eeab-48c6-9a8c-9432e7d4f6ae","ct":1764620932703,"msgs":[],"ci":{"mpid":6504934091054997508,"ck":{"uid":{"c":"g=0b876fb7-59a2-4b88-94c7-0ad23ca58452","e":"2035-11-04T19:37:06.7933933Z"}},"das":"0b876fb7-59a2-4b88-94c7-0ad23ca58452"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dt":"rh","id":"62c9bed1-e59c-488f-b30c-f06990223c73","ct":1764611788151,"msgs":[],"ci":{"mpid":6504934091054997508,"ck":{"uid":{"c":"g=cf0a8016-279b-4933-88e5-0644e88ff82c","e":"2035-11-04T19:37:06.7933933Z"}},"das":"cf0a8016-279b-4933-88e5-0644e88ff82c"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dt":"rh","id":"99323d4a-48fa-410f-91df-f8165d1be676","ct":1764613212857,"msgs":[],"ci":{"mpid":6504934091054997508,"ck":{"uid":{"c":"g=3b8cc9d7-af48-43db-8e15-ebff948f6020","e":"2035-11-04T19:37:06.7933933Z"}},"das":"3b8cc9d7-af48-43db-8e15-ebff948f6020"}}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"context":null,"matched_identities":{"customerid":"123456","email":"[email protected]"},"is_ephemeral":false,"mpid":"6504934091054997508","is_logged_in":true}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dt":"rh","id":"845193e5-1f2e-4d0b-8062-685272884982","ct":1764865609530,"err":[{"dt":"err","id":"e00cc073-74b0-4434-ae09-037e4ce2b553","ct":1764865609531,"msg":"Invalid Consent State provided - please verify the Consent Purposes that you have defined for this workspace.","code":"invalid_consent"}]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dt":"rh","id":"4a60510e-7407-4aac-90c2-4f8dba92c78e","ct":1764773430070,"msgs":[],"ci":{"mpid":6504934091054997508,"ck":{"uid":{"c":"g=729f918a-e41a-48f1-9ac9-ec0e762e9963","e":"2035-11-04T19:37:06.7933933Z"}},"das":"729f918a-e41a-48f1-9ac9-ec0e762e9963"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dt":"rh","id":"9182e451-d96e-4e08-b350-6da24ab3f0e7","ct":1764616655403,"msgs":[],"ci":{"mpid":6504934091054997508,"ck":{"uid":{"c":"g=140f02c6-7a15-4c14-92d0-d1dc1532e292","e":"2035-11-04T19:37:06.7933933Z"}},"das":"140f02c6-7a15-4c14-92d0-d1dc1532e292"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dt":"rh","id":"283eb295-b5a3-42ea-8463-783756145b93","ct":1764605104156,"msgs":[],"ci":{"mpid":6504934091054997508,"ck":{"uid":{"c":"g=bc7ddd85-f6cd-4739-9852-faaa18237c16","e":"2035-11-04T19:37:06.7933933Z"}},"das":"bc7ddd85-f6cd-4739-9852-faaa18237c16"}}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"dt":"ac","id":"03fcd379-b420-43a3-9004-c7bb821e0495","ct":1762457821105,"dbg":false,"cue":"appdefined","pmk":["mp_message","com.urbanairship.push.ALERT","alert","a","message","lp_message","gcm.notification.body"],"cnp":"appdefined","soc":0,"oo":false,"lsv":"6.13.0","rdlat":true,"inhd":false,"iasr":false,"wst":"D38F29DF","amw":90,"crml":1024000,"dur":false,"flags":{"AudienceAPI":"False"},"atos":0,"pio":30}
{"dt":"ac","id":"03fcd379-b420-43a3-9004-c7bb821e0495","ct":1762457821105,"dbg":false,"cue":"appdefined","pmk":["mp_message","com.urbanairship.push.ALERT","alert","a","message","lp_message","gcm.notification.body"],"cnp":"appdefined","soc":0,"oo":false,"lsv":"6.13.0","rdlat":true,"inhd":false,"iasr":false,"wst":"D38F29DF","amw":90,"crml":1024000,"dur":false,"flags":{"AudienceAPI":"True"},"atos":0,"pio":30}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
{
"id": "dfb0699f-cad2-32c6-a80f-6cc849905de0",
"request": {
"method": "POST",
"bodyPatterns": [
{
"equalToJson": {
"id": "${json-unit.ignore}",
"ltv": 0,
"msgs": [
{
"dt": "ss",
"id": "${json-unit.ignore}",
"ct": "${json-unit.ignore}",
"pss": "${json-unit.ignore}",
"psl": 0,
"mt": false,
"vc": "off_thread",
"pid": "${json-unit.ignore}"
},
{
"et": "Other",
"id": "${json-unit.ignore}",
"vc": "off_thread",
"dt": "e",
"el": "${json-unit.ignore}",
"ct": "${json-unit.ignore}",
"attrs": {
"consent_status": "opted_in"
},
"sct": "${json-unit.ignore}",
"sid": "${json-unit.ignore}",
"en": "${json-unit.ignore}",
"n": "CCPA Consent Updated",
"est": "${json-unit.ignore}",
"mt": false
}
],
"dt": "h",
"a": "${json-unit.ignore}",
"ai": {
"av": "1.0",
"sideloaded_kits_count": 0,
"bid": "${json-unit.ignore}",
"pir": false,
"fi": true,
"lud": "${json-unit.ignore}",
"arc": "arm64",
"tsv": "90000",
"apn": "com.mparticle.IntegrationTests",
"env": 1,
"abn": "1",
"bsv": "${json-unit.ignore}",
"ict": "${json-unit.ignore}"
},
"ct": "${json-unit.ignore}",
"ck": "${json-unit.ignore}",
"das": "${json-unit.ignore}",
"mpid": 6504934091054997508,
"ui": [
{
"i": "123456",
"n": 1
},
{
"i": "[email protected]",
"n": 7
}
],
"uitl": 60,
"oo": false,
"sdk": "8.40.0",
"di": {
"p": "arm64",
"tz": "-5",
"bid": "${json-unit.ignore}",
"dn": "${json-unit.ignore}",
"dll": "en",
"dma": "Apple",
"dsh": "1440",
"idst": false,
"vid": "${json-unit.ignore}",
"dlc": "${json-unit.ignore}",
"tzn": "America/New_York",
"dp": "iOS",
"dsw": "960",
"dosv": "${json-unit.ignore}",
"it": false,
"dr": "None",
"dmdl": "arm64",
"jb": {
"cydia": false
},
"lat": false,
"arc": "arm64e",
"b": "arm64"
},
"ua": {
"$Age": "45",
"$Gender": "m",
"Achieved Level": "11"
},
"con": {
"ccpa": {
"data_sale_opt_out": {
"d": "ccpa_consent_agreement_v3",
"ts": 1700000000000,
"l": "17 Cherry Tree Lane",
"c": true,
"h": "IDFA:a5d934n0-232f-4afc-2e9a-3832d95zc702"
}
}
},
"stl": 60
},
"ignoreArrayOrder": true,
"ignoreExtraElements": false
}
],
"urlPattern": "/v2/us1-[a-f0-9]+/events"
},
"response": {
"status": 202,
"bodyFileName": "body-ccpa-consent.json",
"headers": {
"X-Cache": "MISS, MISS",
"X-MP-Trace-Id": "6930a8f1ecf5194d379cd641e80ae902",
"Server": "Kestrel",
"X-Origin-Name": "fastlyshield--shield_ssl_cache_iad_kcgs7200038_IAD",
"Date": "Wed, 03 Dec 2025 21:17:37 GMT",
"X-Timer": "S1764796658.870805,VS0,VE47",
"Via": "1.1 varnish, 1.1 varnish",
"Accept-Ranges": "bytes",
"X-Served-By": "cache-iad-kcgs7200038-IAD, cache-lga21937-LGA",
"Vary": "Accept-Encoding",
"X-Cache-Hits": "0, 0",
"Content-Type": "application/json"
}
},
"uuid": "dfb0699f-cad2-32c6-a80f-6cc849905de0"
}
Loading