package org.kingsski.kaas.service.season;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.kingsski.kaas.database.season.Season;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.mockito.AdditionalMatchers.not;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class)
@WebMvcTest(SeasonRestController.class)
public class SeasonRestControllerTest {

    private static final String API_SEASON = "/season/";
    private static final String API_SEASON_NAME = "/season?name=";
    private static final String API_SEASON_COMPETITION = "/season?competition=";

    @Resource
    private MockMvc mvc;

    @MockBean
    private SeasonService seasonService;

    @Test
    public void getSeasons() throws Exception {
        final Season season = new Season();
        season.setName("boom");
        final List<Season> seasons = new ArrayList<>();
        seasons.add(season);

        given(seasonService.getSeasons()).willReturn(seasons);

        mvc.perform(get(API_SEASON))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$", hasSize(1)))
                .andExpect(jsonPath("$[0].name", is(season.getName())));
    }

    @Test
    public void getSeasonByName() throws Exception {
        final String name = "boom";
        final String badName = "pow";
        final Season season = new Season();
        season.setName(name);

        given(seasonService.getSeasonByName(name)).willReturn(season);
        given(seasonService.getSeasonByName(not(eq(name)))).willReturn(null);

        mvc.perform(get(API_SEASON_NAME + name))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name", is(season.getName())));

        mvc.perform(get(API_SEASON_NAME + badName))
                .andExpect(status().isNotFound());
    }

    @Test
    public void getSeasonByCompetition() throws Exception {
        final String name = "boom";
        final String badName = "pow";
        final Season season = new Season();
        season.setName("popeye");
        final List<Season> seasons = new ArrayList<>();
        seasons.add(season);

        given(seasonService.getSeasonsByCompetition(name)).willReturn(seasons);
        given(seasonService.getSeasonsByCompetition(not(eq(name)))).willReturn(null);

        mvc.perform(get(API_SEASON_COMPETITION + name))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$[0].name", is(season.getName())));

        mvc.perform(get(API_SEASON_COMPETITION + badName))
                .andExpect(status().isNotFound());
    }

    @Test
    public void getSeasonById() throws Exception {
        final long id = 1;
        final long badId = 2;
        final Season season = new Season();
        season.setId(id);

        given(seasonService.getSeasonById(not(eq(id)))).willReturn(null);
        given(seasonService.getSeasonById(id)).willReturn(season);

        mvc.perform(get(API_SEASON + id))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.id", is((int)season.getId())));

        mvc.perform(get(API_SEASON + badId))
                .andExpect(status().isNotFound());
    }
}

@@ -130,21 +130,145 @@
 ase.
-season.Season
+competition.Competition;%0Aimport org.kingsski.kaas.database.season.Season;%0Aimport org.kingsski.kaas.service.competition.CompetitionService
 ;%0Aim
@@ -1448,17 +1448,16 @@
 vc mvc;%0A
-%0A
     @Moc
@@ -1502,16 +1502,81 @@
 Service;
+%0A    @MockBean%0A    private CompetitionService competitionService;
 %0A%0A    @T
@@ -2824,39 +2824,84 @@
   final 
-String badName = %22pow%22;
+Competition competition = Competition.builder().name(name).build();%0A
 %0A       
@@ -2926,54 +2926,47 @@
 on =
- new
  Season
-();%0A        season.setName(%22popeye%22
+.builder().name(name + 1).build(
 );%0A 
@@ -3056,36 +3056,41 @@
 %0A%0A        given(
-seas
+competiti
 onService.getSea
@@ -3082,33 +3082,24 @@
 nService.get
-SeasonsBy
 Competition(
@@ -3097,23 +3097,46 @@
 petition
+ByName
 (name))
+%0A                
 .willRet
@@ -3139,23 +3139,27 @@
 lReturn(
-seas
+competiti
 on
-s
 );%0A     
@@ -3206,30 +3206,38 @@
 tition(n
-ot(eq(name))))
+ame))%0A                
 .willRet
@@ -3232,36 +3232,39 @@
     .willReturn(
-null
+seasons
 );%0A%0A        mvc.
@@ -3415,32 +3415,249 @@
 on.getName())));
+%0A    %7D%0A%0A    @Test%0A    public void getSeasonByCompetitionNotExist() throws Exception %7B%0A        final String name = %22pow%22;%0A%0A        given(competitionService.getCompetitionByName(name))%0A                .willReturn(null);
 %0A%0A        mvc.pe
@@ -3691,20 +3691,17 @@
 ITION + 
-badN
+n
 ame))%0A  

Fix season controller tests