package uk.ac.ebi.quickgo.client.controller;

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.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.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import uk.ac.ebi.quickgo.client.QuickGOREST;
import uk.ac.ebi.quickgo.client.model.presets.impl.CompositePresetImpl;

import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

/**
 * Tests whether the {@link CompositePresetImpl} instance is populated correctly at application startup.
 *
 * Created 05/09/16
 * @author Edd
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {QuickGOREST.class})
@WebAppConfiguration
public class PresetsRetrievalIT {
    private static final String RESOURCE_URL = "/internal/presets";
    private static final String FIELDS_PARAM = "fields";
    private static final int ASSIGNED_BY_PRESETS_WITHOUT_DUPLICATES = 24;

    @Autowired private WebApplicationContext webApplicationContext;

    private MockMvc mockMvc;

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

    @Test
    public void canRetrieveAssignedByPresets() throws Exception {
        mockMvc.perform(get(RESOURCE_URL))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.assignedBy").exists())
                .andExpect(MockMvcResultMatchers.jsonPath("$.assignedBy.*", hasSize(
                        ASSIGNED_BY_PRESETS_WITHOUT_DUPLICATES)));
    }

    @Test
    public void canRetrieveReferencePresets() throws Exception {
        mockMvc.perform(get(RESOURCE_URL))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.references.*", hasSize(greaterThan(0))));
    }

    @Test
    public void canRetrieveEvidencePresets() throws Exception {
        mockMvc.perform(get(RESOURCE_URL))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.evidences.*", hasSize(greaterThan(0))));
    }

    @Test
    public void canRetrieveWithFromPresets() throws Exception {
        mockMvc.perform(get(RESOURCE_URL))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.withFrom.*", hasSize(greaterThan(0))));
    }

    @Test
    public void canRetrieveGeneProductPresets() throws Exception {
        mockMvc.perform(get(RESOURCE_URL))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.geneProducts.*", hasSize(greaterThan(0))));
    }

    @Test
    public void canRetrieveGOSlimSetsPresets() throws Exception {
        mockMvc.perform(get(RESOURCE_URL))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.goSlimSets.*", hasSize(greaterThan(0))));
    }

    @Test
    public void canRetrieveTaxonPresets() throws Exception {
        mockMvc.perform(get(RESOURCE_URL))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.taxons").exists());
    }

    @Test
    public void canRetrieveQualifierPresets() throws Exception {
        mockMvc.perform(get(RESOURCE_URL))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.qualifiers").exists());
    }

    @Test
    public void canRetrieveAspectPresets() throws Exception {
        mockMvc.perform(get(RESOURCE_URL))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.aspects.*", hasSize(3)));
    }

    @Test
    public void canRetrieveGeneProductTypesPresets() throws Exception {
        mockMvc.perform(get(RESOURCE_URL))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.geneProductTypes.*", hasSize(3)));
    }

    @Test
    public void canRetrieveAnnotationExtensionRelationsPresets() throws Exception {
        mockMvc.perform(get(RESOURCE_URL))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.extRelations.*", hasSize(greaterThan(0))));
    }

    @Test
    public void canRetrieveAnnotationExtensionDatabasesPresets() throws Exception {
        mockMvc.perform(get(RESOURCE_URL))
               .andDo(print())
               .andExpect(status().isOk())
               .andExpect(jsonPath("$.extDatabases.*", hasSize(greaterThan(0))));
    }

    @Test
    public void canRetrieveSingleDesiredPreset() throws Exception {
        mockMvc.perform(get(RESOURCE_URL).param(FIELDS_PARAM, "goSlimSets"))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.assignedBy").doesNotExist())
                .andExpect(jsonPath("$.references").doesNotExist())
                .andExpect(jsonPath("$.evidences").doesNotExist())
                .andExpect(jsonPath("$.withFrom").doesNotExist())
                .andExpect(jsonPath("$.geneProducts").doesNotExist())
                .andExpect(jsonPath("$.goSlimSets.*", hasSize(greaterThan(0))));
    }

    @Test
    public void canRetrieveMultipleDesiredPresets() throws Exception {
        mockMvc.perform(get(RESOURCE_URL).param(FIELDS_PARAM, "goSlimSets,geneProducts"))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.assignedBy").doesNotExist())
                .andExpect(jsonPath("$.references").doesNotExist())
                .andExpect(jsonPath("$.evidences").doesNotExist())
                .andExpect(jsonPath("$.withFrom").doesNotExist())
                .andExpect(jsonPath("$.geneProducts.*", hasSize(greaterThan(0))))
                .andExpect(jsonPath("$.goSlimSets.*", hasSize(greaterThan(0))));
    }
}

@@ -446,82 +446,8 @@
 vc;%0A
-import org.springframework.test.web.servlet.result.MockMvcResultMatchers;%0A
 impo
@@ -509,16 +509,16 @@
 ilders;%0A
+
 import o
@@ -1573,82 +1573,8 @@
 ds%22;
-%0A    private static final int ASSIGNED_BY_PRESETS_WITHOUT_DUPLICATES = 24;
 %0A%0A  
@@ -2060,159 +2060,8 @@
 s())
-%0A                .andExpect(MockMvcResultMatchers.jsonPath(%22$.assignedBy.*%22, hasSize(%0A                        ASSIGNED_BY_PRESETS_WITHOUT_DUPLICATES)))
 ;%0A  
@@ -2871,36 +2871,18 @@
 From
-.*%22, hasSize(greaterThan(0))
+%22).exists(
 ));%0A

Change tests for assignedBy and withFrom to reflect the fact their data is now coming from a RESTful source.