jenkins-bot has submitted this change and it was merged. (
https://gerrit.wikimedia.org/r/333499 )
Change subject: Replace EditTest with MockWebServer-based EditClientTest
......................................................................
Replace EditTest with MockWebServer-based EditClientTest
Bug: T154809
Change-Id: I5ab26370acc0e63fbe636275edf1c5ab4d24b3db
---
D app/src/androidTest/java/org/wikipedia/edit/EditTest.java
A app/src/test/java/org/wikipedia/edit/EditClientTest.java
A app/src/test/res/raw/api_error_assert_user_failed.json
A app/src/test/res/raw/edit_result_captcha.json
A app/src/test/res/raw/edit_result_spam_blacklist.json
A app/src/test/res/raw/edit_result_success.json
6 files changed, 172 insertions(+), 233 deletions(-)
Approvals:
Niedzielski: Looks good to me, approved
jenkins-bot: Verified
diff --git a/app/src/androidTest/java/org/wikipedia/edit/EditTest.java
b/app/src/androidTest/java/org/wikipedia/edit/EditTest.java
deleted file mode 100644
index 1e48e2f..0000000
--- a/app/src/androidTest/java/org/wikipedia/edit/EditTest.java
+++ /dev/null
@@ -1,233 +0,0 @@
-package org.wikipedia.edit;
-
-import android.support.annotation.NonNull;
-import android.support.test.filters.LargeTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.wikipedia.WikipediaApp;
-import org.wikipedia.captcha.CaptchaResult;
-import org.wikipedia.dataclient.WikiSite;
-import org.wikipedia.page.Namespace;
-import org.wikipedia.page.PageTitle;
-import org.wikipedia.testlib.TestLatch;
-
-import retrofit2.Call;
-
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-@LargeTest public class EditTest {
- private static final WikiSite TEST_WIKI_SITE =
WikiSite.forLanguageCode("test");
- private static final String ABUSE_FILTER_ERROR_PAGE_TITLE =
"Test_page_for_app_testing/AbuseFilter";
- private static final int DEFAULT_SECTION_ID = 0;
- // https://www.mediawiki.org/wiki/Manual:Edit_token#The_edit_token_suffix
- private static final String ANONYMOUS_TOKEN = "+\\";
- private static final String DEFAULT_SUMMARY = "";
-
- private EditClient client = new EditClient();
-
- @Before
- public void setUp() {
- // Cookies for a logged in session cannot be used with the anonymous
edit token.
- app().getCookieManager().clearAllCookies();
- }
-
- @Test
- public void testEdit() {
- PageTitle title = new PageTitle(null,
"Test_page_for_app_testing/Section1", TEST_WIKI_SITE);
- String wikitext = "== Section 2 ==\n\nEditing section INSERT RANDOM &
HERE test at "
- + System.currentTimeMillis();
- final int sectionId = 3;
- final TestLatch latch = new TestLatch();
-
- client.request(TEST_WIKI_SITE, title, sectionId, wikitext,
ANONYMOUS_TOKEN, DEFAULT_SUMMARY,
- false, null, null, new EditClient.Callback() {
- @Override
- public void success(@NonNull Call<Edit> call, @NonNull
EditResult result) {
- assertThat(result,
instanceOf(EditSuccessResult.class));
- latch.countDown();
- }
-
- @Override
- public void failure(@NonNull Call<Edit> call, @NonNull
Throwable caught) {
- throw new RuntimeException(caught);
- }
- });
- latch.await();
- }
-
- @Test
- public void testCaptcha() {
- PageTitle title = new PageTitle(null,
"Test_page_for_app_testing/Captcha", TEST_WIKI_SITE);
- String wikitext = "== Section 2 ==\n\nEditing by inserting an external
link https://"
- + System.currentTimeMillis();
- final TestLatch latch = new TestLatch();
-
- client.request(TEST_WIKI_SITE, title, DEFAULT_SECTION_ID, wikitext,
ANONYMOUS_TOKEN,
- DEFAULT_SUMMARY, false, null, null, new EditClient.Callback() {
- @Override
- public void success(@NonNull Call<Edit> call, @NonNull
EditResult result) {
- validateCaptcha(result);
- latch.countDown();
- }
-
- @Override
- public void failure(@NonNull Call<Edit> call, @NonNull
Throwable caught) {
- throw new RuntimeException(caught);
- }
- });
- latch.await();
- }
-
- /**
- * Test handling of abuse filter warnings which warn users about making
edits of a certain kind.
- *
- * Type: warn
- * Action: editing any userspace page while logged out
- * Filter: https://test.wikipedia.org/wiki/Special:AbuseFilter/94
- */
- @Test
- public void testAbuseFilterTriggerWarn() {
- PageTitle title = new PageTitle(null, "User:Yuvipandaaaaaaaa",
TEST_WIKI_SITE);
-
- // Rule 94 is only a warning so the initial attempt may be successful.
The second is
- // guaranteed to be a warning if different content is used.
@FlakyTest(tolerance = 2)
- // doesn't work with JUnit 4.
- for (int i = 0; i < 2; ++i) {
- String wikitext = "Testing Abusefilter by simply editing this
page. Triggering rule 94"
- + "at " + System.nanoTime();
- final TestLatch latch = new TestLatch();
-
- client.request(TEST_WIKI_SITE, title, DEFAULT_SECTION_ID,
wikitext, ANONYMOUS_TOKEN,
- DEFAULT_SUMMARY, false, null, null, new
EditClient.Callback() {
- @Override
- public void success(@NonNull Call<Edit> call, @NonNull
EditResult result) {
- if (!(result instanceof EditSuccessResult)) {
- assertThat(result,
instanceOf(EditAbuseFilterResult.class));
- //noinspection ConstantConditions
- assertThat(((EditAbuseFilterResult)
result).getType(),
- is(EditAbuseFilterResult.TYPE_ERROR));
- }
- latch.countDown();
- }
-
- @Override
- public void failure(@NonNull Call<Edit> call, @NonNull
Throwable caught) {
- throw new RuntimeException(caught);
- }
- });
- latch.await();
- }
- }
-
- /**
- * Test handling of abuse filter errors which completely disallow edits of
a certain kind.
- *
- * Type: disallow
- * Action: adding string "poop" to page text
- * Filter: https://test.wikipedia.org/wiki/Special:AbuseFilter/2
- */
- @Test
- public void testAbuseFilterTriggerStop() {
- PageTitle title = new PageTitle(null, ABUSE_FILTER_ERROR_PAGE_TITLE,
TEST_WIKI_SITE);
- String wikitext = "== Section 2 ==\n\nTriggering AbuseFilter number 2
by saying poop many"
- + "times at " + System.currentTimeMillis();
- final TestLatch latch = new TestLatch();
-
- client.request(TEST_WIKI_SITE, title, DEFAULT_SECTION_ID, wikitext,
ANONYMOUS_TOKEN,
- DEFAULT_SUMMARY, false, null, null, new EditClient.Callback() {
- @Override
- public void success(@NonNull Call<Edit> call, @NonNull
EditResult result) {
- assertThat(result,
instanceOf(EditAbuseFilterResult.class));
- assertThat(((EditAbuseFilterResult) result).getType(),
- is(EditAbuseFilterResult.TYPE_ERROR));
- latch.countDown();
- }
-
- @Override
- public void failure(@NonNull Call<Edit> call, @NonNull
Throwable caught) {
- throw new RuntimeException(caught);
- }
- });
- latch.await();
- }
-
- /**
- * Test the app's handling of the abuse filter emitting arbitrary error
codes.
- *
- * Type: warn
- * Action: adding string "appcrashtest" to page text
- * Filter: https://test.wikipedia.org/wiki/Special:AbuseFilter/152
- */
- @Test
- public void testAbuseFilterTriggerStopOnArbitraryErrorCode() {
- PageTitle title = new PageTitle(null, ABUSE_FILTER_ERROR_PAGE_TITLE,
TEST_WIKI_SITE);
- String wikitext = "== Section 2 ==\n\nTriggering AbuseFilter number
152 by saying"
- + "appcrashtest many times at " + System.currentTimeMillis();
- final TestLatch latch = new TestLatch();
-
- client.request(TEST_WIKI_SITE, title, DEFAULT_SECTION_ID, wikitext,
ANONYMOUS_TOKEN,
- DEFAULT_SUMMARY, false, null, null, new EditClient.Callback() {
- @Override
- public void success(@NonNull Call<Edit> call, @NonNull
EditResult result) {
- assertThat(result,
instanceOf(EditAbuseFilterResult.class));
- assertThat(((EditAbuseFilterResult) result).getType(),
- is(EditAbuseFilterResult.TYPE_ERROR));
- latch.countDown();
- }
-
- @Override
- public void failure(@NonNull Call<Edit> call, @NonNull
Throwable caught) {
- throw new RuntimeException(caught);
- }
- });
- latch.await();
- }
-
- // Don't crash.
- @Test
- public void testErrorResponse() {
- WikiSite enwiki = WikiSite.forLanguageCode("en");
- PageTitle title = new PageTitle(Namespace.USER.toLegacyString(),
"Mhollo/sandbox", enwiki);
- String badToken = "BAD_TOKEN";
- String wikitext = "foo";
- final TestLatch latch = new TestLatch();
-
- client.request(enwiki, title, DEFAULT_SECTION_ID, wikitext, badToken,
- DEFAULT_SUMMARY, false, null, null, new EditClient.Callback() {
- @Override
- public void success(@NonNull Call<Edit> call, @NonNull
EditResult result) {
- throw new RuntimeException("Token was bad, this should
fail!");
- }
-
- @Override
- public void failure(@NonNull Call<Edit> call, @NonNull
Throwable caught) {
- assertThat(caught.getMessage(), is("Invalid token"));
- latch.countDown();
- }
- });
- latch.await();
- }
-
- private void validateCaptcha(EditResult result) {
- assertThat(result, instanceOf(CaptchaResult.class));
- CaptchaResult captchaResult = (CaptchaResult) result;
- String url = captchaResult.getCaptchaUrl(TEST_WIKI_SITE);
- assertThat(isValidCaptchaUrl(url), is(true));
- }
-
- private boolean isValidCaptchaUrl(String url) {
- return url.startsWith(getNetworkProtocol()
- +
"://test.wikipedia.org/w/index.php?title=Special:Captcha/image");
- }
-
- private String getNetworkProtocol() {
- return app().getWikiSite().scheme();
- }
-
- private WikipediaApp app() {
- return WikipediaApp.getInstance();
- }
-}
diff --git a/app/src/test/java/org/wikipedia/edit/EditClientTest.java
b/app/src/test/java/org/wikipedia/edit/EditClientTest.java
new file mode 100644
index 0000000..4b9003a
--- /dev/null
+++ b/app/src/test/java/org/wikipedia/edit/EditClientTest.java
@@ -0,0 +1,136 @@
+package org.wikipedia.edit;
+
+import android.support.annotation.NonNull;
+
+import com.google.gson.stream.MalformedJsonException;
+
+import org.junit.Test;
+import org.wikipedia.captcha.CaptchaResult;
+import org.wikipedia.dataclient.WikiSite;
+import org.wikipedia.dataclient.mwapi.MwApiException;
+import org.wikipedia.dataclient.retrofit.RetrofitException;
+import org.wikipedia.page.PageTitle;
+import org.wikipedia.test.MockWebServerTest;
+
+import retrofit2.Call;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isA;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+public class EditClientTest extends MockWebServerTest {
+ private EditClient subject = new EditClient();
+
+ @Test @SuppressWarnings("checkstyle:magicnumber")
+ public void testRequestSuccessHasResults() throws Throwable {
+ EditSuccessResult expected = new EditSuccessResult(761350490);
+ enqueueFromFile("edit_result_success.json");
+
+ EditClient.Callback cb = mock(EditClient.Callback.class);
+ Call<Edit> call = request(cb, false);
+
+ server().takeRequest();
+ assertCallbackSuccess(call, cb, expected);
+ }
+
+ @Test public void testRequestResponseAbuseFilter() throws Throwable {
+ EditAbuseFilterResult expected = new
EditAbuseFilterResult("abusefilter-disallowed",
+ "Hit AbuseFilter: Editing user page by anonymous user",
+ "<b>Warning:</b> This action has been automatically identified
as harmful.\nUnconstructive edits will be quickly reverted,\nand egregious or
repeated unconstructive editing will result in your account or IP address being
blocked.\nIf you believe this action to be constructive, you may submit it
again to confirm it.\nA brief description of the abuse rule which your action
matched is: Editing user page by anonymous user");
+ enqueueFromFile("edit_abuse_filter_result.json");
+
+ EditClient.Callback cb = mock(EditClient.Callback.class);
+ Call<Edit> call = request(cb, false);
+
+ server().takeRequest();
+ assertCallbackSuccess(call, cb, expected);
+ }
+
+ @Test public void testRequestResponseSpamBlacklist() throws Throwable {
+ EditSpamBlacklistResult expected = new
EditSpamBlacklistResult("s-e-x");
+ enqueueFromFile("edit_result_spam_blacklist.json");
+
+ EditClient.Callback cb = mock(EditClient.Callback.class);
+ Call<Edit> call = request(cb, false);
+
+ server().takeRequest();
+ assertCallbackSuccess(call, cb, expected);
+ }
+
+ @Test @SuppressWarnings("checkstyle:magicnumber")
+ public void testRequestResponseCaptcha() throws Throwable {
+ CaptchaResult expected = new CaptchaResult("547159230");
+ enqueueFromFile("edit_result_captcha.json");
+
+ EditClient.Callback cb = mock(EditClient.Callback.class);
+ Call<Edit> call = request(cb, false);
+
+ server().takeRequest();
+ assertCallbackSuccess(call, cb, expected);
+ }
+
+ @Test public void testRequestResponseAssertUserFailed() throws Throwable {
+ enqueueFromFile("api_error_assert_user_failed.json");
+
+ EditClient.Callback cb = mock(EditClient.Callback.class);
+ Call<Edit> call = request(cb, true);
+
+ server().takeRequest();
+ assertCallbackFailure(call, cb, UserNotLoggedInException.class);
+ }
+
+ @Test public void testRequestResponseGenericApiError() throws Throwable {
+ enqueueFromFile("api_error.json");
+
+ EditClient.Callback cb = mock(EditClient.Callback.class);
+ Call<Edit> call = request(cb, false);
+
+ server().takeRequest();
+ assertCallbackFailure(call, cb, MwApiException.class);
+ }
+
+ @Test public void testRequestResponse404() throws Throwable {
+ enqueue404();
+
+ EditClient.Callback cb = mock(EditClient.Callback.class);
+ Call<Edit> call = request(cb, false);
+
+ server().takeRequest();
+ assertCallbackFailure(call, cb, RetrofitException.class);
+ }
+
+ @Test public void testRequestResponseMalformed() throws Throwable {
+ server().enqueue("(-(-_(-_-)_-)-)");
+
+ EditClient.Callback cb = mock(EditClient.Callback.class);
+ Call<Edit> call = request(cb, false);
+
+ server().takeRequest();
+ assertCallbackFailure(call, cb, MalformedJsonException.class);
+ }
+
+ private void assertCallbackSuccess(@NonNull Call<Edit> call,
+ @NonNull EditClient.Callback cb,
+ @NonNull EditResult expected) {
+ verify(cb).success(eq(call), eq(expected));
+ //noinspection unchecked
+ verify(cb, never()).failure(any(Call.class), any(Throwable.class));
+ }
+
+ private void assertCallbackFailure(@NonNull Call<Edit> call,
+ @NonNull EditClient.Callback cb,
+ @NonNull Class<? extends Throwable>
throwable) {
+ //noinspection unchecked
+ verify(cb, never()).success(any(Call.class), any(EditResult.class));
+ verify(cb).failure(eq(call), isA(throwable));
+ }
+
+ private Call<Edit> request(@NonNull EditClient.Callback cb, boolean
loggedIn) {
+ PageTitle title = new PageTitle(null, "TEST",
WikiSite.forLanguageCode("test"));
+ return subject.request(service(EditClient.Service.class), title, 0,
"new text", "token",
+ "summary", loggedIn, "captchaId", "captchaSubmission", cb);
+ }
+}
diff --git a/app/src/test/res/raw/api_error_assert_user_failed.json
b/app/src/test/res/raw/api_error_assert_user_failed.json
new file mode 100644
index 0000000..ee90f9b
--- /dev/null
+++ b/app/src/test/res/raw/api_error_assert_user_failed.json
@@ -0,0 +1,8 @@
+{
+ "error": {
+ "code": "assertuserfailed",
+ "info": "Assertion that the user is logged in failed.",
+ "*": "See https://en.wikipedia.org/w/api.php for API usage."
+ },
+ "servedby": "mw1225"
+}
\ No newline at end of file
diff --git a/app/src/test/res/raw/edit_result_captcha.json
b/app/src/test/res/raw/edit_result_captcha.json
new file mode 100644
index 0000000..2ee0043
--- /dev/null
+++ b/app/src/test/res/raw/edit_result_captcha.json
@@ -0,0 +1,11 @@
+{
+ "edit": {
+ "captcha": {
+ "type": "image",
+ "mime": "image/png",
+ "id": "547159230",
+ "url": "/w/index.php?title=Special:Captcha/image&wpCaptchaId=547159230"
+ },
+ "result": "Failure"
+ }
+}
\ No newline at end of file
diff --git a/app/src/test/res/raw/edit_result_spam_blacklist.json
b/app/src/test/res/raw/edit_result_spam_blacklist.json
new file mode 100644
index 0000000..f477fa5
--- /dev/null
+++ b/app/src/test/res/raw/edit_result_spam_blacklist.json
@@ -0,0 +1,6 @@
+{
+ "edit": {
+ "spamblacklist": "s-e-x",
+ "result": "Failure"
+ }
+}
\ No newline at end of file
diff --git a/app/src/test/res/raw/edit_result_success.json
b/app/src/test/res/raw/edit_result_success.json
new file mode 100644
index 0000000..2288416
--- /dev/null
+++ b/app/src/test/res/raw/edit_result_success.json
@@ -0,0 +1,11 @@
+{
+ "edit": {
+ "result": "Success",
+ "pageid": 46498401,
+ "title": "User:Mhollo/sandbox",
+ "contentmodel": "wikitext",
+ "oldrevid": 760523240,
+ "newrevid": 761350490,
+ "newtimestamp": "2017-01-22T13:43:39Z"
+ }
+}
\ No newline at end of file
--
To view, visit https://gerrit.wikimedia.org/r/333499
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I5ab26370acc0e63fbe636275edf1c5ab4d24b3db
Gerrit-PatchSet: 2
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Mholloway <[email protected]>
Gerrit-Reviewer: Brion VIBBER <[email protected]>
Gerrit-Reviewer: Dbrant <[email protected]>
Gerrit-Reviewer: Niedzielski <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits