Skip to content

Commit 5ac723e

Browse files
committed
Adding test and update docs
1 parent 97884a6 commit 5ac723e

File tree

4 files changed

+179
-5
lines changed

4 files changed

+179
-5
lines changed

Docs/RN_API.md

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -824,12 +824,39 @@ appsFlyer.enableTCFDataCollection(true);
824824
### setConsentData
825825
`setConsentData(consentObject): void`
826826

827-
When GDPR applies to the user and your app does not use a CMP compatible with TCF v2.2, use this API to provide the consent data directly to the SDK.<br>
828-
The AppsFlyerConsent object has 2 methods:
827+
When GDPR applies to the user and your app does not use a CMP compatible with TCF v2.2, use this API to provide the consent data directly to the SDK.
829828

830-
1. `AppsFlyerConsent.forNonGDPRUser`: Indicates that GDPR doesn’t apply to the user and generates nonGDPR consent object. This method doesn’t accept any parameters.
831-
2. `AppsFlyerConsent.forGDPRUser`: create an AppsFlyerConsent object with 2 parameters:
829+
**Recommended approach (since v6.16.2):**
830+
Use the `AppsFlyerConsent` constructor:
831+
832+
```javascript
833+
import appsFlyer, {AppsFlyerConsent} from 'react-native-appsflyer';
834+
835+
// Full consent for GDPR user
836+
const consent1 = new AppsFlyerConsent(true, true, true, true);
837+
838+
// No consent for GDPR user
839+
const consent2 = new AppsFlyerConsent(true, false, false, false);
840+
841+
// Non-GDPR user
842+
const consent3 = new AppsFlyerConsent(false);
832843

844+
appsFlyer.setConsentData(consent1);
845+
```
846+
847+
**Constructor parameters:**
848+
| parameter | type | description |
849+
| ---------- |----------|------------------ |
850+
| isUserSubjectToGDPR | boolean | Whether GDPR applies to the user (required) |
851+
| hasConsentForDataUsage | boolean | Consent for data usage (optional) |
852+
| hasConsentForAdsPersonalization | boolean | Consent for ads personalization (optional) |
853+
| hasConsentForAdStorage | boolean | Consent for ad storage (optional) |
854+
855+
**Deprecated approach (still supported):**
856+
The AppsFlyerConsent object has 2 deprecated methods:
857+
858+
1. `AppsFlyerConsent.forNonGDPRUser`: Indicates that GDPR doesn't apply to the user and generates nonGDPR consent object. This method doesn't accept any parameters.
859+
2. `AppsFlyerConsent.forGDPRUser`: create an AppsFlyerConsent object with 2 parameters:
833860

834861
| parameter | type | description |
835862
| ---------- |----------|------------------ |

