package com.atlassian.stash.internal.spring.security;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.http.HttpMethod;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(Parameterized.class)
public class MaintenanceRequestMatcherTest {

    @Parameterized.Parameter(0)
    public boolean shouldMatch;

    @Parameterized.Parameter(1)
    public HttpServletRequest request;

    private MaintenanceRequestMatcher matcher = new MaintenanceRequestMatcher();

    @Test
    public void testMatches() throws Exception {
        assertEquals("Matcher should " + (shouldMatch ? "" : "not ") + "match " + request,
                shouldMatch, matcher.matches(request));
    }

    @Parameterized.Parameters(name = "{1}")
    public static Iterable<Object[]> data() {
        return Arrays.asList(
                testCase(true, HttpMethod.GET, "/mvc", "/maintenance"),
                testCase(false, HttpMethod.GET, "/custom", "/maintenance"),
                testCase(true, HttpMethod.POST, "/mvc", "/maintenance"),
                testCase(true, HttpMethod.GET, "/mvc", "/maintenance/lock"),
                testCase(true, HttpMethod.DELETE, "/mvc", "/maintenance/lock"),
                testCase(false, HttpMethod.GET, "", "/maintenance"),
                testCase(false, HttpMethod.GET, "/mvc", null)
        );
    }

    private static Object[] testCase(boolean matches, HttpMethod method, String servletPath, String pathInfo) {
        final HttpServletRequest request = mock(HttpServletRequest.class);

        when(request.getMethod()).thenReturn(method.name());
        when(request.getServletPath()).thenReturn(servletPath);
        when(request.getPathInfo()).thenReturn(pathInfo);

        when(request.toString()).thenAnswer(new Answer<Object>() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                return request.getMethod() + " " + request.getServletPath() + request.getPathInfo();
            }
        });

        return new Object[]{matches, request};
    }

}