From 7f868ae5cc0e22df36d8f42c15fc05b151642050 Mon Sep 17 00:00:00 2001 From: Ahmed alaa Date: Thu, 30 May 2024 02:22:59 +0300 Subject: [PATCH 1/9] feat: add supporting variants --- android/native.gradle | 2 +- android/src/main/AndroidManifest.xml | 2 +- .../RNInstabugReactnativeModule.java | 108 ++++++++++++--- .../reactlibrary/utils/ReportUtil.java | 14 -- .../RNInstabugReactnativeModuleTest.java | 123 +++++++++++++----- .../react/example/MainApplication.java | 1 + .../ios/InstabugTests/InstabugSampleTests.m | 33 +++++ examples/default/ios/Podfile.lock | 10 +- .../default/src/screens/SettingsScreen.tsx | 76 +++++++++++ ios/RNInstabug/InstabugReactBridge.h | 4 +- ios/RNInstabug/InstabugReactBridge.m | 33 +++++ ios/native.rb | 2 +- src/models/IBGFeatureRequest.ts | 13 ++ src/modules/Instabug.ts | 51 ++++++++ src/native/NativeInstabug.ts | 47 +++++++ test/mocks/mockInstabug.ts | 3 + test/modules/Instabug.spec.ts | 52 ++++++++ 17 files changed, 496 insertions(+), 78 deletions(-) create mode 100644 src/models/IBGFeatureRequest.ts diff --git a/android/native.gradle b/android/native.gradle index 93cb37d50..2a43fbfee 100644 --- a/android/native.gradle +++ b/android/native.gradle @@ -1,5 +1,5 @@ project.ext.instabug = [ - version: '13.0.3' + version: '13.1.0' ] dependencies { diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index 44ad85bcd..9af27fbd3 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1,4 +1,4 @@ - diff --git a/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java b/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java index 0cd0a3940..9eab5d8db 100644 --- a/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java +++ b/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java @@ -15,6 +15,7 @@ import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableNativeArray; @@ -28,6 +29,7 @@ import com.instabug.library.LogLevel; import com.instabug.library.ReproConfigurations; import com.instabug.library.core.InstabugCore; +import com.instabug.library.featuresflags.model.IBGFeatureFlag; import com.instabug.library.internal.module.InstabugLocale; import com.instabug.library.invocation.InstabugInvocationEvent; import com.instabug.library.logging.InstabugLog; @@ -39,6 +41,7 @@ import com.instabug.reactlibrary.utils.MainThreadHandler; import com.instabug.reactlibrary.utils.RNTouchedViewExtractor; + import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; @@ -48,6 +51,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; @@ -98,6 +102,7 @@ public void removeListeners(Integer count) { /** * Enables or disables Instabug functionality. + * * @param isEnabled A boolean to enable/disable Instabug. */ @ReactMethod @@ -106,7 +111,7 @@ public void setEnabled(final boolean isEnabled) { @Override public void run() { try { - if(isEnabled) + if (isEnabled) Instabug.enable(); else Instabug.disable(); @@ -119,10 +124,11 @@ public void run() { /** * Initializes the SDK. - * @param token The token that identifies the app. You can find it on your dashboard. + * + * @param token The token that identifies the app. You can find it on your dashboard. * @param invocationEventValues The events that invoke the SDK's UI. - * @param logLevel The level of detail in logs that you want to print. - * @param codePushVersion The Code Push version to be used for all reports. + * @param logLevel The level of detail in logs that you want to print. + * @param codePushVersion The Code Push version to be used for all reports. */ @ReactMethod public void init( @@ -148,8 +154,8 @@ public void run() { .setInvocationEvents(invocationEvents) .setLogLevel(parsedLogLevel); - if(codePushVersion != null) { - if(Instabug.isBuilt()) { + if (codePushVersion != null) { + if (Instabug.isBuilt()) { Instabug.setCodePushVersion(codePushVersion); } else { builder.setCodePushVersion(codePushVersion); @@ -315,7 +321,7 @@ public void run() { * * @param userEmail User's default email * @param userName Username. - * @param userId User's ID + * @param userId User's ID */ @ReactMethod public void identifyUser( @@ -735,15 +741,15 @@ public void addFileAttachmentWithDataToReport(String data, String fileName) { private WritableMap convertFromHashMapToWriteableMap(HashMap hashMap) { WritableMap writableMap = new WritableNativeMap(); - for(int i = 0; i < hashMap.size(); i++) { + for (int i = 0; i < hashMap.size(); i++) { Object key = hashMap.keySet().toArray()[i]; Object value = hashMap.get(key); - writableMap.putString((String) key,(String) value); + writableMap.putString((String) key, (String) value); } return writableMap; } - private static JSONObject objectToJSONObject(Object object){ + private static JSONObject objectToJSONObject(Object object) { Object json = null; JSONObject jsonObject = null; try { @@ -760,13 +766,12 @@ private static JSONObject objectToJSONObject(Object object){ private WritableArray convertArrayListToWritableArray(List arrayList) { WritableArray writableArray = new WritableNativeArray(); - for(int i = 0; i < arrayList.size(); i++) { + for (int i = 0; i < arrayList.size(); i++) { Object object = arrayList.get(i); - if(object instanceof String) { + if (object instanceof String) { writableArray.pushString((String) object); - } - else { + } else { JSONObject jsonObject = objectToJSONObject(object); writableArray.pushMap((WritableMap) jsonObject); } @@ -822,7 +827,7 @@ public void run() { * Shows the welcome message in a specific mode. * * @param welcomeMessageMode An enum to set the welcome message mode to - * live, or beta. + * live, or beta. */ @ReactMethod public void showWelcomeMessageWithMode(final String welcomeMessageMode) { @@ -844,7 +849,7 @@ public void run() { * Sets the welcome message mode to live, beta or disabled. * * @param welcomeMessageMode An enum to set the welcome message mode to - * live, beta or disabled. + * live, beta or disabled. */ @ReactMethod public void setWelcomeMessageMode(final String welcomeMessageMode) { @@ -904,7 +909,7 @@ public void run() { @ReactMethod public void networkLog(String jsonObject) throws JSONException { NetworkLog networkLog = new NetworkLog(); - String date = System.currentTimeMillis()+""; + String date = System.currentTimeMillis() + ""; networkLog.setDate(date); JSONObject newJSONObject = new JSONObject(jsonObject); networkLog.setUrl(newJSONObject.getString("url")); @@ -968,7 +973,6 @@ public void run() { * Reports that the screen name been changed (Current View). * * @param screenName string containing the screen name - * */ @ReactMethod public void reportCurrentViewChange(final String screenName) { @@ -991,7 +995,6 @@ public void run() { * Reports that the screen has been changed (Repro Steps) the screen sent to this method will be the 'current view' on the dashboard * * @param screenName string containing the screen name - * */ @ReactMethod public void reportScreenChange(final String screenName) { @@ -1001,7 +1004,7 @@ public void run() { try { Method method = getMethod(Class.forName("com.instabug.library.Instabug"), "reportScreenChange", Bitmap.class, String.class); if (method != null) { - method.invoke(null , null, screenName); + method.invoke(null, null, screenName); } } catch (Exception e) { e.printStackTrace(); @@ -1010,6 +1013,9 @@ public void run() { }); } + /** + * @deprecated see {@link #addFeatureFlags(ReadableArray)} + */ @ReactMethod public void addExperiments(final ReadableArray experiments) { MainThreadHandler.runOnMainThread(new Runnable() { @@ -1026,6 +1032,9 @@ public void run() { }); } + /** + * @deprecated see {@link #removeFeatureFlags(ReadableArray)} + */ @ReactMethod public void removeExperiments(final ReadableArray experiments) { MainThreadHandler.runOnMainThread(new Runnable() { @@ -1042,6 +1051,9 @@ public void run() { }); } + /** + * @deprecated see {@link #removeAllFeatureFlags()} + */ @ReactMethod public void clearAllExperiments() { MainThreadHandler.runOnMainThread(new Runnable() { @@ -1056,6 +1068,60 @@ public void run() { }); } + @ReactMethod + public void addFeatureFlags(final ReadableMap featureFlagsMap) { + MainThreadHandler.runOnMainThread(new Runnable() { + @Override + public void run() { + try { + Iterator> iterator = featureFlagsMap.getEntryIterator(); + ArrayList featureFlags = new ArrayList<>(); + while (iterator.hasNext()) { + Map.Entry item = iterator.next(); + String variant = (String) item.getValue(); + String name = item.getKey(); + featureFlags.add(new IBGFeatureFlag(name, variant.isEmpty() ? null : variant)); + } + if (!featureFlags.isEmpty()) { + Instabug.addFeatureFlags(featureFlags); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + @ReactMethod + public void removeFeatureFlags(final ReadableArray experiments) { + MainThreadHandler.runOnMainThread(new Runnable() { + @Override + public void run() { + try { + Object[] objectArray = ArrayUtil.toArray(experiments); + String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class); + Instabug.removeFeatureFlag(Arrays.asList(stringArray)); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + @ReactMethod + public void removeAllFeatureFlags() { + MainThreadHandler.runOnMainThread(new Runnable() { + @Override + public void run() { + try { + Instabug.removeAllFeatureFlags(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + @ReactMethod public void willRedirectToStore() { MainThreadHandler.runOnMainThread(new Runnable() { @@ -1074,7 +1140,7 @@ public void run() { * Map between the exported JS constant and the arg key in {@link ArgsRegistry}. * The constant name and the arg key should match to be able to resolve the * constant with its actual value from the {@link ArgsRegistry} maps. - * + *

* This is a workaround, because RN cannot resolve enums in the constants map. */ @Override diff --git a/android/src/main/java/com/instabug/reactlibrary/utils/ReportUtil.java b/android/src/main/java/com/instabug/reactlibrary/utils/ReportUtil.java index a44da1882..d33387e7d 100644 --- a/android/src/main/java/com/instabug/reactlibrary/utils/ReportUtil.java +++ b/android/src/main/java/com/instabug/reactlibrary/utils/ReportUtil.java @@ -64,18 +64,4 @@ public static Report createReport(ReadableArray tags, ReadableArray consoleLogs, return report; } - public static WritableArray parseConsoleLogs(ArrayList consoleLogs) { - WritableArray writableArray = new WritableNativeArray(); - - for(int i = 0; i < consoleLogs.size(); i++) { - try { - writableArray.pushString(consoleLogs.get(i).toJson()); - } catch (Exception e) { - e.printStackTrace(); - } - - } - - return writableArray; - } } diff --git a/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java b/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java index beee65c4b..1be271f8b 100644 --- a/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java +++ b/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java @@ -18,6 +18,7 @@ import com.instabug.library.IssueType; import com.instabug.library.ReproConfigurations; import com.instabug.library.ReproMode; +import com.instabug.library.featuresflags.model.IBGFeatureFlag; import com.instabug.library.internal.module.InstabugLocale; import com.instabug.library.ui.onboarding.WelcomeMessage; import com.instabug.reactlibrary.utils.MainThreadHandler; @@ -38,6 +39,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; @@ -62,8 +64,8 @@ public class RNInstabugReactnativeModuleTest { // Mock Objects private MockedStatic mockLooper; - private MockedStatic mockMainThreadHandler; - private MockedStatic mockInstabug; + private MockedStatic mockMainThreadHandler; + private MockedStatic mockInstabug; @Before public void mockMainThreadHandler() throws Exception { @@ -87,6 +89,7 @@ public Boolean answer(InvocationOnMock invocation) throws Throwable { Mockito.doAnswer(handlerPostAnswer).when(MainThreadHandler.class); MainThreadHandler.runOnMainThread(any(Runnable.class)); } + @After public void tearDown() { // Remove static mocks @@ -129,7 +132,7 @@ public void tearDown() { // when rnModule.setUserAttribute(key, value); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.setUserAttribute(key, value); } @@ -141,7 +144,7 @@ public void tearDown() { // when rnModule.removeUserAttribute(key); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.removeUserAttribute(key); } @@ -152,7 +155,7 @@ public void tearDown() { // when rnModule.clearAllUserAttributes(); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.clearAllUserAttributes(); } @@ -163,12 +166,12 @@ public void tearDown() { final String[] keysArray = themesArgs.keySet().toArray(new String[0]); // when - for (String key: keysArray) { + for (String key : keysArray) { rnModule.setColorTheme(key); } // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); for (String key : keysArray) { InstabugColorTheme theme = themesArgs.get(key); Instabug.setColorTheme(theme); @@ -183,7 +186,7 @@ public void tearDown() { // when rnModule.setUserData(data); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.setUserData(data); } @@ -195,7 +198,7 @@ public void tearDown() { // when rnModule.setPrimaryColor(color); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.setPrimaryColor(color); } @@ -241,7 +244,7 @@ public void testIdentifyUserWithId() { // when rnModule.resetTags(); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.resetTags(); } @@ -252,7 +255,7 @@ public void testIdentifyUserWithId() { // when rnModule.logOut(); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.logoutUser(); } @@ -264,7 +267,7 @@ public void testIdentifyUserWithId() { // when rnModule.logUserEvent(eventName); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.logUserEvent(eventName); } @@ -275,7 +278,7 @@ public void testIdentifyUserWithId() { // when rnModule.clearFileAttachment(); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.clearFileAttachment(); } @@ -317,7 +320,7 @@ public void testIdentifyUserWithId() { } // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); for (String key : keysArray) { WelcomeMessage.State state = (WelcomeMessage.State) args.get(key); Instabug.showWelcomeMessage(state); @@ -336,7 +339,7 @@ public void testIdentifyUserWithId() { } // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); for (String key : keysArray) { WelcomeMessage.State state = args.get(key); Instabug.setWelcomeMessageState(state); @@ -350,7 +353,7 @@ public void testIdentifyUserWithId() { // when rnModule.show(); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.show(); } @@ -361,7 +364,7 @@ public void testIdentifyUserWithId() { // when rnModule.setSessionProfilerEnabled(true); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.setSessionProfilerState(Feature.State.ENABLED); } @@ -372,7 +375,7 @@ public void testIdentifyUserWithId() { // when rnModule.setSessionProfilerEnabled(false); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.setSessionProfilerState(Feature.State.DISABLED); } @@ -386,8 +389,8 @@ public void testIdentifyUserWithId() { // when rnModule.appendTags(array); // then - verify(Instabug.class,times(1)); - String [] expectedArray = {"tag1", "tag2"}; + verify(Instabug.class, times(1)); + String[] expectedArray = {"tag1", "tag2"}; Instabug.addTags(expectedArray); } @@ -405,7 +408,7 @@ public void testIdentifyUserWithId() { when(Arguments.createArray()).thenReturn(new JavaOnlyArray()); rnModule.getTags(promise); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.getTags(); WritableArray expectedArray = new JavaOnlyArray(); expectedArray.pushString("tag1"); @@ -426,7 +429,7 @@ public void testIdentifyUserWithId() { when(Instabug.getUserAttribute(key)).thenReturn(value); rnModule.getUserAttribute(key, promise); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.getUserAttribute(key); verify(promise).resolve(value); } @@ -443,7 +446,7 @@ public void testIdentifyUserWithId() { when(Instabug.getAllUserAttributes()).thenReturn(userAttributes); rnModule.getAllUserAttributes(promise); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.getAllUserAttributes(); WritableMap expectedMap = new JavaOnlyMap(); expectedMap.putString("email", "sali@instabug.com"); @@ -463,7 +466,7 @@ public void testIdentifyUserWithId() { } // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); for (String key : keysArray) { final InstabugLocale instabugLocale = args.get(key); final Locale locale = new Locale(instabugLocale.getCode(), instabugLocale.getCountry()); @@ -486,7 +489,7 @@ public void testIdentifyUserWithId() { } // then - verify(Instabug.class ,VerificationModeFactory.atLeastOnce()); + verify(Instabug.class, VerificationModeFactory.atLeastOnce()); Instabug.setCustomTextPlaceHolders(Matchers.any(InstabugCustomTextPlaceHolder.class)); // access placeHolders field by reflection @@ -495,10 +498,10 @@ public void testIdentifyUserWithId() { getDeclaredField("placeHolders"); privateStringField.setAccessible(true); InstabugCustomTextPlaceHolder placeHolders = (InstabugCustomTextPlaceHolder) privateStringField.get(rnModule); - for (String key : keys) { - InstabugCustomTextPlaceHolder.Key placeHolder = args.get(key); - Assert.assertEquals(placeHolders.get(placeHolder), key); - } + for (String key : keys) { + InstabugCustomTextPlaceHolder.Key placeHolder = args.get(key); + Assert.assertEquals(placeHolders.get(placeHolder), key); + } } catch (NoSuchFieldException | IllegalAccessException nsfe) { throw new RuntimeException(nsfe); } @@ -513,7 +516,7 @@ public void testIdentifyUserWithId() { // then verify(Instabug.class, VerificationModeFactory.times(1)); - privateStringMethod.invoke("reportCurrentViewChange","screen"); + privateStringMethod.invoke("reportCurrentViewChange", "screen"); } @Test @@ -525,7 +528,7 @@ public void testIdentifyUserWithId() { // then verify(Instabug.class, VerificationModeFactory.times(1)); - privateStringMethod.invoke("reportScreenChange", null,"screen"); + privateStringMethod.invoke("reportScreenChange", null, "screen"); } @@ -540,7 +543,7 @@ public void testIdentifyUserWithId() { rnModule.addExperiments(array); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); List expectedList = new ArrayList(); expectedList.add("exp1"); expectedList.add("exp2"); @@ -558,7 +561,7 @@ public void testIdentifyUserWithId() { rnModule.removeExperiments(array); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); List expectedList = new ArrayList(); expectedList.add("exp1"); expectedList.add("exp2"); @@ -573,10 +576,62 @@ public void testIdentifyUserWithId() { rnModule.clearAllExperiments(); // then - verify(Instabug.class,times(1)); + verify(Instabug.class, times(1)); Instabug.clearAllExperiments(); } + @Test + public void testAddFeatureFlags() { + // given + JavaOnlyMap map = new JavaOnlyMap(); + map.putString("key1", "value1"); + map.putString("key2", "value2"); + + // when + rnModule.addFeatureFlags(map); + + // then + Iterator> iterator = map.getEntryIterator(); + ArrayList featureFlags = new ArrayList<>(); + while (iterator.hasNext()) { + Map.Entry item = iterator.next(); + featureFlags.add(new IBGFeatureFlag(item.getKey(), (String) item.getValue())); + } + + mockInstabug.verify(() -> Instabug.addFeatureFlags(featureFlags)); + + } + + @Test + public void testRemoveFeatureFlags() { + // given + JavaOnlyArray array = new JavaOnlyArray(); + array.pushString("exp1"); + array.pushString("exp2"); + + // when + rnModule.removeFeatureFlags(array); + + // then + List expectedList = new ArrayList(); + for (Object o : array.toArrayList()) { + expectedList.add((String) o); + } + mockInstabug.verify(() -> Instabug.removeFeatureFlag(expectedList)); + + } + + @Test + public void testRemoveAllFeatureFlags() { + // given + + // when + rnModule.removeAllFeatureFlags(); + + // then + mockInstabug.verify(() -> Instabug.removeAllFeatureFlags()); + } + @Test public void testWillRedirectToStore() { // when diff --git a/examples/default/android/app/src/main/java/com/instabug/react/example/MainApplication.java b/examples/default/android/app/src/main/java/com/instabug/react/example/MainApplication.java index a988f0a84..1db77bfa7 100644 --- a/examples/default/android/app/src/main/java/com/instabug/react/example/MainApplication.java +++ b/examples/default/android/app/src/main/java/com/instabug/react/example/MainApplication.java @@ -57,5 +57,6 @@ public void onCreate() { DefaultNewArchitectureEntryPoint.load(); } ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); + } } diff --git a/examples/default/ios/InstabugTests/InstabugSampleTests.m b/examples/default/ios/InstabugTests/InstabugSampleTests.m index bf4edbd43..9b40064a1 100644 --- a/examples/default/ios/InstabugTests/InstabugSampleTests.m +++ b/examples/default/ios/InstabugTests/InstabugSampleTests.m @@ -442,4 +442,37 @@ - (void)testClearAllExperiments { OCMVerify([mock clearAllExperiments]); } +- (void)testAddFeatureFlags { + id mock = OCMClassMock([Instabug class]); + NSDictionary *featureFlagsMap = @{ @"key13" : @"value1", @"key2" : @"value2"}; + + OCMStub([mock addFeatureFlags :[OCMArg any]]); + [self.instabugBridge addFeatureFlags:featureFlagsMap]; + OCMVerify([mock addFeatureFlags: [OCMArg checkWithBlock:^(id value) { + NSArray *featureFlags = value; + NSString* firstFeatureFlagName = [featureFlags objectAtIndex:0 ].name; + NSString* firstFeatureFlagKey = [[featureFlagsMap allKeys] objectAtIndex:0] ; + if([ firstFeatureFlagKey isEqualToString: firstFeatureFlagName]){ + return YES; + } + return NO; + }]]); +} + +- (void)testRemoveFeatureFlags { + id mock = OCMClassMock([Instabug class]); + NSArray *experiments = @[@"exp1", @"exp2"]; + + OCMStub([mock removeFeatureFlags:experiments]); + [self.instabugBridge removeFeatureFlags:experiments]; + OCMVerify([mock removeFeatureFlags:experiments]); +} + +- (void)testRemoveAllFeatureFlags { + id mock = OCMClassMock([Instabug class]); + OCMStub([mock removeAllFeatureFlags]); + [self.instabugBridge removeAllFeatureFlags]; + OCMVerify([mock removeAllFeatureFlags]); +} + @end diff --git a/examples/default/ios/Podfile.lock b/examples/default/ios/Podfile.lock index f89a967e5..d3720dd7e 100644 --- a/examples/default/ios/Podfile.lock +++ b/examples/default/ios/Podfile.lock @@ -97,7 +97,7 @@ PODS: - hermes-engine (0.72.3): - hermes-engine/Pre-built (= 0.72.3) - hermes-engine/Pre-built (0.72.3) - - Instabug (13.0.5) + - Instabug (13.1.0) - instabug-reactnative-ndk (0.1.0): - RCT-Folly (= 2021.07.22.00) - React-Core @@ -532,7 +532,7 @@ PODS: - RCT-Folly (= 2021.07.22.00) - React-Core - RNInstabug (13.0.5): - - Instabug (= 13.0.5) + - Instabug (= 13.1.0) - React-Core - RNReanimated (3.5.4): - DoubleConversion @@ -798,7 +798,7 @@ SPEC CHECKSUMS: Google-Maps-iOS-Utils: f77eab4c4326d7e6a277f8e23a0232402731913a GoogleMaps: 032f676450ba0779bd8ce16840690915f84e57ac hermes-engine: 10fbd3f62405c41ea07e71973ea61e1878d07322 - Instabug: 54e81af4202faf8ed1e26e47f8816d6c42245d1e + Instabug: 3d55eff7ea55adf22df404908a2b954b8b585c29 instabug-reactnative-ndk: 960119a69380cf4cbe47ccd007c453f757927d17 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OCMock: 300b1b1b9155cb6378660b981c2557448830bdc6 @@ -841,7 +841,7 @@ SPEC CHECKSUMS: React-utils: bcb57da67eec2711f8b353f6e3d33bd8e4b2efa3 ReactCommon: 3ccb8fb14e6b3277e38c73b0ff5e4a1b8db017a9 RNGestureHandler: 6e46dde1f87e5f018a54fe5d40cd0e0b942b49ee - RNInstabug: 5284a7dc148edd3184a6510e9bae0f9f5ef8b254 + RNInstabug: cdc98a25e420c131e539d3a74eae00e56d1433e1 RNReanimated: ab2e96c6d5591c3dfbb38a464f54c8d17fb34a87 RNScreens: b21dc57dfa2b710c30ec600786a3fc223b1b92e7 RNSVG: 80584470ff1ffc7994923ea135a3e5ad825546b9 @@ -852,4 +852,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: ad82a989387dcdb1ce80667f16b998a2644cf0b2 -COCOAPODS: 1.12.0 +COCOAPODS: 1.14.3 diff --git a/examples/default/src/screens/SettingsScreen.tsx b/examples/default/src/screens/SettingsScreen.tsx index 618de54a2..6390bb7a0 100644 --- a/examples/default/src/screens/SettingsScreen.tsx +++ b/examples/default/src/screens/SettingsScreen.tsx @@ -17,8 +17,12 @@ export const SettingsScreen: React.FC = () => { const [userID, setUserID] = useState(''); const [userAttributeKey, setUserAttributeKey] = useState(''); const [userAttributeValue, setUserAttributeValue] = useState(''); + const [featureFlagName, setFeatureFlagName] = useState(''); + const [featureFlagVariant, setfeatureFlagVariant] = useState(''); + const toast = useToast(); const [userAttributesFormError, setUserAttributesFormError] = useState({}); + const [featureFlagFormError, setFeatureFlagFormError] = useState({}); const validateUserAttributeForm = () => { const errors: any = {}; @@ -31,6 +35,15 @@ export const SettingsScreen: React.FC = () => { setUserAttributesFormError(errors); return Object.keys(errors).length === 0; }; + const validateFeatureFlagForm = () => { + const errors: any = {}; + if (featureFlagName.length === 0) { + errors.featureFlagName = 'Value is required'; + } + setFeatureFlagFormError(errors); + return Object.keys(errors).length === 0; + }; + const styles = StyleSheet.create({ inputWrapper: { padding: 4, @@ -60,6 +73,37 @@ export const SettingsScreen: React.FC = () => { setUserAttributeValue(''); } }; + const saveFeatureFlags = () => { + if (validateFeatureFlagForm()) { + Instabug.addFeatureFlag({ + name: featureFlagName, + variant: featureFlagVariant, + }); + toast.show({ + description: 'Feature Flag added successfully', + }); + setFeatureFlagName(''); + setfeatureFlagVariant(''); + } + }; + const removeFeatureFlags = () => { + if (validateFeatureFlagForm()) { + Instabug.removeFeatureFlag(featureFlagName); + toast.show({ + description: 'Feature Flag removed successfully', + }); + setFeatureFlagName(''); + setfeatureFlagVariant(''); + } + }; + const removeAllFeatureFlags = () => { + Instabug.removeAllFeatureFlags(); + toast.show({ + description: 'Feature Flags removed successfully', + }); + setFeatureFlagName(''); + setfeatureFlagVariant(''); + }; const logout = () => { Instabug.logOut(); @@ -215,6 +259,38 @@ export const SettingsScreen: React.FC = () => { + + + + + setFeatureFlagName(key)} + value={featureFlagName} + errorText={featureFlagFormError.featureFlagName} + /> + + + setfeatureFlagVariant(value)} + value={featureFlagVariant} + /> + + + + + + + + + ); diff --git a/ios/RNInstabug/InstabugReactBridge.h b/ios/RNInstabug/InstabugReactBridge.h index 9e9a8db48..c66910652 100644 --- a/ios/RNInstabug/InstabugReactBridge.h +++ b/ios/RNInstabug/InstabugReactBridge.h @@ -116,5 +116,7 @@ - (void)addExperiments:(NSArray *)experiments; - (void)removeExperiments:(NSArray *)experiments; - (void)clearAllExperiments; - +- (void)addFeatureFlags:(NSDictionary *)featureFlagsMap; +- (void)removeFeatureFlags:(NSArray *)featureFlags; +- (void)removeAllFeatureFlags; @end diff --git a/ios/RNInstabug/InstabugReactBridge.m b/ios/RNInstabug/InstabugReactBridge.m index 01dd41aa8..c7e083801 100644 --- a/ios/RNInstabug/InstabugReactBridge.m +++ b/ios/RNInstabug/InstabugReactBridge.m @@ -382,6 +382,39 @@ - (dispatch_queue_t)methodQueue { [Instabug clearAllExperiments]; } +RCT_EXPORT_METHOD(addFeatureFlags:(NSDictionary *)featureFlagsMap) { + NSMutableArray *featureFlags = [NSMutableArray array]; + for(id key in featureFlagsMap){ + NSString* variant =((NSString * )[featureFlagsMap objectForKey:key]); + if ([variant length]==0) { + [featureFlags addObject:[[IBGFeatureFlag alloc] initWithName:key]]; + } + else{ + [featureFlags addObject:[[IBGFeatureFlag alloc] initWithName:key variant:variant]]; + + } + } + + [Instabug addFeatureFlags:featureFlags]; +} + +RCT_EXPORT_METHOD(removeFeatureFlags:(NSArray *)featureFlags) { + NSMutableArray *features = [NSMutableArray array]; + for(id item in featureFlags){ + [features addObject:[[IBGFeatureFlag alloc] initWithName:item]]; + } + + @try { + [Instabug removeFeatureFlags:features]; + } @catch (NSException *exception) { + NSLog(@"%@", exception); + } +} + +RCT_EXPORT_METHOD(removeAllFeatureFlags) { + [Instabug removeAllFeatureFlags]; +} + RCT_EXPORT_METHOD(willRedirectToStore){ [Instabug willRedirectToAppStore]; } diff --git a/ios/native.rb b/ios/native.rb index 3e4049bac..dc0b3bf14 100644 --- a/ios/native.rb +++ b/ios/native.rb @@ -1,4 +1,4 @@ -$instabug = { :version => '13.0.5' } +$instabug = { :version => '13.1.0' } def use_instabug! (spec = nil) version = $instabug[:version] diff --git a/src/models/IBGFeatureRequest.ts b/src/models/IBGFeatureRequest.ts new file mode 100644 index 000000000..eb3d75d40 --- /dev/null +++ b/src/models/IBGFeatureRequest.ts @@ -0,0 +1,13 @@ +export interface IBGFeatureRequest { + /** + * the name of featureRequest + * + */ + name: string; + + /** + * variant is an optional param + * + */ + variant?: string; +} diff --git a/src/modules/Instabug.ts b/src/modules/Instabug.ts index 07b3c079d..9a5830913 100644 --- a/src/modules/Instabug.ts +++ b/src/modules/Instabug.ts @@ -21,6 +21,7 @@ import InstabugUtils, { stringifyIfNotString } from '../utils/InstabugUtils'; import * as NetworkLogger from './NetworkLogger'; import { captureUnhandledRejections } from '../utils/UnhandledRejectionTracking'; import type { ReproConfig } from '../models/ReproConfig'; +import type { IBGFeatureRequest } from '../models/IBGFeatureRequest'; let _currentScreen: string | null = null; let _lastScreen: string | null = null; @@ -539,6 +540,8 @@ export const reportScreenChange = (screenName: string) => { /** * Add experiments to next report. * @param experiments An array of experiments to add to the next report. + * + * @deprecated Please migrate to the new FeatureRequests APIs: {@link addFeatureFlags}. */ export const addExperiments = (experiments: string[]) => { NativeInstabug.addExperiments(experiments); @@ -547,6 +550,8 @@ export const addExperiments = (experiments: string[]) => { /** * Remove experiments from next report. * @param experiments An array of experiments to remove from the next report. + * + * @deprecated Please migrate to the new FeatureRequests APIs: {@link removeFeatureFlags}. */ export const removeExperiments = (experiments: string[]) => { NativeInstabug.removeExperiments(experiments); @@ -554,11 +559,57 @@ export const removeExperiments = (experiments: string[]) => { /** * Clear all experiments + * + * @deprecated Please migrate to the new FeatureRequests APIs: {@link removeAllFeatureFlags}. */ export const clearAllExperiments = () => { NativeInstabug.clearAllExperiments(); }; +/** + * Add featureFlags to next report. + * @param featureFlags An array of featureFlags to add to the next report. + */ +export const addFeatureFlags = (featureFlags: IBGFeatureRequest[]) => { + const flags: Record = {}; + + for (const item of featureFlags) { + flags[item.name] = item.variant ? item.variant : ''; + } + + NativeInstabug.addFeatureFlags(flags); +}; + +/** + * Add featureFlag to next report. + */ +export const addFeatureFlag = (featureFlag: IBGFeatureRequest) => { + addFeatureFlags([featureFlag]); +}; + +/** + * Remove featureFlags from next report. + * @param featureFlags An array of featureFlags to remove from the next report. + */ +export const removeFeatureFlags = (featureFlags: string[]) => { + NativeInstabug.removeFeatureFlags(featureFlags); +}; + +/** + * Remove featureFlags from next report. + * @param name the name of featureFlag to remove from the next report. + */ +export const removeFeatureFlag = (name: string) => { + removeFeatureFlags([name]); +}; + +/** + * Clear all featureFlags + */ +export const removeAllFeatureFlags = () => { + NativeInstabug.removeAllFeatureFlags(); +}; + /** * This API has to be call when using custom app rating prompt */ diff --git a/src/native/NativeInstabug.ts b/src/native/NativeInstabug.ts index 3ff68de26..bcbf0744a 100644 --- a/src/native/NativeInstabug.ts +++ b/src/native/NativeInstabug.ts @@ -19,6 +19,7 @@ export interface InstabugNativeModule extends NativeModule { // Essential APIs // setEnabled(isEnabled: boolean): void; + init( token: string, invocationEvents: InvocationEvent[], @@ -26,21 +27,28 @@ export interface InstabugNativeModule extends NativeModule { useNativeNetworkInterception: boolean, codePushVersion?: string, ): void; + show(): void; // Misc APIs // setCodePushVersion(version: string): void; + setIBGLogPrintsToConsole(printsToConsole: boolean): void; + setSessionProfilerEnabled(isEnabled: boolean): void; // Customization APIs // setLocale(sdkLocale: Locale): void; + setColorTheme(sdkTheme: ColorTheme): void; + setPrimaryColor(color: ProcessedColorValue | null | undefined): void; + setString(string: string, key: StringKey): void; // Network APIs // networkLog(network: NetworkData | string): void; + setNetworkLoggingEnabled(isEnabled: boolean): void; // Repro Steps APIs // @@ -49,62 +57,101 @@ export interface InstabugNativeModule extends NativeModule { crashMode: ReproStepsMode, sessionReplay: ReproStepsMode, ): void; + setTrackUserSteps(isEnabled: boolean): void; + reportScreenChange(firstScreen: string): void; + reportCurrentViewChange(screenName: string): void; + addPrivateView(nativeTag: number | null): void; + removePrivateView(nativeTag: number | null): void; // Logging APIs // logVerbose(message: string): void; + logInfo(message: string): void; + logDebug(message: string): void; + logError(message: string): void; + logWarn(message: string): void; + clearLogs(): void; // User APIs // identifyUser(email: string, name: string, id?: string): void; + logOut(): void; + logUserEvent(name: string): void; + setUserData(data: string): void; // User Attributes APIs // setUserAttribute(key: string, value: string): void; + getUserAttribute(key: string): Promise; + removeUserAttribute(key: string): void; + getAllUserAttributes(): Promise>; + clearAllUserAttributes(): void; // Welcome Message APIs // showWelcomeMessageWithMode(mode: WelcomeMessageMode): void; + setWelcomeMessageMode(mode: WelcomeMessageMode): void; // Tags APIs // appendTags(tags: string[]): void; + resetTags(): void; + getTags(): Promise; // Experiments APIs // addExperiments(experiments: string[]): void; + removeExperiments(experiments: string[]): void; + clearAllExperiments(): void; + addFeatureFlags(featureFlags: Record): void; + + removeFeatureFlags(featureFlags: string[]): void; + + removeAllFeatureFlags(): void; + // Files APIs // setFileAttachment(filePath: string, fileName?: string): void; // Report APIs // setPreSendingHandler(handler?: (report: Report) => void): void; + appendTagToReport(tag: string): void; + appendConsoleLogToReport(consoleLog: string): void; + setUserAttributeToReport(key: string, value: string): void; + logDebugToReport(log: string): void; + logVerboseToReport(log: string): void; + logWarnToReport(log: string): void; + logErrorToReport(log: string): void; + logInfoToReport(log: string): void; + addFileAttachmentWithURLToReport(url: string, filename?: string): void; + addFileAttachmentWithDataToReport(data: string, filename?: string): void; + willRedirectToStore(): void; } diff --git a/test/mocks/mockInstabug.ts b/test/mocks/mockInstabug.ts index bb69eda51..898c2209e 100644 --- a/test/mocks/mockInstabug.ts +++ b/test/mocks/mockInstabug.ts @@ -52,6 +52,9 @@ const mockInstabug: InstabugNativeModule = { addExperiments: jest.fn(), removeExperiments: jest.fn(), clearAllExperiments: jest.fn(), + addFeatureFlags: jest.fn(), + removeFeatureFlags: jest.fn(), + removeAllFeatureFlags: jest.fn(), networkLog: jest.fn(), appendTagToReport: jest.fn(), appendConsoleLogToReport: jest.fn(), diff --git a/test/modules/Instabug.spec.ts b/test/modules/Instabug.spec.ts index f2e52099f..483024b21 100644 --- a/test/modules/Instabug.spec.ts +++ b/test/modules/Instabug.spec.ts @@ -21,6 +21,7 @@ import { WelcomeMessageMode, } from '../../src/utils/Enums'; import InstabugUtils from '../../src/utils/InstabugUtils'; +import type { IBGFeatureRequest } from '../../src/models/IBGFeatureRequest'; describe('Instabug Module', () => { beforeEach(() => { @@ -770,6 +771,57 @@ describe('Instabug Module', () => { expect(NativeInstabug.clearAllExperiments).toBeCalledTimes(1); }); + it('should call native addFeatureFlags method', () => { + const featureFlags: Array = [ + { + name: 'key1', + variant: 'variant1', + }, + { + name: 'key2', + variant: 'variant2', + }, + ]; + const expected: Record = {}; + expected.key1 = 'variant1'; + expected.key2 = 'variant2'; + + Instabug.addFeatureFlags(featureFlags); + expect(NativeInstabug.addFeatureFlags).toBeCalledTimes(1); + expect(NativeInstabug.addFeatureFlags).toBeCalledWith(expected); + }); + + it('should call native addFeatureFlag method', () => { + const featureFlag: IBGFeatureRequest = { + name: 'key1', + variant: 'variant2', + }; + const expected: Record = {}; + expected.key1 = 'variant2'; + + Instabug.addFeatureFlag(featureFlag); + expect(NativeInstabug.addFeatureFlags).toBeCalledTimes(1); + expect(NativeInstabug.addFeatureFlags).toBeCalledWith(expected); + }); + it('should call native removeFeatureFlags method', () => { + const featureFlags = ['exp1', 'exp2']; + Instabug.removeFeatureFlags(featureFlags); + expect(NativeInstabug.removeFeatureFlags).toBeCalledTimes(1); + expect(NativeInstabug.removeFeatureFlags).toBeCalledWith(featureFlags); + }); + + it('should call native removeFeatureFlag method', () => { + const featureFlag = 'exp1'; + Instabug.removeFeatureFlag(featureFlag); + expect(NativeInstabug.removeFeatureFlags).toBeCalledTimes(1); + expect(NativeInstabug.removeFeatureFlags).toBeCalledWith([featureFlag]); + }); + + it('should call native removeAllFeatureFlags method', () => { + Instabug.removeAllFeatureFlags(); + expect(NativeInstabug.removeAllFeatureFlags).toBeCalledTimes(1); + }); + it('should call the native willRedirectToStore method', () => { Instabug.willRedirectToStore(); expect(NativeInstabug.willRedirectToStore).toBeCalledTimes(1); From 7dae97559aa55784501dde9a972bdd6fd6806aa9 Mon Sep 17 00:00:00 2001 From: Ahmed alaa Date: Wed, 5 Jun 2024 01:29:05 +0300 Subject: [PATCH 2/9] merge --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5fdd2e9c..e3b21212f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ - Bump Instabug iOS SDK to v13.1.0 ([#1227](https://github.com/Instabug/Instabug-React-Native/pull/1227)). [See release notes](https://github.com/Instabug/Instabug-iOS/releases/tag/13.1.0). - Bump Instabug android SDK to v13.1.1 ([#1228](https://github.com/Instabug/Instabug-React-Native/pull/1228)). [See release notes](https://github.com/Instabug/android/releases/tag/v13.1.0). +## Added + +- Add support for FeatureFlags APIs `Instabug.addFeatureFlags`, `Instabug.removeFeatureFlags` and `Instabug.clearAllFeatureFlags` ([#471](https://github.com/Instabug/Instabug-Flutter/pull/471)). + +### Deprecated + +- Deprecate execution traces APIs `Instabug.startExecuti# Changelog + ## [13.0.5](https://github.com/Instabug/Instabug-React-Native/compare/v13.0.4...v13.0.5) (May 18, 2024) ### Changed From 69cd4343dac8a1624a412fc7404733b6905b815b Mon Sep 17 00:00:00 2001 From: Ahmed alaa Date: Wed, 5 Jun 2024 01:39:30 +0300 Subject: [PATCH 3/9] fix merge issue --- examples/default/ios/Podfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/default/ios/Podfile.lock b/examples/default/ios/Podfile.lock index d3720dd7e..2b73844bd 100644 --- a/examples/default/ios/Podfile.lock +++ b/examples/default/ios/Podfile.lock @@ -852,4 +852,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: ad82a989387dcdb1ce80667f16b998a2644cf0b2 -COCOAPODS: 1.14.3 +COCOAPODS: 1.12.0 From 21540a58c095959216feb403ee57ad3ce87f259d Mon Sep 17 00:00:00 2001 From: Ahmed alaa Date: Wed, 5 Jun 2024 02:27:58 +0300 Subject: [PATCH 4/9] fix test cases --- .../ios/InstabugTests/InstabugSampleTests.m | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/examples/default/ios/InstabugTests/InstabugSampleTests.m b/examples/default/ios/InstabugTests/InstabugSampleTests.m index 9b40064a1..abf3a2705 100644 --- a/examples/default/ios/InstabugTests/InstabugSampleTests.m +++ b/examples/default/ios/InstabugTests/InstabugSampleTests.m @@ -72,7 +72,7 @@ - (void)testInit { NSArray *invocationEvents = [NSArray arrayWithObjects:[NSNumber numberWithInteger:floatingButtonInvocationEvent], nil]; BOOL useNativeNetworkInterception = YES; IBGSDKDebugLogsLevel sdkDebugLogsLevel = IBGSDKDebugLogsLevelDebug; - + OCMStub([mock setCodePushVersion:codePushVersion]); [self.instabugBridge init:appToken invocationEvents:invocationEvents debugLogsLevel:sdkDebugLogsLevel useNativeNetworkInterception:useNativeNetworkInterception codePushVersion:codePushVersion]; @@ -84,9 +84,9 @@ - (void)testInit { - (void)testSetCodePushVersion { id mock = OCMClassMock([Instabug class]); NSString *codePushVersion = @"123"; - + [self.instabugBridge setCodePushVersion:codePushVersion]; - + OCMVerify([mock setCodePushVersion:codePushVersion]); } @@ -445,7 +445,7 @@ - (void)testClearAllExperiments { - (void)testAddFeatureFlags { id mock = OCMClassMock([Instabug class]); NSDictionary *featureFlagsMap = @{ @"key13" : @"value1", @"key2" : @"value2"}; - + OCMStub([mock addFeatureFlags :[OCMArg any]]); [self.instabugBridge addFeatureFlags:featureFlagsMap]; OCMVerify([mock addFeatureFlags: [OCMArg checkWithBlock:^(id value) { @@ -461,11 +461,17 @@ - (void)testAddFeatureFlags { - (void)testRemoveFeatureFlags { id mock = OCMClassMock([Instabug class]); - NSArray *experiments = @[@"exp1", @"exp2"]; - - OCMStub([mock removeFeatureFlags:experiments]); - [self.instabugBridge removeFeatureFlags:experiments]; - OCMVerify([mock removeFeatureFlags:experiments]); + NSArray *featureFlags = @[@"exp1", @"exp2"]; + [self.instabugBridge removeFeatureFlags:featureFlags]; + OCMVerify([mock removeFeatureFlags: [OCMArg checkWithBlock:^(id value) { + NSArray *featureFlagsObJ = value; + NSString* firstFeatureFlagName = [featureFlagsObJ objectAtIndex:0 ].name; + NSString* firstFeatureFlagKey = [featureFlags firstObject] ; + if([ firstFeatureFlagKey isEqualToString: firstFeatureFlagName]){ + return YES; + } + return NO; + }]]); } - (void)testRemoveAllFeatureFlags { From 56f4ef11634c581dbd22fc8076a6ca163bd6a7e0 Mon Sep 17 00:00:00 2001 From: Ahmed alaa Date: Mon, 15 Jul 2024 04:17:16 +0300 Subject: [PATCH 5/9] fix: format files --- CHANGELOG.md | 4 +- android/src/main/AndroidManifest.xml | 2 +- .../RNInstabugReactnativeModule.java | 50 ++++++------- .../RNInstabugSessionReplayModule.java | 2 +- .../RNInstabugReactnativeModuleTest.java | 73 +++++++++---------- .../react/example/MainApplication.java | 1 - examples/default/src/screens/HomeScreen.tsx | 1 + ios/native.rb | 1 - src/modules/Instabug.ts | 14 ++-- src/native/NativeInstabug.ts | 41 ----------- 10 files changed, 71 insertions(+), 118 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3b21212f..d52e8192e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,11 +9,11 @@ ## Added -- Add support for FeatureFlags APIs `Instabug.addFeatureFlags`, `Instabug.removeFeatureFlags` and `Instabug.clearAllFeatureFlags` ([#471](https://github.com/Instabug/Instabug-Flutter/pull/471)). +- Add support for Feature Flags APIs `Instabug.addFeatureFlags`, `Instabug.removeFeatureFlags` and `Instabug.clearAllFeatureFlags` ([#1230](https://github.com/Instabug/Instabug-Flutter/pull/1230)). ### Deprecated -- Deprecate execution traces APIs `Instabug.startExecuti# Changelog +- Deprecate Experiments APIs `Instabug.addExperiments`, `Instabug.removeExperiments` and `Instabug.clearAllExperiments` in favor of the new Feature Flags APIs ([#1230](https://github.com/Instabug/Instabug-Flutter/pull/1230)). ## [13.0.5](https://github.com/Instabug/Instabug-React-Native/compare/v13.0.4...v13.0.5) (May 18, 2024) diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index 9af27fbd3..44ad85bcd 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1,4 +1,4 @@ - diff --git a/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java b/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java index 9eab5d8db..efcee6467 100644 --- a/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java +++ b/android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java @@ -102,7 +102,6 @@ public void removeListeners(Integer count) { /** * Enables or disables Instabug functionality. - * * @param isEnabled A boolean to enable/disable Instabug. */ @ReactMethod @@ -111,7 +110,7 @@ public void setEnabled(final boolean isEnabled) { @Override public void run() { try { - if (isEnabled) + if(isEnabled) Instabug.enable(); else Instabug.disable(); @@ -124,11 +123,10 @@ public void run() { /** * Initializes the SDK. - * - * @param token The token that identifies the app. You can find it on your dashboard. + * @param token The token that identifies the app. You can find it on your dashboard. * @param invocationEventValues The events that invoke the SDK's UI. - * @param logLevel The level of detail in logs that you want to print. - * @param codePushVersion The Code Push version to be used for all reports. + * @param logLevel The level of detail in logs that you want to print. + * @param codePushVersion The Code Push version to be used for all reports. */ @ReactMethod public void init( @@ -154,8 +152,8 @@ public void run() { .setInvocationEvents(invocationEvents) .setLogLevel(parsedLogLevel); - if (codePushVersion != null) { - if (Instabug.isBuilt()) { + if(codePushVersion != null) { + if(Instabug.isBuilt()) { Instabug.setCodePushVersion(codePushVersion); } else { builder.setCodePushVersion(codePushVersion); @@ -167,7 +165,7 @@ public void run() { } @ReactMethod - public void setCodePushVersion(@Nullable String version) { + public void setCodePushVersion(@Nullable final String version) { MainThreadHandler.runOnMainThread(new Runnable() { @Override public void run() { @@ -321,7 +319,7 @@ public void run() { * * @param userEmail User's default email * @param userName Username. - * @param userId User's ID + * @param userId User's ID */ @ReactMethod public void identifyUser( @@ -741,15 +739,15 @@ public void addFileAttachmentWithDataToReport(String data, String fileName) { private WritableMap convertFromHashMapToWriteableMap(HashMap hashMap) { WritableMap writableMap = new WritableNativeMap(); - for (int i = 0; i < hashMap.size(); i++) { + for(int i = 0; i < hashMap.size(); i++) { Object key = hashMap.keySet().toArray()[i]; Object value = hashMap.get(key); - writableMap.putString((String) key, (String) value); + writableMap.putString((String) key,(String) value); } return writableMap; } - private static JSONObject objectToJSONObject(Object object) { + private static JSONObject objectToJSONObject(Object object){ Object json = null; JSONObject jsonObject = null; try { @@ -766,12 +764,13 @@ private static JSONObject objectToJSONObject(Object object) { private WritableArray convertArrayListToWritableArray(List arrayList) { WritableArray writableArray = new WritableNativeArray(); - for (int i = 0; i < arrayList.size(); i++) { + for(int i = 0; i < arrayList.size(); i++) { Object object = arrayList.get(i); - if (object instanceof String) { + if(object instanceof String) { writableArray.pushString((String) object); - } else { + } + else { JSONObject jsonObject = objectToJSONObject(object); writableArray.pushMap((WritableMap) jsonObject); } @@ -827,7 +826,7 @@ public void run() { * Shows the welcome message in a specific mode. * * @param welcomeMessageMode An enum to set the welcome message mode to - * live, or beta. + * live, or beta. */ @ReactMethod public void showWelcomeMessageWithMode(final String welcomeMessageMode) { @@ -849,7 +848,7 @@ public void run() { * Sets the welcome message mode to live, beta or disabled. * * @param welcomeMessageMode An enum to set the welcome message mode to - * live, beta or disabled. + * live, beta or disabled. */ @ReactMethod public void setWelcomeMessageMode(final String welcomeMessageMode) { @@ -909,7 +908,7 @@ public void run() { @ReactMethod public void networkLog(String jsonObject) throws JSONException { NetworkLog networkLog = new NetworkLog(); - String date = System.currentTimeMillis() + ""; + String date = System.currentTimeMillis()+""; networkLog.setDate(date); JSONObject newJSONObject = new JSONObject(jsonObject); networkLog.setUrl(newJSONObject.getString("url")); @@ -973,6 +972,7 @@ public void run() { * Reports that the screen name been changed (Current View). * * @param screenName string containing the screen name + * */ @ReactMethod public void reportCurrentViewChange(final String screenName) { @@ -995,6 +995,7 @@ public void run() { * Reports that the screen has been changed (Repro Steps) the screen sent to this method will be the 'current view' on the dashboard * * @param screenName string containing the screen name + * */ @ReactMethod public void reportScreenChange(final String screenName) { @@ -1004,7 +1005,7 @@ public void run() { try { Method method = getMethod(Class.forName("com.instabug.library.Instabug"), "reportScreenChange", Bitmap.class, String.class); if (method != null) { - method.invoke(null, null, screenName); + method.invoke(null , null, screenName); } } catch (Exception e) { e.printStackTrace(); @@ -1093,14 +1094,13 @@ public void run() { } @ReactMethod - public void removeFeatureFlags(final ReadableArray experiments) { + public void removeFeatureFlags(final ReadableArray featureFlags) { MainThreadHandler.runOnMainThread(new Runnable() { @Override public void run() { try { - Object[] objectArray = ArrayUtil.toArray(experiments); - String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class); - Instabug.removeFeatureFlag(Arrays.asList(stringArray)); + ArrayList stringArray = ArrayUtil.parseReadableArrayOfStrings(featureFlags); + Instabug.removeFeatureFlag(stringArray); } catch (Exception e) { e.printStackTrace(); } @@ -1140,7 +1140,7 @@ public void run() { * Map between the exported JS constant and the arg key in {@link ArgsRegistry}. * The constant name and the arg key should match to be able to resolve the * constant with its actual value from the {@link ArgsRegistry} maps. - *

+ * * This is a workaround, because RN cannot resolve enums in the constants map. */ @Override diff --git a/android/src/main/java/com/instabug/reactlibrary/RNInstabugSessionReplayModule.java b/android/src/main/java/com/instabug/reactlibrary/RNInstabugSessionReplayModule.java index 1c3967502..5024c6180 100644 --- a/android/src/main/java/com/instabug/reactlibrary/RNInstabugSessionReplayModule.java +++ b/android/src/main/java/com/instabug/reactlibrary/RNInstabugSessionReplayModule.java @@ -83,7 +83,7 @@ public void run() { } @ReactMethod - public void getSessionReplayLink(Promise promise) { + public void getSessionReplayLink(final Promise promise) { MainThreadHandler.runOnMainThread(new Runnable() { @Override public void run() { diff --git a/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java b/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java index 1be271f8b..b9bf2308c 100644 --- a/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java +++ b/android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java @@ -64,8 +64,8 @@ public class RNInstabugReactnativeModuleTest { // Mock Objects private MockedStatic mockLooper; - private MockedStatic mockMainThreadHandler; - private MockedStatic mockInstabug; + private MockedStatic mockMainThreadHandler; + private MockedStatic mockInstabug; @Before public void mockMainThreadHandler() throws Exception { @@ -89,7 +89,6 @@ public Boolean answer(InvocationOnMock invocation) throws Throwable { Mockito.doAnswer(handlerPostAnswer).when(MainThreadHandler.class); MainThreadHandler.runOnMainThread(any(Runnable.class)); } - @After public void tearDown() { // Remove static mocks @@ -132,7 +131,7 @@ public void tearDown() { // when rnModule.setUserAttribute(key, value); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.setUserAttribute(key, value); } @@ -144,7 +143,7 @@ public void tearDown() { // when rnModule.removeUserAttribute(key); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.removeUserAttribute(key); } @@ -155,7 +154,7 @@ public void tearDown() { // when rnModule.clearAllUserAttributes(); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.clearAllUserAttributes(); } @@ -166,12 +165,12 @@ public void tearDown() { final String[] keysArray = themesArgs.keySet().toArray(new String[0]); // when - for (String key : keysArray) { + for (String key: keysArray) { rnModule.setColorTheme(key); } // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); for (String key : keysArray) { InstabugColorTheme theme = themesArgs.get(key); Instabug.setColorTheme(theme); @@ -186,7 +185,7 @@ public void tearDown() { // when rnModule.setUserData(data); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.setUserData(data); } @@ -198,7 +197,7 @@ public void tearDown() { // when rnModule.setPrimaryColor(color); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.setPrimaryColor(color); } @@ -244,7 +243,7 @@ public void testIdentifyUserWithId() { // when rnModule.resetTags(); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.resetTags(); } @@ -255,7 +254,7 @@ public void testIdentifyUserWithId() { // when rnModule.logOut(); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.logoutUser(); } @@ -267,7 +266,7 @@ public void testIdentifyUserWithId() { // when rnModule.logUserEvent(eventName); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.logUserEvent(eventName); } @@ -278,7 +277,7 @@ public void testIdentifyUserWithId() { // when rnModule.clearFileAttachment(); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.clearFileAttachment(); } @@ -320,7 +319,7 @@ public void testIdentifyUserWithId() { } // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); for (String key : keysArray) { WelcomeMessage.State state = (WelcomeMessage.State) args.get(key); Instabug.showWelcomeMessage(state); @@ -339,7 +338,7 @@ public void testIdentifyUserWithId() { } // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); for (String key : keysArray) { WelcomeMessage.State state = args.get(key); Instabug.setWelcomeMessageState(state); @@ -353,7 +352,7 @@ public void testIdentifyUserWithId() { // when rnModule.show(); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.show(); } @@ -364,7 +363,7 @@ public void testIdentifyUserWithId() { // when rnModule.setSessionProfilerEnabled(true); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.setSessionProfilerState(Feature.State.ENABLED); } @@ -375,7 +374,7 @@ public void testIdentifyUserWithId() { // when rnModule.setSessionProfilerEnabled(false); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.setSessionProfilerState(Feature.State.DISABLED); } @@ -389,8 +388,8 @@ public void testIdentifyUserWithId() { // when rnModule.appendTags(array); // then - verify(Instabug.class, times(1)); - String[] expectedArray = {"tag1", "tag2"}; + verify(Instabug.class,times(1)); + String [] expectedArray = {"tag1", "tag2"}; Instabug.addTags(expectedArray); } @@ -408,7 +407,7 @@ public void testIdentifyUserWithId() { when(Arguments.createArray()).thenReturn(new JavaOnlyArray()); rnModule.getTags(promise); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.getTags(); WritableArray expectedArray = new JavaOnlyArray(); expectedArray.pushString("tag1"); @@ -429,7 +428,7 @@ public void testIdentifyUserWithId() { when(Instabug.getUserAttribute(key)).thenReturn(value); rnModule.getUserAttribute(key, promise); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.getUserAttribute(key); verify(promise).resolve(value); } @@ -446,7 +445,7 @@ public void testIdentifyUserWithId() { when(Instabug.getAllUserAttributes()).thenReturn(userAttributes); rnModule.getAllUserAttributes(promise); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.getAllUserAttributes(); WritableMap expectedMap = new JavaOnlyMap(); expectedMap.putString("email", "sali@instabug.com"); @@ -466,7 +465,7 @@ public void testIdentifyUserWithId() { } // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); for (String key : keysArray) { final InstabugLocale instabugLocale = args.get(key); final Locale locale = new Locale(instabugLocale.getCode(), instabugLocale.getCountry()); @@ -489,7 +488,7 @@ public void testIdentifyUserWithId() { } // then - verify(Instabug.class, VerificationModeFactory.atLeastOnce()); + verify(Instabug.class ,VerificationModeFactory.atLeastOnce()); Instabug.setCustomTextPlaceHolders(Matchers.any(InstabugCustomTextPlaceHolder.class)); // access placeHolders field by reflection @@ -498,10 +497,10 @@ public void testIdentifyUserWithId() { getDeclaredField("placeHolders"); privateStringField.setAccessible(true); InstabugCustomTextPlaceHolder placeHolders = (InstabugCustomTextPlaceHolder) privateStringField.get(rnModule); - for (String key : keys) { - InstabugCustomTextPlaceHolder.Key placeHolder = args.get(key); - Assert.assertEquals(placeHolders.get(placeHolder), key); - } + for (String key : keys) { + InstabugCustomTextPlaceHolder.Key placeHolder = args.get(key); + Assert.assertEquals(placeHolders.get(placeHolder), key); + } } catch (NoSuchFieldException | IllegalAccessException nsfe) { throw new RuntimeException(nsfe); } @@ -516,7 +515,7 @@ public void testIdentifyUserWithId() { // then verify(Instabug.class, VerificationModeFactory.times(1)); - privateStringMethod.invoke("reportCurrentViewChange", "screen"); + privateStringMethod.invoke("reportCurrentViewChange","screen"); } @Test @@ -528,7 +527,7 @@ public void testIdentifyUserWithId() { // then verify(Instabug.class, VerificationModeFactory.times(1)); - privateStringMethod.invoke("reportScreenChange", null, "screen"); + privateStringMethod.invoke("reportScreenChange", null,"screen"); } @@ -543,7 +542,7 @@ public void testIdentifyUserWithId() { rnModule.addExperiments(array); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); List expectedList = new ArrayList(); expectedList.add("exp1"); expectedList.add("exp2"); @@ -561,7 +560,7 @@ public void testIdentifyUserWithId() { rnModule.removeExperiments(array); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); List expectedList = new ArrayList(); expectedList.add("exp1"); expectedList.add("exp2"); @@ -570,13 +569,11 @@ public void testIdentifyUserWithId() { @Test public void given$clearAllExperiments_whenQuery_thenShouldCallNativeApi() { - // given - // when rnModule.clearAllExperiments(); // then - verify(Instabug.class, times(1)); + verify(Instabug.class,times(1)); Instabug.clearAllExperiments(); } @@ -623,8 +620,6 @@ public void testRemoveFeatureFlags() { @Test public void testRemoveAllFeatureFlags() { - // given - // when rnModule.removeAllFeatureFlags(); diff --git a/examples/default/android/app/src/main/java/com/instabug/react/example/MainApplication.java b/examples/default/android/app/src/main/java/com/instabug/react/example/MainApplication.java index 1db77bfa7..a988f0a84 100644 --- a/examples/default/android/app/src/main/java/com/instabug/react/example/MainApplication.java +++ b/examples/default/android/app/src/main/java/com/instabug/react/example/MainApplication.java @@ -57,6 +57,5 @@ public void onCreate() { DefaultNewArchitectureEntryPoint.load(); } ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); - } } diff --git a/examples/default/src/screens/HomeScreen.tsx b/examples/default/src/screens/HomeScreen.tsx index 086dc0650..734853450 100644 --- a/examples/default/src/screens/HomeScreen.tsx +++ b/examples/default/src/screens/HomeScreen.tsx @@ -5,6 +5,7 @@ import type { NativeStackScreenProps } from '@react-navigation/native-stack'; import { ListTile } from '../components/ListTile'; import { Screen } from '../components/Screen'; import type { HomeStackParamList } from '../navigation/HomeStack'; +import Instabug from 'instabug-reactnative'; export const HomeScreen: React.FC> = ({ navigation, diff --git a/ios/native.rb b/ios/native.rb index dc0b3bf14..c7a67ec75 100644 --- a/ios/native.rb +++ b/ios/native.rb @@ -2,7 +2,6 @@ def use_instabug! (spec = nil) version = $instabug[:version] - if (!spec) pod 'Instabug', version else diff --git a/src/modules/Instabug.ts b/src/modules/Instabug.ts index 9a5830913..d6a323fa6 100644 --- a/src/modules/Instabug.ts +++ b/src/modules/Instabug.ts @@ -567,7 +567,7 @@ export const clearAllExperiments = () => { }; /** - * Add featureFlags to next report. + * Add feature flags to the next report. * @param featureFlags An array of featureFlags to add to the next report. */ export const addFeatureFlags = (featureFlags: IBGFeatureRequest[]) => { @@ -581,30 +581,30 @@ export const addFeatureFlags = (featureFlags: IBGFeatureRequest[]) => { }; /** - * Add featureFlag to next report. + * Add a feature flag to the to next report. */ export const addFeatureFlag = (featureFlag: IBGFeatureRequest) => { addFeatureFlags([featureFlag]); }; /** - * Remove featureFlags from next report. - * @param featureFlags An array of featureFlags to remove from the next report. + * Remove feature flags from the next report. + * @param featureFlags An array of feature flags to remove from the next report. */ export const removeFeatureFlags = (featureFlags: string[]) => { NativeInstabug.removeFeatureFlags(featureFlags); }; /** - * Remove featureFlags from next report. - * @param name the name of featureFlag to remove from the next report. + * Remove a feature flag from the next report. + * @param name the name of the feature flag to remove from the next report. */ export const removeFeatureFlag = (name: string) => { removeFeatureFlags([name]); }; /** - * Clear all featureFlags + * Clear all feature flags */ export const removeAllFeatureFlags = () => { NativeInstabug.removeAllFeatureFlags(); diff --git a/src/native/NativeInstabug.ts b/src/native/NativeInstabug.ts index bcbf0744a..09b6e42fc 100644 --- a/src/native/NativeInstabug.ts +++ b/src/native/NativeInstabug.ts @@ -19,7 +19,6 @@ export interface InstabugNativeModule extends NativeModule { // Essential APIs // setEnabled(isEnabled: boolean): void; - init( token: string, invocationEvents: InvocationEvent[], @@ -27,28 +26,21 @@ export interface InstabugNativeModule extends NativeModule { useNativeNetworkInterception: boolean, codePushVersion?: string, ): void; - show(): void; // Misc APIs // setCodePushVersion(version: string): void; - setIBGLogPrintsToConsole(printsToConsole: boolean): void; - setSessionProfilerEnabled(isEnabled: boolean): void; // Customization APIs // setLocale(sdkLocale: Locale): void; - setColorTheme(sdkTheme: ColorTheme): void; - setPrimaryColor(color: ProcessedColorValue | null | undefined): void; - setString(string: string, key: StringKey): void; // Network APIs // networkLog(network: NetworkData | string): void; - setNetworkLoggingEnabled(isEnabled: boolean): void; // Repro Steps APIs // @@ -57,67 +49,45 @@ export interface InstabugNativeModule extends NativeModule { crashMode: ReproStepsMode, sessionReplay: ReproStepsMode, ): void; - setTrackUserSteps(isEnabled: boolean): void; - reportScreenChange(firstScreen: string): void; - reportCurrentViewChange(screenName: string): void; - addPrivateView(nativeTag: number | null): void; - removePrivateView(nativeTag: number | null): void; // Logging APIs // logVerbose(message: string): void; - logInfo(message: string): void; - logDebug(message: string): void; - logError(message: string): void; - logWarn(message: string): void; - clearLogs(): void; // User APIs // identifyUser(email: string, name: string, id?: string): void; - logOut(): void; - logUserEvent(name: string): void; - setUserData(data: string): void; // User Attributes APIs // setUserAttribute(key: string, value: string): void; - getUserAttribute(key: string): Promise; - removeUserAttribute(key: string): void; - getAllUserAttributes(): Promise>; - clearAllUserAttributes(): void; // Welcome Message APIs // showWelcomeMessageWithMode(mode: WelcomeMessageMode): void; - setWelcomeMessageMode(mode: WelcomeMessageMode): void; // Tags APIs // appendTags(tags: string[]): void; - resetTags(): void; - getTags(): Promise; // Experiments APIs // addExperiments(experiments: string[]): void; - removeExperiments(experiments: string[]): void; - clearAllExperiments(): void; addFeatureFlags(featureFlags: Record): void; @@ -131,27 +101,16 @@ export interface InstabugNativeModule extends NativeModule { // Report APIs // setPreSendingHandler(handler?: (report: Report) => void): void; - appendTagToReport(tag: string): void; - appendConsoleLogToReport(consoleLog: string): void; - setUserAttributeToReport(key: string, value: string): void; - logDebugToReport(log: string): void; - logVerboseToReport(log: string): void; - logWarnToReport(log: string): void; - logErrorToReport(log: string): void; - logInfoToReport(log: string): void; - addFileAttachmentWithURLToReport(url: string, filename?: string): void; - addFileAttachmentWithDataToReport(data: string, filename?: string): void; - willRedirectToStore(): void; } From f749cd371243f1904efa76863cddb7270e50d6de Mon Sep 17 00:00:00 2001 From: Ahmed alaa Date: Mon, 15 Jul 2024 04:26:29 +0300 Subject: [PATCH 6/9] fix: format files --- examples/default/src/screens/HomeScreen.tsx | 1 - ios/RNInstabug/InstabugReactBridge.m | 23 ++++++++++----------- src/models/FeatureFlag.ts | 12 +++++++++++ src/models/IBGFeatureRequest.ts | 13 ------------ src/modules/Instabug.ts | 6 +++--- test/modules/Instabug.spec.ts | 6 +++--- 6 files changed, 29 insertions(+), 32 deletions(-) create mode 100644 src/models/FeatureFlag.ts delete mode 100644 src/models/IBGFeatureRequest.ts diff --git a/examples/default/src/screens/HomeScreen.tsx b/examples/default/src/screens/HomeScreen.tsx index 734853450..086dc0650 100644 --- a/examples/default/src/screens/HomeScreen.tsx +++ b/examples/default/src/screens/HomeScreen.tsx @@ -5,7 +5,6 @@ import type { NativeStackScreenProps } from '@react-navigation/native-stack'; import { ListTile } from '../components/ListTile'; import { Screen } from '../components/Screen'; import type { HomeStackParamList } from '../navigation/HomeStack'; -import Instabug from 'instabug-reactnative'; export const HomeScreen: React.FC> = ({ navigation, diff --git a/ios/RNInstabug/InstabugReactBridge.m b/ios/RNInstabug/InstabugReactBridge.m index c7e083801..550d3d7bc 100644 --- a/ios/RNInstabug/InstabugReactBridge.m +++ b/ios/RNInstabug/InstabugReactBridge.m @@ -385,30 +385,29 @@ - (dispatch_queue_t)methodQueue { RCT_EXPORT_METHOD(addFeatureFlags:(NSDictionary *)featureFlagsMap) { NSMutableArray *featureFlags = [NSMutableArray array]; for(id key in featureFlagsMap){ - NSString* variant =((NSString * )[featureFlagsMap objectForKey:key]); + NSString* variant =[featureFlagsMap objectForKey:key]; if ([variant length]==0) { [featureFlags addObject:[[IBGFeatureFlag alloc] initWithName:key]]; - } - else{ + } else{ [featureFlags addObject:[[IBGFeatureFlag alloc] initWithName:key variant:variant]]; - } } - + [Instabug addFeatureFlags:featureFlags]; } RCT_EXPORT_METHOD(removeFeatureFlags:(NSArray *)featureFlags) { NSMutableArray *features = [NSMutableArray array]; for(id item in featureFlags){ - [features addObject:[[IBGFeatureFlag alloc] initWithName:item]]; - } - + [features addObject:[[IBGFeatureFlag alloc] initWithName:item]]; + } + @try { - [Instabug removeFeatureFlags:features]; - } @catch (NSException *exception) { - NSLog(@"%@", exception); - } + [Instabug removeFeatureFlags:features]; + } + @catch (NSException *exception) { + NSLog(@"%@", exception); + } } RCT_EXPORT_METHOD(removeAllFeatureFlags) { diff --git a/src/models/FeatureFlag.ts b/src/models/FeatureFlag.ts new file mode 100644 index 000000000..d2fd58e0f --- /dev/null +++ b/src/models/FeatureFlag.ts @@ -0,0 +1,12 @@ +export interface FeatureFlag { + /** + * the name of feature flag + */ + name: string; + + /** + * The variant of the feature flag. + * Leave it `undefined` for boolean (kill switch) feature flags. + */ + variant?: string; +} diff --git a/src/models/IBGFeatureRequest.ts b/src/models/IBGFeatureRequest.ts deleted file mode 100644 index eb3d75d40..000000000 --- a/src/models/IBGFeatureRequest.ts +++ /dev/null @@ -1,13 +0,0 @@ -export interface IBGFeatureRequest { - /** - * the name of featureRequest - * - */ - name: string; - - /** - * variant is an optional param - * - */ - variant?: string; -} diff --git a/src/modules/Instabug.ts b/src/modules/Instabug.ts index d6a323fa6..a30d39ee6 100644 --- a/src/modules/Instabug.ts +++ b/src/modules/Instabug.ts @@ -21,7 +21,7 @@ import InstabugUtils, { stringifyIfNotString } from '../utils/InstabugUtils'; import * as NetworkLogger from './NetworkLogger'; import { captureUnhandledRejections } from '../utils/UnhandledRejectionTracking'; import type { ReproConfig } from '../models/ReproConfig'; -import type { IBGFeatureRequest } from '../models/IBGFeatureRequest'; +import type { FeatureFlag } from '../models/FeatureFlag'; let _currentScreen: string | null = null; let _lastScreen: string | null = null; @@ -570,7 +570,7 @@ export const clearAllExperiments = () => { * Add feature flags to the next report. * @param featureFlags An array of featureFlags to add to the next report. */ -export const addFeatureFlags = (featureFlags: IBGFeatureRequest[]) => { +export const addFeatureFlags = (featureFlags: FeatureFlag[]) => { const flags: Record = {}; for (const item of featureFlags) { @@ -583,7 +583,7 @@ export const addFeatureFlags = (featureFlags: IBGFeatureRequest[]) => { /** * Add a feature flag to the to next report. */ -export const addFeatureFlag = (featureFlag: IBGFeatureRequest) => { +export const addFeatureFlag = (featureFlag: FeatureFlag) => { addFeatureFlags([featureFlag]); }; diff --git a/test/modules/Instabug.spec.ts b/test/modules/Instabug.spec.ts index 483024b21..fdbdcae64 100644 --- a/test/modules/Instabug.spec.ts +++ b/test/modules/Instabug.spec.ts @@ -21,7 +21,7 @@ import { WelcomeMessageMode, } from '../../src/utils/Enums'; import InstabugUtils from '../../src/utils/InstabugUtils'; -import type { IBGFeatureRequest } from '../../src/models/IBGFeatureRequest'; +import type { FeatureFlag } from '../../src/models/FeatureFlag'; describe('Instabug Module', () => { beforeEach(() => { @@ -772,7 +772,7 @@ describe('Instabug Module', () => { }); it('should call native addFeatureFlags method', () => { - const featureFlags: Array = [ + const featureFlags: Array = [ { name: 'key1', variant: 'variant1', @@ -792,7 +792,7 @@ describe('Instabug Module', () => { }); it('should call native addFeatureFlag method', () => { - const featureFlag: IBGFeatureRequest = { + const featureFlag: FeatureFlag = { name: 'key1', variant: 'variant2', }; From 144e1dceb6d08679174cdf8f79d10c238a0a0678 Mon Sep 17 00:00:00 2001 From: Ahmed alaa Date: Mon, 15 Jul 2024 04:29:39 +0300 Subject: [PATCH 7/9] fix: format files --- src/modules/Instabug.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/Instabug.ts b/src/modules/Instabug.ts index a30d39ee6..156761d22 100644 --- a/src/modules/Instabug.ts +++ b/src/modules/Instabug.ts @@ -541,7 +541,7 @@ export const reportScreenChange = (screenName: string) => { * Add experiments to next report. * @param experiments An array of experiments to add to the next report. * - * @deprecated Please migrate to the new FeatureRequests APIs: {@link addFeatureFlags}. + * @deprecated Please migrate to the new Feature Flags APIs: {@link addFeatureFlags}. */ export const addExperiments = (experiments: string[]) => { NativeInstabug.addExperiments(experiments); @@ -551,7 +551,7 @@ export const addExperiments = (experiments: string[]) => { * Remove experiments from next report. * @param experiments An array of experiments to remove from the next report. * - * @deprecated Please migrate to the new FeatureRequests APIs: {@link removeFeatureFlags}. + * @deprecated Please migrate to the new Feature Flags APIs: {@link removeFeatureFlags}. */ export const removeExperiments = (experiments: string[]) => { NativeInstabug.removeExperiments(experiments); @@ -560,7 +560,7 @@ export const removeExperiments = (experiments: string[]) => { /** * Clear all experiments * - * @deprecated Please migrate to the new FeatureRequests APIs: {@link removeAllFeatureFlags}. + * @deprecated Please migrate to the new Feature Flags APIs: {@link removeAllFeatureFlags}. */ export const clearAllExperiments = () => { NativeInstabug.clearAllExperiments(); @@ -568,7 +568,7 @@ export const clearAllExperiments = () => { /** * Add feature flags to the next report. - * @param featureFlags An array of featureFlags to add to the next report. + * @param featureFlags An array of feature flags to add to the next report. */ export const addFeatureFlags = (featureFlags: FeatureFlag[]) => { const flags: Record = {}; From 966fd6cd7a819d22ea554e7ee8a99b731ebdf56d Mon Sep 17 00:00:00 2001 From: Ahmed alaa Date: Mon, 15 Jul 2024 14:52:22 +0300 Subject: [PATCH 8/9] fix: format files --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c26801de2..1d91867e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,11 @@ ## Added -- Add support for Feature Flags APIs `Instabug.addFeatureFlags`, `Instabug.removeFeatureFlags` and `Instabug.clearAllFeatureFlags` ([#1230](https://github.com/Instabug/Instabug-Flutter/pull/1230)). +- Add support for Feature Flags APIs `Instabug.addFeatureFlags`, `Instabug.removeFeatureFlags` and `Instabug.clearAllFeatureFlags` ([#1230](https://github.com/Instabug/Instabug-React-Native/pull/1230)). ### Deprecated -- Deprecate Experiments APIs `Instabug.addExperiments`, `Instabug.removeExperiments` and `Instabug.clearAllExperiments` in favor of the new Feature Flags APIs ([#1230](https://github.com/Instabug/Instabug-Flutter/pull/1230)). +- Deprecate Experiments APIs `Instabug.addExperiments`, `Instabug.removeExperiments` and `Instabug.clearAllExperiments` in favor of the new Feature Flags APIs ([#1230](https://github.com/Instabug/Instabug-React-Native/pull/1230)). ## [13.2.0](https://github.com/Instabug/Instabug-React-Native/compare/v13.1.1...v13.2.0) (July 7, 2024) From 967f7722c59e5212e78e378824b8cb3d20782629 Mon Sep 17 00:00:00 2001 From: Ahmed alaa Date: Mon, 15 Jul 2024 14:52:22 +0300 Subject: [PATCH 9/9] fix: format files --- CHANGELOG.md | 4 ++-- src/modules/Instabug.ts | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c26801de2..1d91867e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,11 @@ ## Added -- Add support for Feature Flags APIs `Instabug.addFeatureFlags`, `Instabug.removeFeatureFlags` and `Instabug.clearAllFeatureFlags` ([#1230](https://github.com/Instabug/Instabug-Flutter/pull/1230)). +- Add support for Feature Flags APIs `Instabug.addFeatureFlags`, `Instabug.removeFeatureFlags` and `Instabug.clearAllFeatureFlags` ([#1230](https://github.com/Instabug/Instabug-React-Native/pull/1230)). ### Deprecated -- Deprecate Experiments APIs `Instabug.addExperiments`, `Instabug.removeExperiments` and `Instabug.clearAllExperiments` in favor of the new Feature Flags APIs ([#1230](https://github.com/Instabug/Instabug-Flutter/pull/1230)). +- Deprecate Experiments APIs `Instabug.addExperiments`, `Instabug.removeExperiments` and `Instabug.clearAllExperiments` in favor of the new Feature Flags APIs ([#1230](https://github.com/Instabug/Instabug-React-Native/pull/1230)). ## [13.2.0](https://github.com/Instabug/Instabug-React-Native/compare/v13.1.1...v13.2.0) (July 7, 2024) diff --git a/src/modules/Instabug.ts b/src/modules/Instabug.ts index 156761d22..baec7660a 100644 --- a/src/modules/Instabug.ts +++ b/src/modules/Instabug.ts @@ -571,12 +571,8 @@ export const clearAllExperiments = () => { * @param featureFlags An array of feature flags to add to the next report. */ export const addFeatureFlags = (featureFlags: FeatureFlag[]) => { - const flags: Record = {}; - - for (const item of featureFlags) { - flags[item.name] = item.variant ? item.variant : ''; - } - + const entries = featureFlags.map((item) => [item.name, item.variant || '']); + const flags = Object.fromEntries(entries); NativeInstabug.addFeatureFlags(flags); };