package com.example.voter;

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.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.*;

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

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class VoteControllerTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private VoteController voteController;

    @Before
    public void setup() {
        // sample test data
        Map candidates = new HashMap();
        candidates.put("Chris Keniston", "3");
        candidates.put("Darrell Castle", "2");
        candidates.put("Donald Trump", "8");
        candidates.put("Gary Johnson", "3");
        candidates.put("Hillary Clinton", "14");
        candidates.put("Jill Stein", "5");
        voteController.seedData(candidates);
    }

    @Test
    public void getVotesReturnsListOfVoteChoices() throws Exception {
        String expectedVoteList =
                "{\"candidates\":[\"Chris Keniston\",\"Darrell Castle\",\"Donald Trump\",\"Gary Johnson\",\"Hillary Clinton\",\"Jill Stein\"]}";
        ResponseEntity<String> responseEntity = this.restTemplate.getForEntity("/candidates", String.class);
        assertThat(responseEntity.getStatusCode().value() == 200);
        assertThat(responseEntity.getBody()).isEqualTo(expectedVoteList);

    }

    @Test
    public void postVoteReturnsNewVote() throws Exception {
        String expectedVote = "Test Vote";
        Vote vote = new Vote(expectedVote);
        ResponseEntity<Vote> responseEntity =
                this.restTemplate.postForEntity("/votes", vote, Vote.class);
        assertThat(responseEntity.getStatusCode().value() == 201);
        assertThat(responseEntity.getBody().getVote()).isEqualTo(expectedVote);
    }

    @Test
    public void getResultsReturnsExpectedVoteCounts() throws Exception {
        String expectedVote = "Chris Keniston";
        int expectedCount = 3;
        ParameterizedTypeReference<Map<String, List<VoteCount>>> typeRef =
                new ParameterizedTypeReference<Map<String, List<VoteCount>>>() {
                };
        ResponseEntity<Map<String, List<VoteCount>>> responseEntity =
                this.restTemplate.exchange("/results", HttpMethod.GET, null, typeRef);
        LinkedHashMap body = ((LinkedHashMap) responseEntity.getBody());
        Collection voteCountCollection = body.values();
        ArrayList voteCountArray = (ArrayList) voteCountCollection.toArray()[0];
        VoteCount voteCount = (VoteCount) voteCountArray.get(0);
        assertThat(responseEntity.getStatusCode().value() == 200);
        assertThat(voteCount.getVote()).isEqualTo(expectedVote);
        assertThat(voteCount.getCount()).isEqualTo(expectedCount);
    }

    @Test
    public void getWinnerReturnsCandidateWithMostVotes() throws Exception {
        String expectedVote = "Hillary Clinton";
        int expectedCount = 14;
        ResponseEntity<VoteCount> responseEntity =
                this.restTemplate.getForEntity("/winner", VoteCount.class);
        VoteCount voteCount = responseEntity.getBody();
        assertThat(responseEntity.getStatusCode().value() == 200);
        assertThat(voteCount.getVote()).isEqualTo(expectedVote);
        assertThat(voteCount.getCount()).isEqualTo(expectedCount);
    }
}

@@ -1307,18 +1307,23 @@
 void get
-Vo
+Candida
 tesRetur
@@ -1330,18 +1330,23 @@
 nsListOf
-Vo
+Candida
 teChoice
@@ -2282,16 +2282,22 @@
 sReturns
+ListOf
 Expected

Fix unit test names