package us.kbase.test.auth2.service.ui;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.nio.file.InvalidPathException;

import javax.ws.rs.core.UriInfo;

import org.junit.Test;

import us.kbase.auth2.service.ui.UIUtils;
import us.kbase.test.auth2.TestCommon;

public class UIUtilsTest {

	@Test
	public void relativizeNoCommonPathNoEndingSlash() {
		final UriInfo info = mock(UriInfo.class);
		when(info.getPath()).thenReturn("/whee/whoo");
		assertThat("incorrect url", UIUtils.relativize(info, "/foo/bar"), is("../foo/bar"));
	}
	
	@Test
	public void relativizeNoCommonPathWithTrailingSlash() {
		final UriInfo info = mock(UriInfo.class);
		when(info.getPath()).thenReturn("/whee/whoo/");
		assertThat("incorrect url", UIUtils.relativize(info, "/foo/bar/"), is("../../foo/bar/"));
	}
	
	@Test
	public void relativizeWithCommonPath() {
		final UriInfo info = mock(UriInfo.class);
		when(info.getPath()).thenReturn("/foo/whoo/");
		assertThat("incorrect url", UIUtils.relativize(info, "/foo/bar/"), is("../bar/"));
	}
	
	@Test
	public void relativizeGetRootParent() {
		final UriInfo info = mock(UriInfo.class);
		when(info.getPath()).thenReturn("/whee");
		assertThat("incorrect url", UIUtils.relativize(info, "/foo/bar/"), is("foo/bar/"));
	}
	
	@Test
	public void relativizeSamePath() {
		final UriInfo info = mock(UriInfo.class);
		when(info.getPath()).thenReturn("/foo/bar/");
		assertThat("incorrect url", UIUtils.relativize(info, "/foo/bar"), is(""));
	}
	
	@Test
	public void relativizeSamePathTrailingSlash() {
		final UriInfo info = mock(UriInfo.class);
		when(info.getPath()).thenReturn("/foo/bar/");
		assertThat("incorrect url", UIUtils.relativize(info, "/foo/bar/"), is(""));
	}
	
	@Test
	public void relativizeRootPaths() {
		final UriInfo info = mock(UriInfo.class);
		when(info.getPath()).thenReturn("/");
		assertThat("incorrect url", UIUtils.relativize(info, "/"), is(""));
	}
	
	@Test
	public void relativizeSubElement() {
		final UriInfo info = mock(UriInfo.class);
		when(info.getPath()).thenReturn("/foo/bar");
		assertThat("incorrect url", UIUtils.relativize(info, "/foo/baz"), is("baz"));
	}
	
	@Test
	public void relativizeFailNulls() {
		failRelativize(null, "whee", new NullPointerException("current"));
		failRelativize(mock(UriInfo.class), null, new NullPointerException("target"));
	}
	
	@Test
	public void relativizeFailIllegalPath() {
		failRelativize(mock(UriInfo.class), "/foo/bar\0baz/whee",
				new InvalidPathException("/foo/bar\0baz/whee", "Nul character not allowed"));
	}
	
	@Test
	public void relativizeFailRelativePath() {
		failRelativize(mock(UriInfo.class), "foo/bar",
				new IllegalArgumentException("target must be absolute: foo/bar"));
	}
	
	private void failRelativize(
			final UriInfo uriInfo,
			final String target,
			final Exception e) {
		try {
			UIUtils.relativize(uriInfo, target);
			fail("expected exception");
		} catch (Exception got) {
			TestCommon.assertExceptionCorrect(got, e);
		}
	}
	
}

@@ -341,16 +341,180 @@
 .Test;%0A%0A
+import us.kbase.auth2.lib.exceptions.AuthException;%0Aimport us.kbase.auth2.lib.exceptions.ErrorType;%0Aimport us.kbase.auth2.lib.exceptions.MissingParameterException;%0A
 import u
@@ -3284,10 +3284,882 @@
 %09%7D%0A%09%7D%0A%09%0A
+%09@Test%0A%09public void checkState() throws Exception %7B%0A%09%09UIUtils.checkState(%22foo%22, %22foo%22); // expect nothing to happen%0A%09%7D%0A%09%0A%09@Test%0A%09public void checkStateFailNulls() %7B%0A%09%09failCheckState(null, %22foo%22,%0A%09%09%09%09new MissingParameterException(%22Couldn't retrieve state value from cookie%22));%0A%09%09failCheckState(%22foo%22, null, new AuthException(ErrorType.AUTHENTICATION_FAILED,%0A%09%09%09%09%22State values do not match, this may be a CXRF attack%22));%0A%09%7D%0A%09%0A%09@Test%0A%09public void checkStateFailNoMatch() %7B%0A%09%09failCheckState(%22foo%22, %22bar%22, new AuthException(ErrorType.AUTHENTICATION_FAILED,%0A%09%09%09%09%22State values do not match, this may be a CXRF attack%22));%0A%09%7D%0A%09%0A%09private void failCheckState(final String cookie, final String state, final Exception e) %7B%0A%09%09try %7B%0A%09%09%09UIUtils.checkState(cookie, state);%0A%09%09%09fail(%22expected exception%22);%0A%09%09%7D catch (Exception got) %7B%0A%09%09%09TestCommon.assertExceptionCorrect(got, e);%0A%09%09%7D%0A%09%7D%0A%09%0A%09%0A
 %7D%0A

Add checkState test