/**
 * Copyright 2016-2017 Sixt GmbH & Co. Autovermietung KG
 * 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 com.sixt.service.framework.protobuf;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.protobuf.Message;
import org.junit.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

//TODO: enhance this test to cover and verify all of the types for
//      serialization / deserialization

public class ProtobufUtilTest {

    @Test
    public void fromJson_SetRepeated_YieldsTheSameValues() throws Exception {
        // given
        FrameworkTest.Foobar.Builder builder = FrameworkTest.Foobar.newBuilder();
        JsonParser parser = new JsonParser();
        JsonObject json = (JsonObject) parser.parse("{\"blah\":[\"a\",\"b\",\"c\"]}");

        // when
        FrameworkTest.Foobar message = (FrameworkTest.Foobar) ProtobufUtil.fromJson(builder, json);

        // then
        List<String> blahArray = message.getBlahList();
        assertThat(blahArray).hasSize(3);
        assertThat(blahArray).containsOnly("a", "b", "c");
    }

    @Test
    public void testNullSubmessage_YieldsDefaultInstance() throws Exception {
        FrameworkTest.SerializationTest.Builder builder = FrameworkTest.SerializationTest.newBuilder();
        String jsonInput = "{\"id\":\"a\",\"id2\":\"b\",\"id4\":\"c\",\"sub_message\":null}";
        JsonObject json = (JsonObject) new JsonParser().parse(jsonInput);
        FrameworkTest.SerializationTest message = (FrameworkTest.SerializationTest) ProtobufUtil.fromJson(builder, json);

        assertThat(message.getSubMessage()).isEqualTo(FrameworkTest.SerializationSubMessage.getDefaultInstance());
    }

    @Test
    public void testMessageWithEnums() {
        FrameworkTest.MessageWithEnum message = FrameworkTest.MessageWithEnum.newBuilder().
                setError(FrameworkTest.Error.INVALID_VEHICLE_ID).build();
        JsonObject messageStr = ProtobufUtil.protobufToJson(message);
        assertThat(messageStr.get("error").getAsString()).isEqualTo("INVALID_VEHICLE_ID");
    }

    @Test
    public void protobufToJson_NullMessage_YieldsToEmptyJson() {
        // given

        // when
        JsonObject result = ProtobufUtil.protobufToJson(null);

        // then
        assertThat(result).isNotNull();
        assertThat(result).isEqualTo(new JsonObject());
    }

    @Test
    public void protobufToJson_SimpleMessage_YieldsSuccess() {
        // given
        FrameworkTest.SerializationTest message = FrameworkTest.SerializationTest.newBuilder()
                .setId("id")
                .setId2("id2")
                .build();

        // when
        JsonObject result = ProtobufUtil.protobufToJson(message);

        // then
        assertThat(result).isNotNull();
        assertThat(result.getAsJsonPrimitive("id").getAsString()).isEqualTo("id");
        assertThat(result.getAsJsonPrimitive("id2").getAsString()).isEqualTo("id2");
    }

    @Test
    public void protobufToJson_RepeatedFields_YieldsSuccess() {
        // given
        FrameworkTest.SerializationTest message = FrameworkTest.SerializationTest.newBuilder()
                .setSubMessage(
                        FrameworkTest.SerializationSubMessage.newBuilder()
                                .setId("TheId")
                                .build()
                ).setId4("The fourth id")
                .build();

        // when
        JsonObject result = ProtobufUtil.protobufToJson(message);

        // then
        assertThat(result).isNotNull();
        assertThat(result.get("sub_message").getAsJsonObject().get("id").getAsString()).isEqualTo("TheId");
        assertThat(result.getAsJsonPrimitive("id4").getAsString()).isEqualTo("The fourth id");
    }

    @Test
    public void jsonToProtobuf_SimpleJsonToProtobufGeneralMessage_YieldsSuccess() {
        // given
        final String json = "{\"id\":\"theId\"}";

        // when
        Message message = ProtobufUtil.jsonToProtobuf(json, FrameworkTest.SerializationTest.class);

        // then
        assertThat(message).isInstanceOf(FrameworkTest.SerializationTest.class);
        assertThat(((FrameworkTest.SerializationTest) message).getId()).isEqualTo("theId");
    }

    @Test
    public void jsonToProtobuf_SimpleJsonToProtobufSpecificMessage_YieldsSuccess() {
        // given
        final String json = "{\"id\":\"theId\"}";

        // when
        FrameworkTest.SerializationTest message = ProtobufUtil.jsonToProtobuf(json, FrameworkTest.SerializationTest.class);

        // then
        assertThat(message.getId()).isEqualTo("theId");
    }

    @Test
    public void jsonToProtobuf_SimpleJsonWithUnknownField_MessageEmpty() {
        // given
        final String json = "{\"fahrzeug\":\"auto\"}"; // key 'fahrzeug' does not exist in protobuf message FrameworkTest.SerializationTest.

        // when
        FrameworkTest.SerializationTest message = ProtobufUtil.jsonToProtobuf(json, FrameworkTest.SerializationTest.class);

        // then
        assertThat(message.getId()).isEmpty();
    }

}

@@ -5600,10 +5600,464 @@
 %0A    %7D%0A%0A
+    @Test%0A    public void jsonToProtobuf_SimpleJsonWithEmptyUnknownField_MessageEmpty() %7B%0A        // given%0A        final String json = %22%7B%5C%22fahrzeug%5C%22: %7B%7D%7D%22; // key 'fahrzeug' does not exist in protobuf message FrameworkTest.SerializationTest.%0A%0A        // when%0A        FrameworkTest.SerializationTest message = ProtobufUtil.jsonToProtobuf(json, FrameworkTest.SerializationTest.class);%0A%0A        // then%0A        assertThat(message.getId()).isEmpty();%0A    %7D%0A
 %7D%0A

Add test to parse json with empty unknown field