Docs/RN_EspIntegration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ adb shell am start -W -a android.intent.action.VIEW -d "https://your-onelink-dom
477477
<manifest xmlns:tools="http://schemas.android.com/tools">
478478
<application android:allowBackup="false" tools:replace="android:allowBackup">
479479
```
480+
See [AppsFlyer Android SDK documentation](https://dev.appsflyer.com/hc/docs/install-android-sdk#backup-rules) for more details.
480481

481482
**4. Package attribute deprecated:**
482483
- Remove `package="com.yourapp"` from AndroidManifest.xml

__tests__/compatibility.test.js

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/**
2+
* Backward Compatibility Tests
3+
*
4+
* These tests verify that changes in this branch don't break existing client code patterns.
5+
* Focus: Runtime compatibility and type safety.
6+
*/
7+
8+
import appsFlyer, { AppsFlyerConsent, StoreKitVersion } from '../index';
9+
10+
describe('Backward Compatibility Tests', () => {
11+
afterEach(() => {
12+
jest.clearAllMocks();
13+
});
14+
15+
describe('setConsentData - Runtime Compatibility', () => {
16+
test('setConsentData accepts AppsFlyerConsentType-like plain object at runtime', () => {
17+
// Simulate old code using plain object (AppsFlyerConsentType shape)
18+
const consent = {
19+
isUserSubjectToGDPR: true,
20+
hasConsentForDataUsage: true,
21+
hasConsentForAdsPersonalization: false
22+
};
23+
24+
// Should not throw - native code accepts ReadableMap/NSDictionary
25+
expect(() => appsFlyer.setConsentData(consent)).not.toThrow();
26+
expect(require('../node_modules/react-native/Libraries/BatchedBridge/NativeModules').RNAppsFlyer.setConsentData).toHaveBeenCalled();
27+
});
28+
29+
test('setConsentData accepts AppsFlyerConsent class instance', () => {
30+
// New code using AppsFlyerConsent class
31+
const consent = new AppsFlyerConsent(true, true, false, true);
32+
33+
expect(() => appsFlyer.setConsentData(consent)).not.toThrow();
34+
expect(require('../node_modules/react-native/Libraries/BatchedBridge/NativeModules').RNAppsFlyer.setConsentData).toHaveBeenCalled();
35+
});
36+
37+
test('setConsentData accepts minimal consent object (non-GDPR)', () => {
38+
// Minimal object for non-GDPR user
39+
const consent = {
40+
isUserSubjectToGDPR: false
41+
};
42+
43+
expect(() => appsFlyer.setConsentData(consent)).not.toThrow();
44+
});
45+
46+
test('setConsentData accepts AppsFlyerConsent with all optional fields', () => {
47+
const consent = new AppsFlyerConsent(
48+
true, // isUserSubjectToGDPR
49+
true, // hasConsentForDataUsage
50+
false, // hasConsentForAdsPersonalization
51+
true // hasConsentForAdStorage
52+
);
53+
54+
expect(() => appsFlyer.setConsentData(consent)).not.toThrow();
55+
});
56+
});
57+
58+
describe('StoreKitVersion - Runtime Access', () => {
59+
test('StoreKitVersion is accessible at runtime as object', () => {
60+
expect(StoreKitVersion).toBeDefined();
61+
expect(typeof StoreKitVersion).toBe('object');
62+
expect(StoreKitVersion.SK1).toBe('SK1');
63+
expect(StoreKitVersion.SK2).toBe('SK2');
64+
});
65+
66+
test('StoreKitVersion can be used in PurchaseConnectorConfig', () => {
67+
const config = {
68+
logSubscriptions: true,
69+
logInApps: true,
70+
sandbox: false,
71+
storeKitVersion: StoreKitVersion.SK1
72+
};
73+
74+
expect(config.storeKitVersion).toBe('SK1');
75+
expect(config.storeKitVersion).toBe(StoreKitVersion.SK1);
76+
});
77+
78+
test('StoreKitVersion values are correct strings', () => {
79+
expect(StoreKitVersion.SK1).toBe('SK1');
80+
expect(StoreKitVersion.SK2).toBe('SK2');
81+
expect(typeof StoreKitVersion.SK1).toBe('string');
82+
expect(typeof StoreKitVersion.SK2).toBe('string');
83+
});
84+
});
85+
86+
describe('AppsFlyerConsent - Deprecated Static Methods', () => {
87+
test('AppsFlyerConsent.forGDPRUser still works at runtime', () => {
88+
const consent = AppsFlyerConsent.forGDPRUser(true, false);
89+
90+
expect(consent).toBeInstanceOf(AppsFlyerConsent);
91+
expect(consent.isUserSubjectToGDPR).toBe(true);
92+
expect(consent.hasConsentForDataUsage).toBe(true);
93+
expect(consent.hasConsentForAdsPersonalization).toBe(false);
94+
95+
// Should work with setConsentData
96+
expect(() => appsFlyer.setConsentData(consent)).not.toThrow();
97+
});
98+
99+
test('AppsFlyerConsent.forNonGDPRUser still works at runtime', () => {
100+
const consent = AppsFlyerConsent.forNonGDPRUser();
101+
102+
expect(consent).toBeInstanceOf(AppsFlyerConsent);
103+
expect(consent.isUserSubjectToGDPR).toBe(false);
104+
105+
// Should work with setConsentData
106+
expect(() => appsFlyer.setConsentData(consent)).not.toThrow();
107+
});
108+
});
109+
110+
describe('Callback Behavior - Android CallbackGuard (Transparent)', () => {
111+
test('Callbacks still work with initSdk', () => {
112+
const successCallback = jest.fn();
113+
const errorCallback = jest.fn();
114+
115+
const options = {
116+
devKey: 'test',
117+
appId: '123',
118+
isDebug: true
119+
};
120+
121+
appsFlyer.initSdk(options, successCallback, errorCallback);
122+
123+
// CallbackGuard should be transparent - callbacks should still be callable
124+
expect(require('../node_modules/react-native/Libraries/BatchedBridge/NativeModules').RNAppsFlyer.initSdkWithCallBack).toHaveBeenCalled();
125+
});
126+
127+
test('Callbacks still work with logEvent', () => {
128+
const successCallback = jest.fn();
129+
const errorCallback = jest.fn();
130+
131+
appsFlyer.logEvent('test_event', {}, successCallback, errorCallback);
132+
133+
expect(require('../node_modules/react-native/Libraries/BatchedBridge/NativeModules').RNAppsFlyer.logEvent).toHaveBeenCalled();
134+
});
135+
});
136+
137+
describe('Type Exports - ESLint Compatibility', () => {
138+
test('All expected exports are available', () => {
139+
expect(appsFlyer).toBeDefined();
140+
expect(StoreKitVersion).toBeDefined();
141+
// Note: AppsFlyerPurchaseConnector may not be available if Purchase Connector is disabled
142+
// This test verifies the exports exist, not that they're functional
143+
});
144+
});
145+
});
146+

jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module.exports = {
1515
modulePathIgnorePatterns: ['<rootDir>/demos/'],
1616
testMatch: [
1717
'<rootDir>/__tests__/**/*.test.ts?(x)',
18-
'<rootDir>/__tests__/index.test.js?(x)',
18+
'<rootDir>/__tests__/**/*.test.js?(x)',
1919
],
2020
setupFiles: ['<rootDir>/__tests__/setup.js'],
2121
};

0 commit comments

Comments
 (0)