io.morea.handy.android.EventReporterTest.java Source code

Java tutorial

Introduction

Here is the source code for io.morea.handy.android.EventReporterTest.java

Source

/*
 * Copyright 2015 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.morea.handy.android;

import android.app.Activity;
import android.app.Application;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.squareup.okhttp.Credentials;
import io.morea.handy.android.testutil.SynchronousExecutorService;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonParser;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import org.assertj.core.data.MapEntry;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static io.morea.handy.android.EventDatabaseOpenHelper.Metadata.Events;
import static org.assertj.core.api.Assertions.assertThat;

/**
 * @author Andreas Ahlenstorf
 */
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class EventReporterTest {

    private UUID probeId;
    private UUID accessKey;
    private Application application;
    private MockWebServer server;
    private Gson gson;

    @Before
    public void setUp() throws Exception {
        probeId = UUID.fromString("b8a6f9ce-c69f-4945-ab1f-306edf50903b");
        accessKey = UUID.fromString("255ab196-e6de-4a93-be3a-da1b7d9e6840");

        application = Robolectric.setupActivity(Activity.class).getApplication();
        server = new MockWebServer();

        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(Date.class, new DateSerializer());
        gson = gsonBuilder.create();
    }

    @Test
    public void eventLoggedAndSavedToDatabase() throws Exception {
        EventReporter reporter = new EventReporter(application,
                new EventReporterConfiguration.Builder("http://localhost/").build(),
                new SynchronousExecutorService());

        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Zurich"));
        calendar.set(2015, Calendar.JUNE, 9, 13, 44, 12);

        Event e = new Event.Builder(application, Collections.singletonMap("foo", "bar"))
                .dateRecorded(calendar.getTime()).position(new Position(47.5574472, 8.5788336)).build();

        reporter.log(e);

        EventDatabaseOpenHelper helper = new EventDatabaseOpenHelper(this.application);
        SQLiteDatabase db = helper.getWritableDatabase();
        Cursor c = db.query(Events.TABLE_NAME, Events.orderedColumns(), null, null, null, null, null);
        try {
            List<Event> data = readCursor(c);

            assertThat(data).hasSize(1);

            Event actual = data.get(0);

            assertThat(actual.getIdentifier()).isEqualTo(e.getIdentifier());
            assertThat(actual.getDateRecorded()).isEqualTo(e.getDateRecorded());
            assertThat(actual.getPosition().getLatitude()).isEqualTo(47.5574472);
            assertThat(actual.getPosition().getLongitude()).isEqualTo(8.5788336);
            assertThat((Map<String, String>) actual.getData()).contains(MapEntry.entry("foo", "bar"));
            assertThat(actual.getContext().getAndroidVersion()).contains("unknown");
            assertThat(actual.getContext().getPhoneManufacturer()).contains("unknown");
            assertThat(actual.getContext().getPhoneModel()).contains("unknown");
        } finally {
            Util.closeQuietly(c);
            Util.closeQuietly(db);
        }
    }

    @Test
    public void eventsSentToRemoteServer() throws Exception {
        server.enqueue(new MockResponse().setResponseCode(401));
        server.enqueue(new MockResponse().setResponseCode(201));
        server.enqueue(new MockResponse().setResponseCode(401));
        server.enqueue(new MockResponse().setResponseCode(500));
        server.enqueue(new MockResponse().setResponseCode(401));
        server.enqueue(new MockResponse().setResponseCode(201));
        server.start();

        EventReporterConfiguration configuration = new EventReporterConfiguration.Builder(server.getUrl("/"))
                .probeId(probeId.toString()).accessKey(accessKey.toString()).syncBatchSize(2).build();

        EventReporter reporter = new EventReporter(application, configuration, new SynchronousExecutorService());

        reporter.log(fiveEvents());
        reporter.send();

        EventDatabaseOpenHelper helper = new EventDatabaseOpenHelper(this.application);
        SQLiteDatabase db = helper.getWritableDatabase();
        Cursor cursor = db.query(Events.TABLE_NAME, Events.orderedColumns(), null, null, null, null,
                Events.IDENTIFIER);

        List<Event> remainingEvents = readCursor(cursor);
        assertThat(remainingEvents).hasSize(2);
        assertThat(remainingEvents.get(0).getIdentifier())
                .isEqualTo(UUID.fromString("4c654f6e-0373-43cf-bd52-31e20067c397"));
        assertThat(remainingEvents.get(1).getIdentifier())
                .isEqualTo(UUID.fromString("74af8761-11ab-47d9-b787-a41c437b7bf1"));

        assertThat(server.getRequestCount()).isEqualTo(6);

        server.takeRequest(1, TimeUnit.SECONDS);
        RecordedRequest request2 = server.takeRequest(1, TimeUnit.SECONDS);
        server.takeRequest(1, TimeUnit.SECONDS);
        RecordedRequest request4 = server.takeRequest(1, TimeUnit.SECONDS);
        server.takeRequest(1, TimeUnit.SECONDS);
        RecordedRequest request6 = server.takeRequest(1, TimeUnit.SECONDS);

        String credentials = Credentials.basic(probeId.toString(), accessKey.toString());

        assertThat(request2.getHeader("Authorization")).isEqualTo(credentials);
        assertThat(fromJson(request2.getBody().readUtf8())).hasSize(2);
        assertThat(request4.getHeader("Authorization")).isEqualTo(credentials);
        assertThat(fromJson(request4.getBody().readUtf8())).hasSize(2);
        assertThat(request6.getHeader("Authorization")).isEqualTo(credentials);
        assertThat(fromJson(request6.getBody().readUtf8())).hasSize(1);

        Util.closeQuietly(cursor);
        server.shutdown();
    }

    private static List<Event> readCursor(Cursor cursor) {
        List<Event> data = new ArrayList<>(cursor.getCount());

        while (cursor.moveToNext()) {
            data.add(Event.fromCursor(cursor));
        }

        return data;
    }

    private List<Event> fromJson(String json) {
        List<Event> events = new ArrayList<>();
        JsonParser parser = new JsonParser();

        JsonArray array = parser.parse(json).getAsJsonArray();
        for (int i = 0; i < array.size(); i++) {
            events.add(gson.fromJson(array.get(i), Event.class));
        }

        return events;
    }

    private List<Event> fiveEvents() {
        List<Event> events = new ArrayList<>();

        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Zurich"));
        calendar.set(2015, Calendar.JUNE, 9, 13, 44, 12);

        events.add(new Event.Builder(application, Collections.singletonMap("foo", "bar"))
                .id(UUID.fromString("28c61b26-6f24-43d9-9603-5301a21f5052")).dateRecorded(calendar.getTime())
                .position(new Position(47.5574472, 8.5788336)).build());
        events.add(new Event.Builder(application, Collections.singletonMap("count", 3))
                .id(UUID.fromString("547cfa8a-a869-4650-8e2d-bb576d6fcad5")).dateRecorded(calendar.getTime())
                .position(new Position(47.5574472, 8.5788336)).build());

        calendar.set(Calendar.SECOND, 29);

        events.add(new Event.Builder(application, Collections.singletonMap("fizz", "buzz"))
                .id(UUID.fromString("74af8761-11ab-47d9-b787-a41c437b7bf1")).dateRecorded(calendar.getTime())
                .build());

        calendar.set(Calendar.SECOND, 54);

        events.add(new Event.Builder(application, Collections.singletonMap("zigg", "zagg"))
                .id(UUID.fromString("4c654f6e-0373-43cf-bd52-31e20067c397")).dateRecorded(calendar.getTime())
                .position(new Position(47.557885, 8.579300)).build());
        events.add(new Event.Builder(application, Collections.singletonMap("count", 4))
                .id(UUID.fromString("67590b18-1b55-49bf-83e0-3f27f4da9968")).dateRecorded(calendar.getTime())
                .position(new Position(47.557885, 8.579300)).build());

        return events;
    }
}