Skip to content

Conversation

@denischilik
Copy link
Contributor

Background

Added comprehensive integration tests for user attributes, error logging, and timed events. Tests now use environment variables for API credentials instead of hardcoding them.

What Has Changed

  • Added 7 new integration tests: setUserAttribute, incrementUserAttribute, logError, logException, logTimedEvent, getUserAudiences, and Rokt placement
  • Environment variables (MPARTICLE_API_KEY, MPARTICLE_API_SECRET) now used for API credentials with validation
  • Created WireMock recordings for all new test scenarios with proper dynamic field handling
  • Updated documentation with environment variable requirements

Checklist

  • I have performed a self-review of my own code.
  • I have made corresponding changes to the documentation.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have tested this locally.

Additional Notes

All tests use deterministic values (fixed timestamps, static user data) to ensure reproducible WireMock recordings. The transform_mapping_body.py script was enhanced to handle additional dynamic fields (iba, el).

Reference Issue (For employees only. Ignore if you are an outside contributor)

- Made comments more maintainable by removing hardcoded line references
- Comments now reference source methods without specific line numbers
- Tests retrieving user audience memberships via Identity API
- Covers successful audience retrieval with mock data
- Verifies getAudiencesWithCompletionHandler method
- Includes enabled AudienceAPI flag in config for testing
- Add testLogTimedEvent function to test begin/end timed event flow
- Test uses fixed 2-second delay for deterministic behavior
- Add WireMock recordings for timed event API call
- Verify event duration is properly calculated and sent
- Tests error logging with custom event info dictionary
- Verifies error events are properly sent with attributes (cause: slippery floor)
- Covers error severity level and exception handling attributes
- Adds iba (instruction base address) and el (event length) to dynamic fields list
- Fixes timed event mapping to ignore variable event length values
- Tests NSException logging functionality
- Covers exception name, reason, and SDK handling
- Based on ViewController.m logException method
- Fixes dynamic 'is' field in mapping-log-error.json to use ${json-unit.ignore}
- Read MPARTICLE_API_KEY and MPARTICLE_API_SECRET from environment variables in main.swift
- Pass environment variables to simulator using SIMCTL_CHILD_ prefix in common.sh
- Add documentation for required environment variables in README.md
- Validate that environment variables are set before launching tests
- Tests setting predefined user attributes (Age, Gender)
- Covers custom user attributes (Achieved Level)
- Verifies attributes are properly sent in events batch
- Related to SDKE-632
- Tests incrementing a numeric user attribute by a specified value
- Covers setting initial attribute value and incrementing it
- Verifies both SET and INCREMENT operations are properly handled
- Related to user attribute management functionality
@denischilik denischilik requested a review from a team as a code owner December 1, 2025 21:08
@denischilik denischilik force-pushed the test/SDKE-632-Add-New-Integration-Tests branch from 8582544 to fd79312 Compare December 2, 2025 14:18
Copy link
Contributor

@nickolas-dimitrakas nickolas-dimitrakas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

- Add create_proxy_mappings() function to common.sh
- Add remove_proxy_mappings() function to common.sh
- Call create_proxy_mappings in run_wiremock_recorder.sh
- Call remove_proxy_mappings in run_clean_integration_tests.sh
- Remove static proxy mapping files (now generated dynamically)
- Use fake keys (us1-00000000...) when env vars not set
- Real keys only required for recording mode
- Update README.md to document this behavior
- Add key validation in run_wiremock_recorder.sh
Copy link
Collaborator

@BrandonStalnaker BrandonStalnaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets merge this to the blackout branch rather than main. Other than that it looks good.

- Test sets session attribute 'Station' with value 'Classic Rock'
- Session attributes are sent in session end message (dt: se)
- Calls endSession() to trigger sending the attribute
- Added corresponding WireMock mapping and body files
- Test increments session attribute 'Song Count' by 1 (initial value 5 → 6)
- Requires beginSession() since previous test ends session
- Session attributes are sent in session end message (dt: se)
- Added two mappings: session start (ss) and session end (se)
- Based on ViewController.m lines 348-351
Test 14: Toggle CCPA Consent
- Sets CCPA consent state on current user with all fields (consented, document, timestamp, location, hardwareId)
- Logs event to trigger upload that includes consent data in request body
- Verifies CCPA data is transmitted in 'con.ccpa.data_sale_opt_out' field

