{"action":"created","comment":{"url":"https://api.github.com/repos/Qabel/qabel-android/pulls/comments/60896956","id":60896956,"diff_hunk":"@@ -0,0 +1,189 @@\n+package de.qabel.qabelbox.communication;\n+\n+import android.content.Context;\n+import android.content.Intent;\n+import android.net.ConnectivityManager;\n+import android.net.NetworkInfo;\n+import android.support.annotation.Nullable;\n+\n+import org.json.JSONException;\n+import org.json.JSONObject;\n+import org.junit.Before;\n+import org.junit.Test;\n+import org.junit.runner.RunWith;\n+import org.robolectric.RobolectricGradleTestRunner;\n+import org.robolectric.RuntimeEnvironment;\n+import org.robolectric.annotation.Config;\n+import org.robolectric.shadows.ShadowConnectivityManager;\n+import org.robolectric.shadows.ShadowNetworkInfo;\n+\n+import java.net.URI;\n+import java.util.ArrayList;\n+import java.util.Collection;\n+\n+import de.qabel.core.config.DropServer;\n+import de.qabel.core.config.Identity;\n+import de.qabel.core.crypto.QblECKeyPair;\n+import de.qabel.core.drop.AdjustableDropIdGenerator;\n+import de.qabel.core.drop.DropIdGenerator;\n+import de.qabel.core.drop.DropURL;\n+import de.qabel.qabelbox.BuildConfig;\n+import de.qabel.qabelbox.QabelBoxApplication;\n+import de.qabel.qabelbox.RoboApplication;\n+import de.qabel.qabelbox.communication.callbacks.JsonRequestCallback;\n+import de.qabel.qabelbox.config.AppPreference;\n+import okhttp3.Response;\n+\n+import static junit.framework.Assert.assertNotNull;\n+import static junit.framework.Assert.assertTrue;\n+import static junit.framework.Assert.fail;\n+import static org.robolectric.Shadows.shadowOf;\n+\n+@RunWith(RobolectricGradleTestRunner.class)\n+@Config(application = RoboApplication.class, constants = BuildConfig.class, shadows = {ShadowConnectivityManager.class})\n+public class OfflineTest {\n+\n+    private void setConnectivity(Context context, boolean connected) {\n+        ConnectivityManager connectivityManager = (ConnectivityManager)\n+                RuntimeEnvironment.application.getSystemService(Context.CONNECTIVITY_SERVICE);\n+\n+        ShadowConnectivityManager shadowCM = shadowOf(connectivityManager);\n+\n+        NetworkInfo disconnectedInfo = ShadowNetworkInfo.newInstance(\n+                NetworkInfo.DetailedState.DISCONNECTED,\n+                ConnectivityManager.TYPE_MOBILE,\n+                ConnectivityManager.TYPE_MOBILE_MMS,\n+                true,\n+                connected);\n+        shadowCM.setNetworkInfo(\n+                ConnectivityManager.TYPE_MOBILE, disconnectedInfo);\n+        shadowCM.setActiveNetworkInfo(disconnectedInfo);\n+        context.sendBroadcast(new Intent(android.net.ConnectivityManager.CONNECTIVITY_ACTION));\n+    }\n+\n+    public Identity createIdentity(String identityName) {\n+        URI uri = URI.create(QabelBoxApplication.DEFAULT_DROP_SERVER);\n+        DropServer dropServer = new DropServer(uri, \"\", true);\n+        DropIdGenerator adjustableDropIdGenerator = new AdjustableDropIdGenerator(2 * 8);\n+        DropURL dropURL = new DropURL(dropServer, adjustableDropIdGenerator);\n+        Collection<DropURL> dropURLs = new ArrayList<>();\n+        dropURLs.add(dropURL);\n+\n+        Identity identity = new Identity(identityName, dropURLs, new QblECKeyPair());\n+        identity.getPrefixes().add(\"test\");\n+        return identity;\n+    }\n+\n+    @Before\n+    public void setUp() {\n+        QabelBoxApplication application = (QabelBoxApplication) RuntimeEnvironment.application;\n+        application.getService().addIdentity(createIdentity(\"spoon\"));\n+        AppPreference preference = new AppPreference(application);\n+        preference.setToken(\"MAGICFAIRY\");\n+        preference.setAccountName(\"TestFoo\");\n+        URLs.setBaseBlockURL(\"http://testing.qabel.de:8888\");\n+    }\n+\n+    private boolean successIsOffline;\n+\n+    @Test\n+    public void testDeviceIsOffline() {\n+        Context context = RuntimeEnvironment.application;\n+        PrefixServer testServer = new PrefixServer();\n+\n+        successIsOffline = false;\n+\n+        setConnectivity(context, false);\n+\n+        testServer.getPrefix(context, new JsonRequestCallback(new int[]{201}) {\n+            @Override\n+            protected void onError(Exception e, @Nullable Response response) {\n+                e.printStackTrace();\n+                fail(\"Request ended with error\");\n+            }\n+\n+            @Override\n+            protected void onJSONSuccess(Response response, JSONObject result) {\n+                try {\n+                    assertNotNull(result.getString(\"prefix\"));\n+                } catch (JSONException e) {\n+                    fail(\"Cannot parse JSON\");\n+                }\n+                successIsOffline = true;\n+            }\n+        });\n+\n+\n+        try {\n+            Thread.sleep(2000);\n+        } catch (InterruptedException ex) {\n+            Thread.currentThread().interrupt();\n+        }\n+\n+        setConnectivity(context, true);\n+\n+        try {\n+            int i = 0;\n+            while (i < 10 && !successIsOffline) {\n+                Thread.sleep(1000);\n+                i++;\n+            }\n+            assertTrue(\"No Response received\", successIsOffline);\n+        } catch (InterruptedException ex) {\n+            ex.printStackTrace();\n+            Thread.currentThread().interrupt();\n+            fail(\"Test interrupted\");\n+        }\n+    }\n+\n+    private boolean successGoOffline;\n+\n+    @Test\n+    public void testDeviceGoOffline() {\n+        Context context = RuntimeEnvironment.application;\n+        PrefixServer testServer = new PrefixServer();\n+\n+        successGoOffline = false;\n+\n+        testServer.getPrefix(context, new JsonRequestCallback(new int[]{201}) {\n+            @Override\n+            protected void onError(Exception e, @Nullable Response response) {\n+                e.printStackTrace();\n+                fail(\"Request ended with error\");\n+            }\n+\n+            @Override\n+            protected void onJSONSuccess(Response response, JSONObject result) {\n+                try {\n+                    assertNotNull(result.getString(\"prefix\"));\n+                } catch (JSONException e) {\n+                    fail(\"Cannot parse JSON\");\n+                }\n+                successGoOffline = true;\n+            }\n+        });\n+\n+        setConnectivity(context, false);\n+\n+        try {\n+            Thread.sleep(2000);\n+        } catch (InterruptedException ex) {\n+            Thread.currentThread().interrupt();\n+        }\n+\n+        setConnectivity(context, true);\n+\n+        try {\n+            int i = 0;\n+            while (i < 10 && !successGoOffline) {\n+                Thread.sleep(1000);\n+                i++;\n+            }\n+            assertTrue(\"No Response received\", successGoOffline);\n+        } catch (InterruptedException ex) {\n+            ex.printStackTrace();","path":"qabelbox/src/test/java/de/qabel/qabelbox/communication/OfflineTest.java","position":184,"original_position":184,"commit_id":"58bb244a5f5581d3ac31864a4580a03abe379384","original_commit_id":"58bb244a5f5581d3ac31864a4580a03abe379384","user":{"login":"audax","id":858339,"avatar_url":"https://avatars.githubusercontent.com/u/858339?v=3","gravatar_id":"","url":"https://api.github.com/users/audax","html_url":"https://github.com/audax","followers_url":"https://api.github.com/users/audax/followers","following_url":"https://api.github.com/users/audax/following{/other_user}","gists_url":"https://api.github.com/users/audax/gists{/gist_id}","starred_url":"https://api.github.com/users/audax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/audax/subscriptions","organizations_url":"https://api.github.com/users/audax/orgs","repos_url":"https://api.github.com/users/audax/repos","events_url":"https://api.github.com/users/audax/events{/privacy}","received_events_url":"https://api.github.com/users/audax/received_events","type":"User","site_admin":false},"body":"no printStacktrace please","created_at":"2016-04-25T11:10:58Z","updated_at":"2016-04-25T11:10:58Z","html_url":"https://github.com/Qabel/qabel-android/pull/458#discussion_r60896956","pull_request_url":"https://api.github.com/repos/Qabel/qabel-android/pulls/458","_links":{"self":{"href":"https://api.github.com/repos/Qabel/qabel-android/pulls/comments/60896956"},"html":{"href":"https://github.com/Qabel/qabel-android/pull/458#discussion_r60896956"},"pull_request":{"href":"https://api.github.com/repos/Qabel/qabel-android/pulls/458"}}},"pull_request":{"url":"https://api.github.com/repos/Qabel/qabel-android/pulls/458","id":66166852,"html_url":"https://github.com/Qabel/qabel-android/pull/458","diff_url":"https://github.com/Qabel/qabel-android/pull/458.diff","patch_url":"https://github.com/Qabel/qabel-android/pull/458.patch","issue_url":"https://api.github.com/repos/Qabel/qabel-android/issues/458","number":458,"state":"open","locked":false,"title":"Offline indicator","user":{"login":"JoGir","id":16522130,"avatar_url":"https://avatars.githubusercontent.com/u/16522130?v=3","gravatar_id":"","url":"https://api.github.com/users/JoGir","html_url":"https://github.com/JoGir","followers_url":"https://api.github.com/users/JoGir/followers","following_url":"https://api.github.com/users/JoGir/following{/other_user}","gists_url":"https://api.github.com/users/JoGir/gists{/gist_id}","starred_url":"https://api.github.com/users/JoGir/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JoGir/subscriptions","organizations_url":"https://api.github.com/users/JoGir/orgs","repos_url":"https://api.github.com/users/JoGir/repos","events_url":"https://api.github.com/users/JoGir/events{/privacy}","received_events_url":"https://api.github.com/users/JoGir/received_events","type":"User","site_admin":false},"body":"resolves #162","created_at":"2016-04-12T14:26:15Z","updated_at":"2016-04-25T11:10:58Z","closed_at":null,"merged_at":null,"merge_commit_sha":"198f7928f4f7fa28d88333e9028069f979ae4c6d","assignee":{"login":"audax","id":858339,"avatar_url":"https://avatars.githubusercontent.com/u/858339?v=3","gravatar_id":"","url":"https://api.github.com/users/audax","html_url":"https://github.com/audax","followers_url":"https://api.github.com/users/audax/followers","following_url":"https://api.github.com/users/audax/following{/other_user}","gists_url":"https://api.github.com/users/audax/gists{/gist_id}","starred_url":"https://api.github.com/users/audax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/audax/subscriptions","organizations_url":"https://api.github.com/users/audax/orgs","repos_url":"https://api.github.com/users/audax/repos","events_url":"https://api.github.com/users/audax/events{/privacy}","received_events_url":"https://api.github.com/users/audax/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/Qabel/qabel-android/pulls/458/commits","review_comments_url":"https://api.github.com/repos/Qabel/qabel-android/pulls/458/comments","review_comment_url":"https://api.github.com/repos/Qabel/qabel-android/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Qabel/qabel-android/issues/458/comments","statuses_url":"https://api.github.com/repos/Qabel/qabel-android/statuses/58bb244a5f5581d3ac31864a4580a03abe379384","head":{"label":"JoGir:offline_indicator","ref":"offline_indicator","sha":"58bb244a5f5581d3ac31864a4580a03abe379384","user":{"login":"JoGir","id":16522130,"avatar_url":"https://avatars.githubusercontent.com/u/16522130?v=3","gravatar_id":"","url":"https://api.github.com/users/JoGir","html_url":"https://github.com/JoGir","followers_url":"https://api.github.com/users/JoGir/followers","following_url":"https://api.github.com/users/JoGir/following{/other_user}","gists_url":"https://api.github.com/users/JoGir/gists{/gist_id}","starred_url":"https://api.github.com/users/JoGir/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JoGir/subscriptions","organizations_url":"https://api.github.com/users/JoGir/orgs","repos_url":"https://api.github.com/users/JoGir/repos","events_url":"https://api.github.com/users/JoGir/events{/privacy}","received_events_url":"https://api.github.com/users/JoGir/received_events","type":"User","site_admin":false},"repo":{"id":53146477,"name":"qabel-android","full_name":"JoGir/qabel-android","owner":{"login":"JoGir","id":16522130,"avatar_url":"https://avatars.githubusercontent.com/u/16522130?v=3","gravatar_id":"","url":"https://api.github.com/users/JoGir","html_url":"https://github.com/JoGir","followers_url":"https://api.github.com/users/JoGir/followers","following_url":"https://api.github.com/users/JoGir/following{/other_user}","gists_url":"https://api.github.com/users/JoGir/gists{/gist_id}","starred_url":"https://api.github.com/users/JoGir/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JoGir/subscriptions","organizations_url":"https://api.github.com/users/JoGir/orgs","repos_url":"https://api.github.com/users/JoGir/repos","events_url":"https://api.github.com/users/JoGir/events{/privacy}","received_events_url":"https://api.github.com/users/JoGir/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/JoGir/qabel-android","description":"Android Frontend of Qabel","fork":true,"url":"https://api.github.com/repos/JoGir/qabel-android","forks_url":"https://api.github.com/repos/JoGir/qabel-android/forks","keys_url":"https://api.github.com/repos/JoGir/qabel-android/keys{/key_id}","collaborators_url":"https://api.github.com/repos/JoGir/qabel-android/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/JoGir/qabel-android/teams","hooks_url":"https://api.github.com/repos/JoGir/qabel-android/hooks","issue_events_url":"https://api.github.com/repos/JoGir/qabel-android/issues/events{/number}","events_url":"https://api.github.com/repos/JoGir/qabel-android/events","assignees_url":"https://api.github.com/repos/JoGir/qabel-android/assignees{/user}","branches_url":"https://api.github.com/repos/JoGir/qabel-android/branches{/branch}","tags_url":"https://api.github.com/repos/JoGir/qabel-android/tags","blobs_url":"https://api.github.com/repos/JoGir/qabel-android/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/JoGir/qabel-android/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/JoGir/qabel-android/git/refs{/sha}","trees_url":"https://api.github.com/repos/JoGir/qabel-android/git/trees{/sha}","statuses_url":"https://api.github.com/repos/JoGir/qabel-android/statuses/{sha}","languages_url":"https://api.github.com/repos/JoGir/qabel-android/languages","stargazers_url":"https://api.github.com/repos/JoGir/qabel-android/stargazers","contributors_url":"https://api.github.com/repos/JoGir/qabel-android/contributors","subscribers_url":"https://api.github.com/repos/JoGir/qabel-android/subscribers","subscription_url":"https://api.github.com/repos/JoGir/qabel-android/subscription","commits_url":"https://api.github.com/repos/JoGir/qabel-android/commits{/sha}","git_commits_url":"https://api.github.com/repos/JoGir/qabel-android/git/commits{/sha}","comments_url":"https://api.github.com/repos/JoGir/qabel-android/comments{/number}","issue_comment_url":"https://api.github.com/repos/JoGir/qabel-android/issues/comments{/number}","contents_url":"https://api.github.com/repos/JoGir/qabel-android/contents/{+path}","compare_url":"https://api.github.com/repos/JoGir/qabel-android/compare/{base}...{head}","merges_url":"https://api.github.com/repos/JoGir/qabel-android/merges","archive_url":"https://api.github.com/repos/JoGir/qabel-android/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/JoGir/qabel-android/downloads","issues_url":"https://api.github.com/repos/JoGir/qabel-android/issues{/number}","pulls_url":"https://api.github.com/repos/JoGir/qabel-android/pulls{/number}","milestones_url":"https://api.github.com/repos/JoGir/qabel-android/milestones{/number}","notifications_url":"https://api.github.com/repos/JoGir/qabel-android/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/JoGir/qabel-android/labels{/name}","releases_url":"https://api.github.com/repos/JoGir/qabel-android/releases{/id}","deployments_url":"https://api.github.com/repos/JoGir/qabel-android/deployments","created_at":"2016-03-04T15:50:34Z","updated_at":"2016-03-04T15:50:35Z","pushed_at":"2016-04-24T17:04:54Z","git_url":"git://github.com/JoGir/qabel-android.git","ssh_url":"git@github.com:JoGir/qabel-android.git","clone_url":"https://github.com/JoGir/qabel-android.git","svn_url":"https://github.com/JoGir/qabel-android","homepage":"","size":6082,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"Qabel:master","ref":"master","sha":"ec66597494b2989e2c44c36947c2f78ce0a400b6","user":{"login":"Qabel","id":7711470,"avatar_url":"https://avatars.githubusercontent.com/u/7711470?v=3","gravatar_id":"","url":"https://api.github.com/users/Qabel","html_url":"https://github.com/Qabel","followers_url":"https://api.github.com/users/Qabel/followers","following_url":"https://api.github.com/users/Qabel/following{/other_user}","gists_url":"https://api.github.com/users/Qabel/gists{/gist_id}","starred_url":"https://api.github.com/users/Qabel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Qabel/subscriptions","organizations_url":"https://api.github.com/users/Qabel/orgs","repos_url":"https://api.github.com/users/Qabel/repos","events_url":"https://api.github.com/users/Qabel/events{/privacy}","received_events_url":"https://api.github.com/users/Qabel/received_events","type":"Organization","site_admin":false},"repo":{"id":37848561,"name":"qabel-android","full_name":"Qabel/qabel-android","owner":{"login":"Qabel","id":7711470,"avatar_url":"https://avatars.githubusercontent.com/u/7711470?v=3","gravatar_id":"","url":"https://api.github.com/users/Qabel","html_url":"https://github.com/Qabel","followers_url":"https://api.github.com/users/Qabel/followers","following_url":"https://api.github.com/users/Qabel/following{/other_user}","gists_url":"https://api.github.com/users/Qabel/gists{/gist_id}","starred_url":"https://api.github.com/users/Qabel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Qabel/subscriptions","organizations_url":"https://api.github.com/users/Qabel/orgs","repos_url":"https://api.github.com/users/Qabel/repos","events_url":"https://api.github.com/users/Qabel/events{/privacy}","received_events_url":"https://api.github.com/users/Qabel/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Qabel/qabel-android","description":"Android Frontend of Qabel","fork":false,"url":"https://api.github.com/repos/Qabel/qabel-android","forks_url":"https://api.github.com/repos/Qabel/qabel-android/forks","keys_url":"https://api.github.com/repos/Qabel/qabel-android/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Qabel/qabel-android/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Qabel/qabel-android/teams","hooks_url":"https://api.github.com/repos/Qabel/qabel-android/hooks","issue_events_url":"https://api.github.com/repos/Qabel/qabel-android/issues/events{/number}","events_url":"https://api.github.com/repos/Qabel/qabel-android/events","assignees_url":"https://api.github.com/repos/Qabel/qabel-android/assignees{/user}","branches_url":"https://api.github.com/repos/Qabel/qabel-android/branches{/branch}","tags_url":"https://api.github.com/repos/Qabel/qabel-android/tags","blobs_url":"https://api.github.com/repos/Qabel/qabel-android/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Qabel/qabel-android/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Qabel/qabel-android/git/refs{/sha}","trees_url":"https://api.github.com/repos/Qabel/qabel-android/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Qabel/qabel-android/statuses/{sha}","languages_url":"https://api.github.com/repos/Qabel/qabel-android/languages","stargazers_url":"https://api.github.com/repos/Qabel/qabel-android/stargazers","contributors_url":"https://api.github.com/repos/Qabel/qabel-android/contributors","subscribers_url":"https://api.github.com/repos/Qabel/qabel-android/subscribers","subscription_url":"https://api.github.com/repos/Qabel/qabel-android/subscription","commits_url":"https://api.github.com/repos/Qabel/qabel-android/commits{/sha}","git_commits_url":"https://api.github.com/repos/Qabel/qabel-android/git/commits{/sha}","comments_url":"https://api.github.com/repos/Qabel/qabel-android/comments{/number}","issue_comment_url":"https://api.github.com/repos/Qabel/qabel-android/issues/comments{/number}","contents_url":"https://api.github.com/repos/Qabel/qabel-android/contents/{+path}","compare_url":"https://api.github.com/repos/Qabel/qabel-android/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Qabel/qabel-android/merges","archive_url":"https://api.github.com/repos/Qabel/qabel-android/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Qabel/qabel-android/downloads","issues_url":"https://api.github.com/repos/Qabel/qabel-android/issues{/number}","pulls_url":"https://api.github.com/repos/Qabel/qabel-android/pulls{/number}","milestones_url":"https://api.github.com/repos/Qabel/qabel-android/milestones{/number}","notifications_url":"https://api.github.com/repos/Qabel/qabel-android/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Qabel/qabel-android/labels{/name}","releases_url":"https://api.github.com/repos/Qabel/qabel-android/releases{/id}","deployments_url":"https://api.github.com/repos/Qabel/qabel-android/deployments","created_at":"2015-06-22T10:05:20Z","updated_at":"2016-04-09T19:42:30Z","pushed_at":"2016-04-25T10:56:20Z","git_url":"git://github.com/Qabel/qabel-android.git","ssh_url":"git@github.com:Qabel/qabel-android.git","clone_url":"https://github.com/Qabel/qabel-android.git","svn_url":"https://github.com/Qabel/qabel-android","homepage":"","size":6739,"stargazers_count":1,"watchers_count":1,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":12,"mirror_url":null,"open_issues_count":82,"forks":12,"open_issues":82,"watchers":1,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Qabel/qabel-android/pulls/458"},"html":{"href":"https://github.com/Qabel/qabel-android/pull/458"},"issue":{"href":"https://api.github.com/repos/Qabel/qabel-android/issues/458"},"comments":{"href":"https://api.github.com/repos/Qabel/qabel-android/issues/458/comments"},"review_comments":{"href":"https://api.github.com/repos/Qabel/qabel-android/pulls/458/comments"},"review_comment":{"href":"https://api.github.com/repos/Qabel/qabel-android/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Qabel/qabel-android/pulls/458/commits"},"statuses":{"href":"https://api.github.com/repos/Qabel/qabel-android/statuses/58bb244a5f5581d3ac31864a4580a03abe379384"}}}}