package org.wikipedia.csrf; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.StringRes; import org.junit.Before; import org.junit.Test; import org.wikipedia.WikipediaApp; import org.wikipedia.dataclient.WikiSite; import org.wikipedia.login.LoginClient; import org.wikipedia.login.LoginResult; import org.wikipedia.login.User; import org.wikipedia.testlib.TestLatch; import static android.support.test.InstrumentationRegistry.getInstrumentation; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import static org.wikipedia.test.TestUtil.runOnMainSync; public class CsrfTokenClientTest { private static final WikiSite TEST_WIKI = WikiSite.forLanguageCode("test"); private static final String USERNAME = getString(org.wikipedia.test.R.string.test_username); private static final String PASSWORD = getString(org.wikipedia.test.R.string.test_password); @Before public void setUp() { User.disableStorage(); // don't change the app login from this test } @Test public void testCsrfTokenForAnon() { WikipediaApp.getInstance().getCookieManager().clearAllCookies(); final TestLatch completionLatch = new TestLatch(); runOnMainSync(new Runnable() { @Override public void run() { getCsrfToken(completionLatch, false); } }); completionLatch.await(); } @Test public void testCsrfTokenForLogin() { WikipediaApp.getInstance().getCookieManager().clearAllCookies(); final TestLatch completionLatch = new TestLatch(); runOnMainSync(new Runnable() { @Override public void run() { new LoginClient().request(TEST_WIKI, USERNAME, PASSWORD, new LoginClient.LoginCallback() { @Override public void success(@NonNull LoginResult result) { assertThat(result.getStatus(), equalTo("PASS")); getCsrfToken(completionLatch, true); } @Override public void twoFactorPrompt(@NonNull Throwable throwble, @Nullable String token) { fail("Two-factor prompt not expected here"); } @Override public void error(@NonNull Throwable caught) { assertThat("login failed!", false); } }); } }); completionLatch.await(); } @Test public void testCsrfTokenLoginError() { WikipediaApp.getInstance().getCookieManager().clearAllCookies(); final TestLatch completionLatch = new TestLatch(); runOnMainSync(new Runnable() { @Override public void run() { new LoginClient().request(TEST_WIKI, USERNAME, "foo", new LoginClient.LoginCallback() { @Override public void success(@NonNull LoginResult result) { assertThat("login succeeded, when it shouldn't have!", false); } @Override public void twoFactorPrompt(@NonNull Throwable throwble, @Nullable String token) { fail("Two-factor prompt not expected here"); } @Override public void error(@NonNull Throwable caught) { assertThat(caught, is(instanceOf(LoginClient.LoginFailedException.class))); completionLatch.countDown(); } }); } }); completionLatch.await(); } private void getCsrfToken(final TestLatch completionLatch, final boolean loggedIn) { new CsrfTokenClient(TEST_WIKI, TEST_WIKI).request(new CsrfTokenClient.Callback() { @Override public void success(@NonNull String token) { assertThat(token.equals(CsrfTokenClient.ANON_TOKEN), is(!loggedIn)); completionLatch.countDown(); } @Override public void failure(@NonNull Throwable caught) { throw new RuntimeException(caught); } @Override public void twoFactorPrompt() { throw new RuntimeException("TODO: test 2FA login."); } }); } private static String getString(@StringRes int id) { return getInstrumentation().getContext().getString(id); } }