package uk.ac.ebi.atlas.experimentpage;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import uk.ac.ebi.atlas.testutils.JdbcUtils;

import javax.inject.Inject;

import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.isA;
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.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@ExtendWith(SpringExtension.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"classpath:applicationContext.xml", "classpath:dispatcher-servlet.xml"})
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class JsonCellMetadataControllerWIT {
    @Inject
    private JdbcUtils jdbcTestUtils;

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @BeforeEach
    void setUp() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }

    @Test
    public void validJsonForExistingCellId() throws Exception {
        String experimentAccession = jdbcTestUtils.fetchRandomSingleCellExperimentAccession();
        String cellId = jdbcTestUtils.fetchRandomCellFromExperiment(experimentAccession);

        this.mockMvc
                .perform(get(
                        "/json/experiment/" + experimentAccession + "/cell/" + cellId + "/metadata"))
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(jsonPath("$", hasSize(greaterThanOrEqualTo(0))))
                .andExpect(jsonPath("$[0].displayName", isA(String.class)))
                .andExpect(jsonPath("$[0].value", isA(String.class)));
    }

    @Test
    public void emptyJsonForInvalidCellId() throws Exception {
        String experimentAccession = jdbcTestUtils.fetchRandomSingleCellExperimentAccession();
        String cellId = "FOO";

        this.mockMvc
                .perform(get(
                        "/json/experiment/" + experimentAccession + "/cell/" + cellId + "/metadata"))
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(jsonPath("$", hasSize(0)));
    }

    @Test
    public void validJsonForInvalidExperimentAccession() throws Exception {
        String experimentAccession = "FOO";
        String cellId = "BAR";

        this.mockMvc
                .perform(get(
                        "/json/experiment/" + experimentAccession + "/cell/" + cellId + "/metadata")).andDo(print())
                .andExpect(status().is4xxClientError());
    }
}


@@ -75,16 +75,59 @@
 reEach;%0A
+import org.junit.jupiter.api.RepeatedTest;%0A
 import o
@@ -1605,23 +1605,16 @@
 _CLASS)%0A
-public 
 class Js
@@ -1898,39 +1898,44 @@
     %7D%0A%0A    @
-Test%0A    public
+RepeatedTest(20)%0A   
  void validJ
@@ -2521,154 +2521,8 @@
 ))))
-%0A                .andExpect(jsonPath(%22$%5B0%5D.displayName%22, isA(String.class)))%0A                .andExpect(jsonPath(%22$%5B0%5D.value%22, isA(String.class)))
 ;%0A  
@@ -2536,31 +2536,24 @@
   @Test%0A    
-public 
 void emptyJs
@@ -3079,15 +3079,8 @@
     
-public 
 void

Fix test Some experiments don’t have any factors other than single cell identifier (e.g. E-GEOD-99058) and this is contemplated in the test hasSize(greaterThanOrEuqalTo(0)), but then there will be no displayName or value available; this happened only sometimes, so repeating the test ensures a more consistent behaviour: either it fails or it passes