package it.com.atlassian.stash.rest.pull;

import com.atlassian.bitbucket.test.TestContext;
import com.google.common.collect.ImmutableMap;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.response.Response;
import org.junit.Test;

import javax.ws.rs.core.MediaType;
import java.util.List;
import java.util.Map;

import static java.util.stream.Collectors.toList;
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import static javax.ws.rs.core.Response.Status.OK;
import static javax.ws.rs.core.Response.Status.UNAUTHORIZED;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;

public class PullRequestParticipantSearchResourceTest extends BasePullRequestParticipantResourceTest {

    @Test
    public void testGetPullParticipantsWithNameFilter() {
        RestAssured.expect().statusCode(OK.getStatusCode())
                .body("size", equalTo(1))
                .body("start", equalTo(0))
                .body("isLastPage", equalTo(true))
                .body("values[0].name", equalTo(AUTHOR))
                .body("values[0].emailAddress", equalTo(AUTHOR + TestContext.DEFAULT_EMAIL_HOST))
                .log().ifError()
                .given()
                .auth().preemptive().basic(AUTHOR, AUTHOR)
                .contentType(MediaType.APPLICATION_JSON)
                .header("Accept", MediaType.APPLICATION_JSON)
                .when()
                .get(getUrl(PR_PARTICIPANT_TEST, PR_PARTICIPANT_TEST, ImmutableMap.<String, String>builder()
                        .put("filter", "auth")
                        .build()));
    }

    @Test
    public void testGetPullParticipantsWithRoleFilter() {
        RestAssured.expect().statusCode(OK.getStatusCode())
                .body("size", equalTo(2))
                .body("start", equalTo(0))
                .body("isLastPage", equalTo(true))
                .body("values[0].name", equalTo(REVIEWER))
                .body("values[0].emailAddress", equalTo(REVIEWER + TestContext.DEFAULT_EMAIL_HOST))
                .body("values[1].name", equalTo(REVIEWER2))
                .body("values[1].emailAddress", equalTo(REVIEWER2 + TestContext.DEFAULT_EMAIL_HOST))
                .log().ifError()
                .given()
                .auth().preemptive().basic(AUTHOR, AUTHOR)
                .contentType(MediaType.APPLICATION_JSON)
                .header("Accept", MediaType.APPLICATION_JSON)
                .when()
                .get(getUrl(PR_PARTICIPANT_TEST, PR_PARTICIPANT_TEST, ImmutableMap.<String, String>builder()
                        .put("role", "REVIEWER")
                        .build()));
    }

    @Test
    public void testGetPullParticipantsWithInvalidRoleFilter() {
        RestAssured.expect().statusCode(BAD_REQUEST.getStatusCode())
                .log().ifError()
                .given()
                .auth().preemptive().basic(AUTHOR, AUTHOR)
                .contentType(MediaType.APPLICATION_JSON)
                .header("Accept", MediaType.APPLICATION_JSON)
                .when()
                .get(getUrl(PR_PARTICIPANT_TEST, PR_PARTICIPANT_TEST, ImmutableMap.<String, String>builder()
                        .put("role", "INVALID_REVIEWER")
                        .build()));
    }

    @Test
    public void testGetPullParticipantsShouldReturnUsersSortedByName() {
        Response response = RestAssured.expect().statusCode(OK.getStatusCode())
                .log().ifError()
                .given()
                .auth().preemptive().basic(AUTHOR, AUTHOR)
                .contentType(MediaType.APPLICATION_JSON)
                .header("Accept", MediaType.APPLICATION_JSON)
                .when()
                .get(getUrl(PR_PARTICIPANT_TEST, PR_PARTICIPANT_TEST, ImmutableMap.<String, String>builder()
                        .build()));

        List<String> userNames = response.body().jsonPath()
                .getList("values", Map.class)
                .stream()
                .map(user -> (String) user.get("name"))
                .collect(toList());
        assertThat(userNames, is(userNames.stream().sorted().collect(toList())));
    }

    @Test
    public void testGetPullParticipantsShouldFailIfUserDoesNotHaveRepoPermission() {
        RestAssured.expect().statusCode(UNAUTHORIZED.getStatusCode())
                .log().ifValidationFails()
                .given()
                .auth().preemptive().basic(USER_WITHOUT_PERMISSION, USER_WITHOUT_PERMISSION)
                .contentType(MediaType.APPLICATION_JSON)
                .header("Accept", MediaType.APPLICATION_JSON)
                .when()
                .get(getUrl(PR_PARTICIPANT_TEST, PR_PARTICIPANT_TEST, ImmutableMap.<String, String>builder()
                        .build()));
    }
}