Based on ViewController.m toggleCCPAConsent method (lines 357-386)
- Test sets GDPR consent state on the current user
- Based on ViewController.m toggleGDPRConsent method (lines 388-416)
- Creates MPGDPRConsent with consented=true, document, timestamp, location, hardwareId
- Adds GDPR consent with purpose 'My GDPR Purpose' to MPConsentState
- Preserves existing CCPA consent state
- Logs event to trigger upload with consent state in 'con' field
- Uses static timestamp for deterministic testing
- Test modifies user identity to add/update the iOS Advertiser ID via Identity API
- Uses static IDFA value for deterministic testing
- Based on ViewController.m logIDFA method (lines 418-429)
- Added corresponding WireMock mapping and body files
- Test sets ATT status to 'authorized' with static timestamp
- Based on ViewController.m requestIDFA method (lines 431-476)
- ATT status is sent in device info ('atts' field)
- ATT timestamp is sent in device info ('attt' field)
- Added corresponding WireMock mapping and body files
@denischilik denischilik changed the base branch from main to blackout/Phase-1 December 4, 2025 19:52
@denischilik
Copy link
Contributor Author

Lets merge this to the blackout branch rather than main. Other than that it looks good.

Thanks switched base branch to blackout/Phase-1

@denischilik denischilik merged commit f6a30a3 into blackout/Phase-1 Dec 8, 2025
13 of 15 checks passed
@denischilik denischilik deleted the test/SDKE-632-Add-New-Integration-Tests branch December 8, 2025 15:23
BrandonStalnaker pushed a commit that referenced this pull request Jan 12, 2026
* refactor: Remove specific line numbers from test comments

- Made comments more maintainable by removing hardcoded line references
- Comments now reference source methods without specific line numbers

* Add integration test for getUserAudiences API

- Tests retrieving user audience memberships via Identity API
- Covers successful audience retrieval with mock data
- Verifies getAudiencesWithCompletionHandler method
- Includes enabled AudienceAPI flag in config for testing

* Add integration test for timed events

- Add testLogTimedEvent function to test begin/end timed event flow
- Test uses fixed 2-second delay for deterministic behavior
- Add WireMock recordings for timed event API call
- Verify event duration is properly calculated and sent

* Add integration test for logError

- Tests error logging with custom event info dictionary
- Verifies error events are properly sent with attributes (cause: slippery floor)
- Covers error severity level and exception handling attributes
- Adds iba (instruction base address) and el (event length) to dynamic fields list
- Fixes timed event mapping to ignore variable event length values

* Add integration test for logException

- Tests NSException logging functionality
- Covers exception name, reason, and SDK handling
- Based on ViewController.m logException method
- Fixes dynamic 'is' field in mapping-log-error.json to use ${json-unit.ignore}

* feat: Pass API keys via environment variables in integration tests

- Read MPARTICLE_API_KEY and MPARTICLE_API_SECRET from environment variables in main.swift
- Pass environment variables to simulator using SIMCTL_CHILD_ prefix in common.sh
- Add documentation for required environment variables in README.md
- Validate that environment variables are set before launching tests

* Add integration test for setUserAttribute

- Tests setting predefined user attributes (Age, Gender)
- Covers custom user attributes (Achieved Level)
- Verifies attributes are properly sent in events batch
- Related to SDKE-632

* Add integration test for incrementUserAttribute

- Tests incrementing a numeric user attribute by a specified value
- Covers setting initial attribute value and incrementing it
- Verifies both SET and INCREMENT operations are properly handled
- Related to user attribute management functionality

* - decrease timeout

* Add mapping for Rokt identify request

* Auto-create/remove proxy mappings in recorder/verification scripts

- Add create_proxy_mappings() function to common.sh
- Add remove_proxy_mappings() function to common.sh
- Call create_proxy_mappings in run_wiremock_recorder.sh
- Call remove_proxy_mappings in run_clean_integration_tests.sh
- Remove static proxy mapping files (now generated dynamically)

* Allow running verification tests without API keys

- Use fake keys (us1-00000000...) when env vars not set
- Real keys only required for recording mode
- Update README.md to document this behavior
- Add key validation in run_wiremock_recorder.sh

* Add integration test for setSessionAttribute

- Test sets session attribute 'Station' with value 'Classic Rock'
- Session attributes are sent in session end message (dt: se)
- Calls endSession() to trigger sending the attribute
- Added corresponding WireMock mapping and body files

* Add integration test for incrementSessionAttribute

- Test increments session attribute 'Song Count' by 1 (initial value 5 → 6)
- Requires beginSession() since previous test ends session
- Session attributes are sent in session end message (dt: se)
- Added two mappings: session start (ss) and session end (se)
- Based on ViewController.m lines 348-351

* Add integration test for CCPA consent state

Test 14: Toggle CCPA Consent
- Sets CCPA consent state on current user with all fields (consented, document, timestamp, location, hardwareId)
- Logs event to trigger upload that includes consent data in request body
- Verifies CCPA data is transmitted in 'con.ccpa.data_sale_opt_out' field

Based on ViewController.m toggleCCPAConsent method (lines 357-386)

* Add integration test for toggleGDPRConsent

