package com.atlassian.stash.sal.api.web.context;

import com.atlassian.bitbucket.request.RequestContext;
import com.atlassian.bitbucket.request.RequestManager;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class DefaultHttpContextTest {
    @Mock
    private RequestManager requestManager;

    @InjectMocks
    private DefaultHttpContext context;

    @Test
    public void testNullRequestContext() {
        assertNull(context.getRequest());
        assertNull(context.getResponse());
        assertNull(context.getSession(false));
        assertNull(context.getSession(true));
    }

    @Test
    public void testNonHttpRequestContext() {
        Object request = new Object();
        Object response = new Object();

        mockRequestContext(request, response);

        assertNull(context.getRequest());
        assertNull(context.getResponse());
        assertNull(context.getSession(false));
        assertNull(context.getSession(true));
    }

    @Test
    public void testHttpRequestContext() {
        HttpServletRequest request = mock(HttpServletRequest.class);
        HttpServletResponse response = mock(HttpServletResponse.class);
        HttpSession session = mock(HttpSession.class);

        mockRequestContext(request, response);
        when(request.getSession(eq(false))).thenReturn(null);
        when(request.getSession(eq(true))).thenReturn(session);

        assertSame(request, context.getRequest());
        assertSame(response, context.getResponse());
        assertNull(context.getSession(false));

        verify(request).getSession(eq(false));
        verify(request, never()).getSession();

        assertSame(session, context.getSession(true));
    }

    private void mockRequestContext(Object request, Object response) {
        RequestContext requestContext = mock(RequestContext.class);
        when(requestContext.getRawRequest()).thenReturn(request);
        when(requestContext.getRawResponse()).thenReturn(response);
        when(requestManager.getRequestContext()).thenReturn(requestContext);

    }

}
