diff --git a/CHANGELOG.md b/CHANGELOG.md index 8336437fed..70a1a51d14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 4.3.3 (2018-04-04) + +### Bug fixes + +* Prevent duplicate reports being delivered in low connectivity situations + [#270](https://github.com/bugsnag/bugsnag-android/pull/270) +* Fix possible NPE when reading default metadata filters + [#263](https://github.com/bugsnag/bugsnag-android/pull/263) + ## 4.3.2 (2018-03-09) ### Bug fixes diff --git a/gradle.properties b/gradle.properties index fd51f85366..df80939f92 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ org.gradle.jvmargs=-Xmx1536m # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -VERSION_NAME=4.3.2 +VERSION_NAME=4.3.3 GROUP=com.bugsnag POM_SCM_URL=https://github.com/bugsnag/bugsnag-android POM_SCM_CONNECTION=scm:git@github.com:bugsnag/bugsnag-android.git diff --git a/sdk/src/androidTest/java/com/bugsnag/android/ClientConfigTest.java b/sdk/src/androidTest/java/com/bugsnag/android/ClientConfigTest.java new file mode 100644 index 0000000000..875a1d571c --- /dev/null +++ b/sdk/src/androidTest/java/com/bugsnag/android/ClientConfigTest.java @@ -0,0 +1,89 @@ +package com.bugsnag.android; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class ClientConfigTest { + + private Configuration config; + private Client client; + + /** + * Generates a configuration and clears sharedPrefs values to begin the test with a clean slate + * @throws Exception if initialisation failed + */ + @Before + public void setUp() throws Exception { + Context context = InstrumentationRegistry.getContext(); + config = new Configuration("api-key"); + client = new Client(context, config); + } + + @Test + public void testSetReleaseStage() throws Exception { + client.setReleaseStage("beta"); + assertEquals("beta", config.getReleaseStage()); + } + + @Test + public void testSetAutoCaptureSessions() throws Exception { + client.setAutoCaptureSessions(true); + assertEquals(true, config.shouldAutoCaptureSessions()); + } + + @Test + public void testSetAppVersion() throws Exception { + client.setAppVersion("5.6.7"); + assertEquals("5.6.7", config.getAppVersion()); + } + + @Test + public void testSetContext() throws Exception { + client.setContext("JunitTest"); + assertEquals("JunitTest", client.getContext()); + assertEquals("JunitTest", config.getContext()); + } + + @Test + public void testSetEndpoint() throws Exception { + client.setEndpoint("http://example.com/bugsnag"); + assertEquals("http://example.com/bugsnag", config.getEndpoint()); + } + + @Test + public void testSetBuildUuid() throws Exception { + client.setBuildUUID("gh905"); + assertEquals("gh905", config.getBuildUUID()); + } + + @Test + public void testSetIgnoreClasses() throws Exception { + client.setIgnoreClasses("RuntimeException", "Foo"); + assertArrayEquals(new String[]{"RuntimeException", "Foo"}, config.getIgnoreClasses()); + } + + @Test + public void testSetNotifyReleaseStages() throws Exception { + client.setNotifyReleaseStages("beta", "prod"); + assertArrayEquals(new String[]{"beta", "prod"}, config.getNotifyReleaseStages()); + } + + @Test + public void testSetSendThreads() throws Exception { + client.setSendThreads(false); + assertFalse(config.getSendThreads()); + } + +} diff --git a/sdk/src/androidTest/java/com/bugsnag/android/ConfigurationTest.java b/sdk/src/androidTest/java/com/bugsnag/android/ConfigurationTest.java index ba78b03d5f..ddf1c0ad18 100644 --- a/sdk/src/androidTest/java/com/bugsnag/android/ConfigurationTest.java +++ b/sdk/src/androidTest/java/com/bugsnag/android/ConfigurationTest.java @@ -1,5 +1,6 @@ package com.bugsnag.android; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -89,6 +90,10 @@ public void testInProject() { // Shouldn't be inProject if class not in projectPackages config.setProjectPackages(new String[]{"com.bugsnag.android"}); assertFalse(config.inProject("java.io.IOException")); + + // Should be inProject if class is in projectPackages with null element + config.setProjectPackages(new String[]{null, "java.io.IOException"}); + assertTrue(config.inProject("java.io.IOException")); } @Test @@ -124,4 +129,39 @@ public void testSessionApiHeaders() throws Exception { assertNotNull(headers.get("Bugsnag-Payload-Version")); } + @Test + public void testOverrideContext() throws Exception { + config.setContext("LevelOne"); + assertEquals("LevelOne", config.getContext()); + } + + @Test + public void testOverrideFilters() throws Exception { + config.setFilters(new String[]{"Foo"}); + assertArrayEquals(new String[]{"Foo"}, config.getFilters()); + } + + @Test + public void testOverrideIgnoreClasses() throws Exception { + config.setIgnoreClasses(new String[]{"Bar"}); + assertArrayEquals(new String[]{"Bar"}, config.getIgnoreClasses()); + } + + @Test + public void testOverrideNotifyReleaseStages() throws Exception { + config.setNotifyReleaseStages(new String[]{"Test"}); + assertArrayEquals(new String[]{"Test"}, config.getNotifyReleaseStages()); + } + + @Test + public void testOverrideNotifierType() throws Exception { + config.setNotifierType("React Native"); + assertEquals("React Native", config.getNotifierType()); + } + + @Test + public void testOverrideCodeBundleId() throws Exception { + config.setCodeBundleId("abc123"); + assertEquals("abc123", config.getCodeBundleId()); + } } diff --git a/sdk/src/androidTest/java/com/bugsnag/android/ErrorTest.java b/sdk/src/androidTest/java/com/bugsnag/android/ErrorTest.java index 66161f5b91..3e9e5c4eb8 100644 --- a/sdk/src/androidTest/java/com/bugsnag/android/ErrorTest.java +++ b/sdk/src/androidTest/java/com/bugsnag/android/ErrorTest.java @@ -1,13 +1,17 @@ package com.bugsnag.android; import static com.bugsnag.android.BugsnagTestUtils.generateSession; +import static com.bugsnag.android.BugsnagTestUtils.generateSessionTracker; import static com.bugsnag.android.BugsnagTestUtils.streamableToJson; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.content.Context; +import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; @@ -264,6 +268,85 @@ public void checkExceptionMessageNullity() throws Exception { assertEquals("", err.getExceptionMessage()); } + @Test + public void testNullSeverity() throws Exception { + error.setSeverity(null); + assertEquals(Severity.WARNING, error.getSeverity()); + } + + @Test + public void testSendThreadsDisabled() throws Exception { + config.setSendThreads(false); + JSONObject errorJson = streamableToJson(error); + assertFalse(errorJson.has("threads")); + } + + @Test + public void testBugsnagExceptionName() throws Exception { + BugsnagException exception = new BugsnagException("Busgang", "exceptional", + new StackTraceElement[]{}); + Error err = new Error.Builder(config, exception, null).build(); + assertEquals("Busgang", err.getExceptionName()); + } + + @Test + public void testConfigContext() throws Exception { + String expected = "Junit test suite"; + error.setContext(null); + config.setContext(expected); + assertEquals(expected, error.getContext()); + } + + @Test + public void testNullContext() throws Exception { + error.setContext(null); + error.setAppData(null); + assertNull(error.getContext()); + } + + @Test + public void testAppDataContext() throws Exception { + error.setContext(null); + Context context = InstrumentationRegistry.getContext(); + SessionTracker sessionTracker = generateSessionTracker(); + String expectedContext = "FooActivity"; + sessionTracker.updateForegroundTracker(expectedContext, + true, System.currentTimeMillis()); + error.setAppData(new AppData(context, config, sessionTracker)); + assertEquals(expectedContext, error.getContext()); + } + + + @Test + public void testSetUser() throws Exception { + String firstId = "123"; + String firstEmail = "fake@example.com"; + String firstName = "Bob Swaggins"; + error.setUser(firstId, firstEmail, firstName); + + assertEquals(firstId, error.getUser().getId()); + assertEquals(firstEmail, error.getUser().getEmail()); + assertEquals(firstName, error.getUser().getName()); + + String userId = "foo"; + error.setUserId(userId); + assertEquals(userId, error.getUser().getId()); + assertEquals(firstEmail, error.getUser().getEmail()); + assertEquals(firstName, error.getUser().getName()); + + String userEmail = "another@example.com"; + error.setUserEmail(userEmail); + assertEquals(userId, error.getUser().getId()); + assertEquals(userEmail, error.getUser().getEmail()); + assertEquals(firstName, error.getUser().getName()); + + String userName = "Isaac"; + error.setUserName(userName); + assertEquals(userId, error.getUser().getId()); + assertEquals(userEmail, error.getUser().getEmail()); + assertEquals(userName, error.getUser().getName()); + } + private void validateEmptyAttributes(JSONObject severityReason) { try { severityReason.getJSONObject("attributes"); diff --git a/sdk/src/androidTest/java/com/bugsnag/android/MetaDataTest.java b/sdk/src/androidTest/java/com/bugsnag/android/MetaDataTest.java index d6be1be989..d2f592d528 100644 --- a/sdk/src/androidTest/java/com/bugsnag/android/MetaDataTest.java +++ b/sdk/src/androidTest/java/com/bugsnag/android/MetaDataTest.java @@ -3,6 +3,7 @@ import static com.bugsnag.android.BugsnagTestUtils.streamableToJson; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.support.test.filters.SmallTest; @@ -233,4 +234,13 @@ public void testFilterMetadataOverride() throws Exception { client.setMetaData(data); assertArrayEquals(new String[]{"CUSTOM"}, data.getFilters()); } + + @Test + public void testClearTab() throws Exception { + MetaData metaData = new MetaData(); + metaData.addToTab("example", "string", "value"); + metaData.clearTab("example"); + JSONObject json = streamableToJson(metaData); + assertFalse(json.has("example")); + } } diff --git a/sdk/src/androidTest/java/com/bugsnag/android/ReportTest.java b/sdk/src/androidTest/java/com/bugsnag/android/ReportTest.java index 37650ff248..a447bd82b7 100644 --- a/sdk/src/androidTest/java/com/bugsnag/android/ReportTest.java +++ b/sdk/src/androidTest/java/com/bugsnag/android/ReportTest.java @@ -50,4 +50,26 @@ public void testModifyingGroupingHash() throws JSONException, IOException { JSONObject event = events.getJSONObject(0); assertEquals(groupingHash, event.getString("groupingHash")); } + + @Test + public void testModifyReportDetails() throws Exception { + String apiKey = "custom-api-key"; + String notifierName = "React Native"; + String notifierUrl = "https://bugsnag.com/reactnative"; + String notifierVersion = "3.4.5"; + + report.setApiKey(apiKey); + report.setNotifierName(notifierName); + report.setNotifierURL(notifierUrl); + report.setNotifierVersion(notifierVersion); + + JSONObject reportJson = streamableToJson(report); + assertEquals(apiKey, reportJson.getString("apiKey")); + + JSONObject notifier = reportJson.getJSONObject("notifier"); + assertEquals(notifierName, notifier.getString("name")); + assertEquals(notifierVersion, notifier.getString("version")); + assertEquals(notifierUrl, notifier.getString("url")); + } + } diff --git a/sdk/src/main/java/com/bugsnag/android/Notifier.java b/sdk/src/main/java/com/bugsnag/android/Notifier.java index f58c841380..f31616b938 100644 --- a/sdk/src/main/java/com/bugsnag/android/Notifier.java +++ b/sdk/src/main/java/com/bugsnag/android/Notifier.java @@ -9,7 +9,7 @@ */ public class Notifier implements JsonStream.Streamable { static final String NOTIFIER_NAME = "Android Bugsnag Notifier"; - static final String NOTIFIER_VERSION = "4.3.2"; + static final String NOTIFIER_VERSION = "4.3.3"; static final String NOTIFIER_URL = "https://bugsnag.com"; private String name; private String version;