michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: package org.mozilla.gecko.background.healthreport.upload; michael@0: michael@0: import java.util.Collection; michael@0: michael@0: import org.mozilla.gecko.background.bagheera.BagheeraRequestDelegate; michael@0: import org.mozilla.gecko.background.healthreport.Environment; michael@0: import org.mozilla.gecko.background.healthreport.HealthReportStorage; michael@0: import org.mozilla.gecko.background.healthreport.HealthReportDatabaseStorage; michael@0: import org.mozilla.gecko.background.healthreport.MockHealthReportDatabaseStorage.PrepopulatedMockHealthReportDatabaseStorage; michael@0: import org.mozilla.gecko.background.healthreport.MockProfileInformationCache; michael@0: import org.mozilla.gecko.background.healthreport.ProfileInformationCache; michael@0: import org.mozilla.gecko.background.healthreport.upload.AndroidSubmissionClient; michael@0: import org.mozilla.gecko.background.healthreport.upload.AndroidSubmissionClient.SubmissionsFieldName; michael@0: import org.mozilla.gecko.background.helpers.FakeProfileTestCase; michael@0: import org.mozilla.gecko.background.testhelpers.StubDelegate; michael@0: michael@0: import android.content.ContentProviderClient; michael@0: import android.content.Context; michael@0: import android.content.SharedPreferences; michael@0: import org.json.JSONException; michael@0: import org.json.JSONObject; michael@0: michael@0: public class TestAndroidSubmissionClient extends FakeProfileTestCase { michael@0: public static class MockAndroidSubmissionClient extends AndroidSubmissionClient { michael@0: protected final PrepopulatedMockHealthReportDatabaseStorage storage; michael@0: michael@0: public SubmissionState submissionState = SubmissionState.SUCCESS; michael@0: public DocumentStatus documentStatus = DocumentStatus.VALID; michael@0: public boolean hasUploadBeenRequested = true; michael@0: michael@0: public MockAndroidSubmissionClient(final Context context, final SharedPreferences sharedPrefs, michael@0: final PrepopulatedMockHealthReportDatabaseStorage storage) { michael@0: super(context, sharedPrefs, "profilePath"); michael@0: this.storage = storage; michael@0: } michael@0: michael@0: @Override michael@0: public HealthReportDatabaseStorage getStorage(final ContentProviderClient client) { michael@0: return storage; michael@0: } michael@0: michael@0: @Override michael@0: public boolean hasUploadBeenRequested() { michael@0: return hasUploadBeenRequested; michael@0: } michael@0: michael@0: @Override michael@0: protected void uploadPayload(String id, String payload, Collection oldIds, michael@0: BagheeraRequestDelegate delegate) { michael@0: switch (submissionState) { michael@0: case SUCCESS: michael@0: delegate.handleSuccess(0, null, id, null); michael@0: break; michael@0: michael@0: case FAILURE: michael@0: delegate.handleFailure(0, null, null); michael@0: break; michael@0: michael@0: case ERROR: michael@0: delegate.handleError(null); michael@0: break; michael@0: michael@0: default: michael@0: throw new IllegalStateException("Unknown submissionState, " + submissionState); michael@0: } michael@0: } michael@0: michael@0: @Override michael@0: public SubmissionsTracker getSubmissionsTracker(final HealthReportStorage storage, michael@0: final long localTime, final boolean hasUploadBeenRequested) { michael@0: return new MockSubmissionsTracker(storage, localTime, hasUploadBeenRequested); michael@0: } michael@0: michael@0: public class MockSubmissionsTracker extends SubmissionsTracker { michael@0: public MockSubmissionsTracker (final HealthReportStorage storage, final long localTime, michael@0: final boolean hasUploadBeenRequested) { michael@0: super(storage, localTime, hasUploadBeenRequested); michael@0: } michael@0: michael@0: @Override michael@0: public ProfileInformationCache getProfileInformationCache() { michael@0: final MockProfileInformationCache cache = new MockProfileInformationCache(profilePath); michael@0: cache.setInitialized(true); // Will throw errors otherwise. michael@0: return cache; michael@0: } michael@0: michael@0: @Override michael@0: public TrackingGenerator getGenerator() { michael@0: return new MockTrackingGenerator(); michael@0: } michael@0: michael@0: public class MockTrackingGenerator extends TrackingGenerator { michael@0: @Override michael@0: public JSONObject generateDocument(final long localTime, final long last, michael@0: final String profilePath) throws JSONException { michael@0: switch (documentStatus) { michael@0: case VALID: michael@0: return new JSONObject(); // Beyond == null, we don't check for valid FHR documents. michael@0: michael@0: case NULL: michael@0: // The overridden method should return null since we return a null has for the current michael@0: // Environment. michael@0: return super.generateDocument(localTime, last, profilePath); michael@0: michael@0: case EXCEPTION: michael@0: throw new IllegalStateException("Intended Exception"); michael@0: michael@0: default: michael@0: throw new IllegalStateException("Unintended Exception"); michael@0: } michael@0: } michael@0: michael@0: // Used in super.generateDocument, where a null document is returned if getHash returns null michael@0: @Override michael@0: public Environment getCurrentEnvironment() { michael@0: return new Environment() { michael@0: @Override michael@0: public int register() { michael@0: return 0; michael@0: } michael@0: michael@0: @Override michael@0: public String getHash() { michael@0: return null; michael@0: } michael@0: }; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: public final SubmissionsFieldName[] SUBMISSIONS_STATUS_FIELD_NAMES = new SubmissionsFieldName[] { michael@0: SubmissionsFieldName.SUCCESS, michael@0: SubmissionsFieldName.CLIENT_FAILURE, michael@0: SubmissionsFieldName.TRANSPORT_FAILURE, michael@0: SubmissionsFieldName.SERVER_FAILURE michael@0: }; michael@0: michael@0: public static enum SubmissionState { SUCCESS, FAILURE, ERROR } michael@0: public static enum DocumentStatus { VALID, NULL, EXCEPTION }; michael@0: michael@0: public StubDelegate stubDelegate; michael@0: public PrepopulatedMockHealthReportDatabaseStorage storage; michael@0: public MockAndroidSubmissionClient client; michael@0: michael@0: public void setUp() throws Exception { michael@0: super.setUp(); michael@0: stubDelegate = new StubDelegate(); michael@0: storage = new PrepopulatedMockHealthReportDatabaseStorage(context, fakeProfileDirectory); michael@0: client = new MockAndroidSubmissionClient(context, getSharedPreferences(), storage); michael@0: } michael@0: michael@0: public int getSubmissionsCount(final SubmissionsFieldName fieldName) { michael@0: final int id = fieldName.getID(storage); michael@0: return storage.getIntFromQuery("SELECT COUNT(*) FROM events WHERE field = " + id, null); michael@0: } michael@0: michael@0: public void testUploadSubmissionsFirstAttemptCount() throws Exception { michael@0: client.hasUploadBeenRequested = false; michael@0: client.upload(storage.now, null, null, stubDelegate); michael@0: assertEquals(1, getSubmissionsCount(SubmissionsFieldName.FIRST_ATTEMPT)); michael@0: assertEquals(0, getSubmissionsCount(SubmissionsFieldName.CONTINUATION_ATTEMPT)); michael@0: } michael@0: michael@0: public void testUploadSubmissionsContinuationAttemptCount() throws Exception { michael@0: client.upload(storage.now, null, null, stubDelegate); michael@0: assertEquals(0, getSubmissionsCount(SubmissionsFieldName.FIRST_ATTEMPT)); michael@0: assertEquals(1, getSubmissionsCount(SubmissionsFieldName.CONTINUATION_ATTEMPT)); michael@0: } michael@0: michael@0: /** michael@0: * Asserts that the given field name has a count of 1 and all other status (success and failures) michael@0: * have a count of 0. michael@0: */ michael@0: public void assertStatusCount(final SubmissionsFieldName fieldName) { michael@0: for (SubmissionsFieldName name : SUBMISSIONS_STATUS_FIELD_NAMES) { michael@0: if (name == fieldName) { michael@0: assertEquals(1, getSubmissionsCount(name)); michael@0: } else { michael@0: assertEquals(0, getSubmissionsCount(name)); michael@0: } michael@0: } michael@0: } michael@0: michael@0: public void testUploadSubmissionsSuccessCount() throws Exception { michael@0: client.upload(storage.now, null, null, stubDelegate); michael@0: assertStatusCount(SubmissionsFieldName.SUCCESS); michael@0: } michael@0: michael@0: public void testUploadNullDocumentSubmissionsFailureCount() throws Exception { michael@0: client.documentStatus = DocumentStatus.NULL; michael@0: client.upload(storage.now, null, null, stubDelegate); michael@0: assertStatusCount(SubmissionsFieldName.CLIENT_FAILURE); michael@0: } michael@0: michael@0: public void testUploadDocumentGenerationExceptionSubmissionsFailureCount() throws Exception { michael@0: client.documentStatus = DocumentStatus.EXCEPTION; michael@0: client.upload(storage.now, null, null, stubDelegate); michael@0: assertStatusCount(SubmissionsFieldName.CLIENT_FAILURE); michael@0: } michael@0: }