package org.codiki.core;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.codiki.core.security.Route;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.http.HttpMethod;

@RunWith(MockitoJUnitRunner.class)
public class AbstractFilterTest {
	
	/**
	 * Class that simplify the test mocks for the method {@link AbstractFilter#getRoutes()}.
	 * 
	 * @author Takiguchi
	 *
	 */
	private class TestFilter extends AbstractFilter {
		public List<Route> routes;
		
		@Override
		protected List<Route> getRoutes() {
			return routes;
		}

		@Override
		protected void filter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
				throws IOException, ServletException {
			// Do nothing
		}
	}
	
	/** Tested class object */
	private AbstractFilter filter = new TestFilter();
	
	@Test
	public void test_isRequestFiltered_true() {
		((TestFilter) filter).routes = Arrays.asList(new Route("toto", HttpMethod.GET));
		
		Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "GET"));
	}
	
	@Test
	public void test_isRequestFiltered_true_without_httpMethod() {
		((TestFilter) filter).routes = Arrays.asList(new Route("toto"));
		
		Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "GET"));
		Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "POST"));
		Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "PUT"));
		Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "DELETE"));
		Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "DumbThing"));
	}
	
	@Test
	public void test_isRequestFiltered_false() {
		((TestFilter) filter).routes = Arrays.asList(new Route("toto", HttpMethod.POST));

		Assert.assertFalse(filter.isRequestFiltered("http://localhost/toto", "GET"));
	}

	@Test
	public void test_isRequestFiltered_severalHttpMethods() {
		((TestFilter) filter).routes = Arrays.asList(new Route("toto", HttpMethod.GET, HttpMethod.POST));

		Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "GET"));
		Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "POST"));
		Assert.assertFalse(filter.isRequestFiltered("http://localhost/toto", "PUT"));
		Assert.assertFalse(filter.isRequestFiltered("http://localhost/toto", "DELETE"));
		Assert.assertFalse(filter.isRequestFiltered("http://localhost/toto", "DumbThing"));
		
	}
}
