/*
 * Copyright (C) 2016 Orange
 *
 * 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.orange.ngsi2.server;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.web.context.WebApplicationContext;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;

/**
 * Tests for the NGSI v2 base controller.
 * This class uses the two FakeNgsi2ControllerHelper and NotImplementedNgsi2Controller classes
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestConfiguration.class)
@WebAppConfiguration
public class Ngsi2BaseControllerTest {

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Autowired
    private MappingJackson2HttpMessageConverter jsonV2Converter;

    @Before
    public void setup() throws Exception {
        this.mockMvc = webAppContextSetup(webApplicationContext).build();
    }

    @Test
    public void checkListEntitiesNotImplemented() throws Exception {
        mockMvc.perform(
                get("/v2/ni/entities").contentType(MediaType.APPLICATION_JSON).header("Host", "localhost").accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.jsonPath("$.error").value("501"))
                .andExpect(MockMvcResultMatchers.jsonPath("$.description").value("this operation 'List Entities' is not implemented"))
                .andExpect(status().isNotImplemented());

    }

    @Test
    public void checkListEntitiesIncompatibleParameter() throws Exception {
        mockMvc.perform(
                get("/v2/i/entities").param("id", "Boe_Idearium").param("idPattern", "Bode_.*").contentType(MediaType.APPLICATION_JSON).header("Host", "localhost").accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.jsonPath("$.error").value("400"))
                .andExpect(MockMvcResultMatchers.jsonPath("$.description").value("The incoming request is invalid in this context. The parameter Boe_Idearium is incompatible with Bode_.* in List entities operation."))
                .andExpect(status().isBadRequest());
    }

    @Test
    public void checkListEntitiesInvalidSyntax() throws Exception {
        mockMvc.perform(
                get("/v2/i/entities").param("id", "Boe_Idearium?").contentType(MediaType.APPLICATION_JSON).header("Host", "localhost").accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.jsonPath("$.error").value("400"))
                .andExpect(MockMvcResultMatchers.jsonPath("$.description").value("Syntax invalid"))
                .andExpect(MockMvcResultMatchers.jsonPath("$.affectedItems").value("Boe_Idearium?"))
                .andExpect(status().isBadRequest());
    }

}

@@ -621,16 +621,47 @@
 erver;%0A%0A
+import junit.framework.Assert;%0A
 import o
@@ -1393,16 +1393,135 @@
 Context;
+%0Aimport sun.text.resources.ar.CollationData_ar;%0A%0Aimport java.util.stream.Collectors;%0Aimport java.util.stream.IntStream;
 %0A%0Aimport
@@ -4236,10 +4236,1500 @@
 %0A    %7D%0A%0A
+    @Test%0A    public void checkListTypeInvalidSyntax() throws Exception %7B%0A        String p257times = IntStream.range(0, 257)%0A                .mapToObj(x -%3E %22p%22)%0A                .collect(Collectors.joining());%0A        mockMvc.perform(%0A                get(%22/v2/i/entities%22).param(%22type%22, p257times).contentType(MediaType.APPLICATION_JSON).header(%22Host%22, %22localhost%22).accept(MediaType.APPLICATION_JSON))%0A                .andExpect(MockMvcResultMatchers.jsonPath(%22$.error%22).value(%22400%22))%0A                .andExpect(MockMvcResultMatchers.jsonPath(%22$.description%22).value(%22Syntax invalid%22))%0A                .andExpect(MockMvcResultMatchers.jsonPath(%22$.affectedItems%22).value(p257times))%0A                .andExpect(status().isBadRequest());%0A    %7D%0A%0A    @Test%0A    public void checkListAttrsInvalidSyntax() throws Exception %7B%0A        String  invalidAttrs = IntStream.range(0, 257)%0A                .mapToObj(x -%3E %22?%22)%0A                .collect(Collectors.joining());%0A        mockMvc.perform(%0A                get(%22/v2/i/entities%22).param(%22attrs%22, invalidAttrs).contentType(MediaType.APPLICATION_JSON).header(%22Host%22, %22localhost%22).accept(MediaType.APPLICATION_JSON))%0A                .andExpect(MockMvcResultMatchers.jsonPath(%22$.error%22).value(%22400%22))%0A                .andExpect(MockMvcResultMatchers.jsonPath(%22$.description%22).value(%22Syntax invalid%22))%0A                .andExpect(MockMvcResultMatchers.jsonPath(%22$.affectedItems%22).value(invalidAttrs))%0A                .andExpect(status().isBadRequest());%0A    %7D%0A%0A
 %7D%0A

add invalid syntax tests for the type and the attrs request params