diff options
Diffstat (limited to 'WordPress/src/androidTest/java/org/wordpress/android/util/HealthCheckTest.java')
-rw-r--r-- | WordPress/src/androidTest/java/org/wordpress/android/util/HealthCheckTest.java | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/WordPress/src/androidTest/java/org/wordpress/android/util/HealthCheckTest.java b/WordPress/src/androidTest/java/org/wordpress/android/util/HealthCheckTest.java new file mode 100644 index 000000000..0e94c079e --- /dev/null +++ b/WordPress/src/androidTest/java/org/wordpress/android/util/HealthCheckTest.java @@ -0,0 +1,227 @@ +package org.wordpress.android.util; + +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.test.InstrumentationTestCase; + +import com.squareup.okhttp.Headers; +import com.squareup.okhttp.mockwebserver.Dispatcher; +import com.squareup.okhttp.mockwebserver.MockResponse; +import com.squareup.okhttp.mockwebserver.MockWebServer; +import com.squareup.okhttp.mockwebserver.RecordedRequest; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.wordpress.android.TestUtils; +import org.wordpress.android.WordPress; +import org.xmlrpc.android.LoggedInputStream; +import org.xmlrpc.android.XMLRPCUtils; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; + +public class HealthCheckTest extends InstrumentationTestCase { + private static final String sAssetPathBase = "health-check/"; + private static final String sServerAddressMagicString = "mockserver"; + private static final String sServerResponsesMagicScheme = "asset:"; + + private void setLocale(String language, String country) { + Locale locale = new Locale(language, country); + Locale.setDefault(locale); + Resources res = getInstrumentation().getTargetContext().getResources(); + Configuration config = res.getConfiguration(); + config.locale = locale; + res.updateConfiguration(config, res.getDisplayMetrics()); + } + + @Override + protected void setUp() { + WordPress.setupVolleyQueue(); + + // set the app locale to english since the tests only support English for now + setLocale("en", "US"); + } + + @Override + protected void tearDown() { + } + + private static String stringFromAsset(Context context, String assetFilename) throws IOException { + LoggedInputStream mLoggedInputStream = new LoggedInputStream(context.getAssets().open(assetFilename)); + return TestUtils.convertStreamToString(mLoggedInputStream); + } + + private static JSONObject jsonFromAsset(Context context, String assetFilename) throws IOException, JSONException { + return new JSONObject(stringFromAsset(context, assetFilename)); + } + + public void testHealthCheckXplat() throws JSONException, IOException { + JSONArray testCases = jsonFromAsset(getInstrumentation().getContext(), sAssetPathBase + + "health-check-xplat-testcases.json").getJSONArray("testcases"); + + for (int i = 0; i < testCases.length(); i++) { + final JSONObject testCase = testCases.getJSONObject(i); + final String testCaseComment = testCase.getString("comment"); + + final JSONObject testSetup = testCase.getJSONObject("setup"); + final String realm = testCase.getString("realm"); + + switch (realm) { + case "URL_CANONICALIZATION": + runUrlCanonicalization(testCaseComment, testSetup); + break; + case "XMLPRC_DISCOVERY": + runXmlrpcDiscovery(testCaseComment, testSetup); + break; + default: + // fail the testsuite + assertTrue("health-check realm " + realm + " is not supported!", false); + break; + } + } + } + + private void runUrlCanonicalization(String testCaseComment, JSONObject testSetup) throws JSONException { + final JSONObject input = testSetup.getJSONObject("input"); + + final String inputUrl = input.isNull("siteUrl") ? null : input.getString("siteUrl"); + + final JSONObject output = testSetup.getJSONObject("output"); + + final String outputUrl = output.optString("siteUrl", null); + final JSONObject error = output.optJSONObject("error"); + + String canonicalizedUrl = null; + try { + canonicalizedUrl = XMLRPCUtils.sanitizeSiteUrl(inputUrl, true); + + // if we reached this point, it means that no error occurred + assertNull(testCaseMessage("Testcase defines an error but no error occurred!", testCaseComment), error); + } catch (XMLRPCUtils.XMLRPCUtilsException hce) { + assertNotNull(testCaseMessage("Error occurred but testcase does not define an error!", testCaseComment), + error); + + assertEquals(testCaseMessage("Error message does not match the defined one!", testCaseComment), error + .getString("message"), getInstrumentation().getTargetContext().getString(hce.errorMsgId)); + } + + assertEquals(testCaseMessage("Canonicalized URL does not match the defined one!", testCaseComment), + outputUrl, canonicalizedUrl); + } + + private void runXmlrpcDiscovery(String testCaseComment, JSONObject testSetup) throws JSONException, IOException { + final MockWebServer server = new MockWebServer(); + + testSetup = new JSONObject(replaceServerMagicName(server, testSetup.toString())); + + final JSONObject input = testSetup.getJSONObject("input"); + + setupMockHttpServer(server, input); + + final String inputUrl = input.isNull("siteUrl") ? server.url("").toString() : input.getString("siteUrl"); + + final JSONObject output = testSetup.getJSONObject("output"); + + final String outputUrl = output.optString("xmlrpcEndpoint", null); + final JSONObject error = output.optJSONObject("error"); + + String xmlrpcUrl = null; + try { + xmlrpcUrl = XMLRPCUtils.verifyOrDiscoverXmlRpcUrl(inputUrl, input.optString("username", null), input + .optString("username", null)); + + // if we reached this point, it means that no error occurred + assertNull(testCaseMessage("Testcase defines an error but no error occurred!", testCaseComment), error); + } catch (XMLRPCUtils.XMLRPCUtilsException hce) { + assertNotNull(testCaseMessage("Error occurred but testcase does not define an error!", testCaseComment), + error); + + assertEquals(testCaseMessage("Error message does not match the defined one!", testCaseComment), error + .getString("message"), getInstrumentation().getTargetContext().getString(hce.errorMsgId)); + } + + assertEquals(testCaseMessage("XMLRPC URL does not match the defined one!", testCaseComment), outputUrl, + xmlrpcUrl); + + server.shutdown(); + } + + private MockWebServer setupMockHttpServer(MockWebServer server, JSONObject requestResponsesJson) throws + JSONException, IOException { + final Map<RecordedRequest, MockResponse> mockRequestResponses = new HashMap<>(); + + final JSONArray serverMock = requestResponsesJson.getJSONArray("serverMock"); + for (int i = 0; i < serverMock.length(); i++) { + final JSONObject reqRespJson = serverMock.getJSONObject(i); + + final JSONObject reqJson = reqRespJson.getJSONObject("request"); + Headers reqHeaders = json2Headers(reqJson.optJSONObject("headers")); + + RecordedRequest recordedRequest = new RecordedRequest(reqJson.getString("method") + " " + reqJson + .getString("path") + " HTTP/1.1", reqHeaders, null, 0, null, 0, null); + + final JSONObject respJson = reqRespJson.getJSONObject("response"); + Headers respHeaders = json2Headers(respJson.optJSONObject("headers")); + + String body = respJson.optString("body"); + if (body.startsWith(sServerResponsesMagicScheme)) { + body = stringFromAsset(getInstrumentation().getContext(), sAssetPathBase + body.substring + (sServerResponsesMagicScheme.length())); + } + + body = replaceServerMagicName(server, body); + + final MockResponse resp = new MockResponse() + .setResponseCode(respJson.getInt("statusCode")) + .setHeaders(respHeaders) + .setBody(body); + + mockRequestResponses.put(recordedRequest, resp); + } + + server.setDispatcher(new Dispatcher() { + @Override + public MockResponse dispatch(RecordedRequest request) throws InterruptedException { + + for (Map.Entry<RecordedRequest, MockResponse> reqResp : mockRequestResponses.entrySet()) { + final RecordedRequest mockRequest = reqResp.getKey(); + if (mockRequest.getRequestLine().equals(request.getRequestLine())) { + return reqResp.getValue(); + } + } + return new MockResponse().setResponseCode(404).setBody(""); + } + }); + + return server; + } + + private String replaceServerMagicName(MockWebServer server, String str) { + return str.replaceAll(sServerAddressMagicString, server.getHostName() + ":" + server.getPort()); + + } + + private Headers json2Headers(JSONObject headersJson) throws JSONException { + if (headersJson != null) { + Headers.Builder headBuilder = new Headers.Builder(); + Iterator<String> headerKeys = headersJson.keys(); + while (headerKeys.hasNext()) { + final String headerName = headerKeys.next(); + headBuilder.add(headerName, headersJson.getString(headerName)); + } + + return headBuilder.build(); + } + + return new Headers.Builder().build(); + } + + private String testCaseMessage(String message, String testCaseComment) { + return message + " (on testCase: '" + testCaseComment + "')"; + } +} |