package com.google.tripmeout.serialization;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import com.google.tripmeout.frontend.TripModel;
import com.google.tripmeout.frontend.serialization.GsonTripModelTypeAdapter;
import com.google.tripmeout.serialization.testdata.TripTestDataAccessUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class GsonTripModelTypeAdapterTest {
  private Gson gson;

  private TripModel baseTrip = TripModel.builder().setUserId("idk").setName("New Jersey").build();

  @Before
  public void setup() {
    this.gson = new GsonBuilder()
                    .registerTypeHierarchyAdapter(TripModel.class, new GsonTripModelTypeAdapter())
                    .create();
  }

  @Test
  public void deserialize_wellFormed() throws Exception {
    TripModel trip =
        gson.fromJson(TripTestDataAccessUtil.getTripModelWellFormed(), TripModel.class);

    TripModel expected = baseTrip.toBuilder()
                             .setId("a")
                             .setLocationLat(12.66)
                             .setLocationLong(34.78)
                             .build();

    assertThat(trip).isEqualTo(expected);
  }

  @Test
  public void deserialize_unknownField_throwsJsonParseException() throws Exception {
    assertThrows(JsonParseException.class,
        ()
            -> gson.fromJson(

                TripTestDataAccessUtil.getTripModelUnknownField(), TripModel.class));
  }

  @Test
  public void deserialize_noId_throwsJsonParseException() throws Exception {
    TripModel trip =
        gson.fromJson(TripTestDataAccessUtil.getTripModelWithoutId(), TripModel.class);

    TripModel expected = baseTrip.toBuilder().setLocationLat(12.66).setLocationLong(34.78).build();

    assertThat(trip).isEqualTo(expected);
  }

  @Test
  public void deserialize_noName_returnsTripModelWithNullName() throws Exception {
    assertThrows(JsonParseException.class,
        ()
            -> gson.fromJson(

                TripTestDataAccessUtil.getTripModelWithoutName(), TripModel.class));
  }

  @Test
  public void deserialize_noUserId_throwsJsonParseException() throws Exception {
    assertThrows(JsonParseException.class,
        ()
            -> gson.fromJson(

                TripTestDataAccessUtil.getTripModelWithoutUserId(), TripModel.class));
  }

  @Test
  public void deserialize_noLatitude_throwsJsonParseException() throws Exception {
    TripModel trip =
        gson.fromJson(TripTestDataAccessUtil.getTripModelWithoutLatitude(), TripModel.class);

    TripModel expected = baseTrip.toBuilder().setId("a").setLocationLong(34.78).build();

    assertThat(trip).isEqualTo(expected);
  }

  @Test
  public void deserialize_noLongitude_throwsJsonParseException() throws Exception {
    TripModel trip =
        gson.fromJson(TripTestDataAccessUtil.getTripModelWithoutLongitude(), TripModel.class);

    TripModel expected = baseTrip.toBuilder().setId("a").setLocationLat(12.66).build();

    assertThat(trip).isEqualTo(expected);
  }

  @Test
  public void roundTrip_objectsAreEqual() throws Exception {
    TripModel trip = TripModel.builder()
                         .setId("id")
                         .setName("name")
                         .setUserId("userId")
                         .setLocationLat(23.9)
                         .setLocationLong(24.2)
                         .build();
    assertThat(gson.fromJson(gson.toJson(trip), TripModel.class)).isEqualTo(trip);
  }
}

@@ -707,25 +707,8 @@
 r().
-setUserId(%22idk%22).
 setN
@@ -1202,16 +1202,63 @@
 Id(%22a%22)%0A
+                             .setUserId(%22idk%22)%0A
         
@@ -1811,32 +1811,24 @@
 Model trip =
-%0A       
  gson.fromJs
@@ -1913,32 +1913,40 @@
 Model expected =
+%0A       
  baseTrip.toBuil
@@ -1951,16 +1951,33 @@
 ilder().
+setUserId(%22idk%22).
 setLocat
@@ -2433,72 +2433,32 @@
     
-assertThrows(JsonParseException.class,%0A        ()%0A  
+TripModel trip =%0A
        
-   -%3E
  gso
@@ -2468,34 +2468,16 @@
 romJson(
-%0A%0A                
 TripTest
@@ -2528,32 +2528,194 @@
 TripModel.class)
+;%0A%0A    TripModel expected =%0A        baseTrip.toBuilder().setId(%22a%22).setLocationLat(12.66).setLocationLong(34.78).build();%0A%0A    assertThat(trip).isEqualTo(expected
 );%0A  %7D%0A%0A  @Test%0A
@@ -2929,32 +2929,40 @@
 Model expected =
+%0A       
  baseTrip.toBuil
@@ -2970,32 +2970,49 @@
 er().setId(%22a%22).
+setUserId(%22idk%22).
 setLocationLong(
@@ -3300,32 +3300,40 @@
 Model expected =
+%0A       
  baseTrip.toBuil
@@ -3341,32 +3341,49 @@
 er().setId(%22a%22).
+setUserId(%22idk%22).
 setLocationLat(1

fix testing