- Test sets GDPR consent state on the current user
- Based on ViewController.m toggleGDPRConsent method (lines 388-416)
- Creates MPGDPRConsent with consented=true, document, timestamp, location, hardwareId
- Adds GDPR consent with purpose 'My GDPR Purpose' to MPConsentState
- Preserves existing CCPA consent state
- Logs event to trigger upload with consent state in 'con' field
- Uses static timestamp for deterministic testing

* Add integration test for logIDFA (modify iOS Advertiser ID)

- Test modifies user identity to add/update the iOS Advertiser ID via Identity API
- Uses static IDFA value for deterministic testing
- Based on ViewController.m logIDFA method (lines 418-429)
- Added corresponding WireMock mapping and body files

* Add integration test for setATTStatus (App Tracking Transparency)

- Test sets ATT status to 'authorized' with static timestamp
- Based on ViewController.m requestIDFA method (lines 431-476)
- ATT status is sent in device info ('atts' field)
- ATT timestamp is sent in device info ('attt' field)
- Added corresponding WireMock mapping and body files
denischilik added a commit that referenced this pull request Jan 15, 2026
* Update max parrallel

* test: SDKE-632 Add New Integration Tests (#461)

* refactor: Remove specific line numbers from test comments

- Made comments more maintainable by removing hardcoded line references
- Comments now reference source methods without specific line numbers

* Add integration test for getUserAudiences API

- Tests retrieving user audience memberships via Identity API
- Covers successful audience retrieval with mock data
- Verifies getAudiencesWithCompletionHandler method
- Includes enabled AudienceAPI flag in config for testing

* Add integration test for timed events

- Add testLogTimedEvent function to test begin/end timed event flow
- Test uses fixed 2-second delay for deterministic behavior
- Add WireMock recordings for timed event API call
- Verify event duration is properly calculated and sent

* Add integration test for logError

- Tests error logging with custom event info dictionary
- Verifies error events are properly sent with attributes (cause: slippery floor)
- Covers error severity level and exception handling attributes
- Adds iba (instruction base address) and el (event length) to dynamic fields list
- Fixes timed event mapping to ignore variable event length values

* Add integration test for logException

- Tests NSException logging functionality
- Covers exception name, reason, and SDK handling
- Based on ViewController.m logException method
- Fixes dynamic 'is' field in mapping-log-error.json to use ${json-unit.ignore}

* feat: Pass API keys via environment variables in integration tests

- Read MPARTICLE_API_KEY and MPARTICLE_API_SECRET from environment variables in main.swift
- Pass environment variables to simulator using SIMCTL_CHILD_ prefix in common.sh
- Add documentation for required environment variables in README.md
- Validate that environment variables are set before launching tests

* Add integration test for setUserAttribute

- Tests setting predefined user attributes (Age, Gender)
- Covers custom user attributes (Achieved Level)
- Verifies attributes are properly sent in events batch
- Related to SDKE-632

* Add integration test for incrementUserAttribute

- Tests incrementing a numeric user attribute by a specified value
- Covers setting initial attribute value and incrementing it
- Verifies both SET and INCREMENT operations are properly handled
- Related to user attribute management functionality

* - decrease timeout

* Add mapping for Rokt identify request

* Auto-create/remove proxy mappings in recorder/verification scripts

- Add create_proxy_mappings() function to common.sh
- Add remove_proxy_mappings() function to common.sh
- Call create_proxy_mappings in run_wiremock_recorder.sh
- Call remove_proxy_mappings in run_clean_integration_tests.sh
- Remove static proxy mapping files (now generated dynamically)

* Allow running verification tests without API keys

- Use fake keys (us1-00000000...) when env vars not set
- Real keys only required for recording mode
- Update README.md to document this behavior
- Add key validation in run_wiremock_recorder.sh

* Add integration test for setSessionAttribute

- Test sets session attribute 'Station' with value 'Classic Rock'
- Session attributes are sent in session end message (dt: se)
- Calls endSession() to trigger sending the attribute
- Added corresponding WireMock mapping and body files

* Add integration test for incrementSessionAttribute

- Test increments session attribute 'Song Count' by 1 (initial value 5 → 6)
- Requires beginSession() since previous test ends session
- Session attributes are sent in session end message (dt: se)
- Added two mappings: session start (ss) and session end (se)
- Based on ViewController.m lines 348-351

* Add integration test for CCPA consent state

Test 14: Toggle CCPA Consent
- Sets CCPA consent state on current user with all fields (consented, document, timestamp, location, hardwareId)
- Logs event to trigger upload that includes consent data in request body
- Verifies CCPA data is transmitted in 'con.ccpa.data_sale_opt_out' field

Based on ViewController.m toggleCCPAConsent method (lines 357-386)

* Add integration test for toggleGDPRConsent

- Test sets GDPR consent state on the current user
- Based on ViewController.m toggleGDPRConsent method (lines 388-416)
- Creates MPGDPRConsent with consented=true, document, timestamp, location, hardwareId
- Adds GDPR consent with purpose 'My GDPR Purpose' to MPConsentState
- Preserves existing CCPA consent state
- Logs event to trigger upload with consent state in 'con' field
- Uses static timestamp for deterministic testing

* Add integration test for logIDFA (modify iOS Advertiser ID)

- Test modifies user identity to add/update the iOS Advertiser ID via Identity API
- Uses static IDFA value for deterministic testing
- Based on ViewController.m logIDFA method (lines 418-429)
- Added corresponding WireMock mapping and body files

* Add integration test for setATTStatus (App Tracking Transparency)

- Test sets ATT status to 'authorized' with static timestamp
- Based on ViewController.m requestIDFA method (lines 431-476)
- ATT status is sent in device info ('atts' field)
- ATT timestamp is sent in device info ('attt' field)
- Added corresponding WireMock mapping and body files

* feat: Implement Manual Scene Delegate Support (#462)

* Manual APIs: To allow customers to manually forward these calls to mParticle in case they don’t want it to proxy.
* Backward Compatibility: We should maintain full support for AppDelegate-based apps while adding SceneDelegate support.

Co-authored-by: Denis Chilik <[email protected]>

* fix: Simulator not found failing CI (#472)

* Update max parrallel

* chore: Change setup xcode to use 3rd party action

* Setup specified simulator

* Add fail fast false so all tests run and we can see failures

* chore: SDKE-538 Integrate Test Scripts into CI/CD for iOS (#464)

* chore(ci): add GitHub Actions workflow for integration tests

- Add integration-tests.yml workflow with Colima/Docker setup
- Support headless simulator mode for CI environments
- Upload artifacts (WireMock logs, requests) on test failures

* fix(ci): use Java WireMock instead of Docker for macOS runners

- Replace Colima/Docker with standalone WireMock JAR
- Add run_integration_tests_ci.sh for CI-specific execution
- Use sudo for binding to privileged HTTPS port 443

* - update ranches

* fix(mappings): make timezone field dynamic for CI compatibility

* fix(mappings): make timezone name field dynamic for CI compatibility

* test: change events API version to v3 (intentional break)

* - revert test commit

* - run for all PRs

* Fix testIncrementSessionAttribute timing issue in CI

Replace sleep(1) with uploadWaiter.wait() after beginSession() to ensure
session start is uploaded as a separate request before session end.
This prevents SDK from batching both messages into one request in CI
where execution is faster.

* - address github comments

* chore: Align concurrency and branch rules (#474)

* chore: Align concurrency and branch rules

* Use same simulator setup in secondary platform tests

* Add timeout for native tests

* fix: Flakey test testLoggingCommerceEventToUpload (#475)

* test: Fix device test to not use hard coded country (#476)

* chore: Replace C++ Kit Bracket code (#470)

* chore: Replace CPP Kit Bracket code

* Update max parrallel

* Use setup-xcode action

* Revert "Use setup-xcode action"

This reverts commit 0ffa2c9.

* fix: Crash on launch when upgrading due to NSInvalidUnarchiveOperationException (#469)

fix: handle NSInvalidUnarchiveOperationException on SDK upgrade

* feat: Add trunk rule to detect mParticle API keys (#481)

* fix: Rokt User Attribute Mapping Fix (#478)

* fix: Rokt User Attribute Mapping

* code improvements suggested by Nick

* feat: Add IDFA and IDFV Support for FilteredMParticleUser

* fix: Simulator not found failing CI

* Update .github/workflows/native-tests.yml

Co-authored-by: Nickolas Dimitrakas <[email protected]>

---------

Co-authored-by: Nickolas Dimitrakas <[email protected]>

* fix: Handle Parenthesis in Release Notes (#487)

* Trunk fixes

* fix: Use awk for changelog (#488)

fix: Use awk for Changelog

* Correct merge resolution

* Remove duplicated functions

* chore: Format files with Trunk (#490)

* chore: Trunk fixes

* Manual fixes

* chore: Fix trunk issues run_integration_tests_ci.sh (#491)

* fix: Quotes and braces

* Quotes

* Fix sudo and regex quotes

* Correct merge conflict

* - update "tsv" field to 150600

* Switch workflow to manual execution (we will adjust RN project later)

* Update .github/workflows/build-secondary-platforms.yml

Co-authored-by: Thomson Thomas <[email protected]>

---------

Co-authored-by: denischilik <[email protected]>
Co-authored-by: Brandon Stalnaker <[email protected]>
Co-authored-by: Nickolas Dimitrakas <[email protected]>
Co-authored-by: Thomson Thomas <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants