package com.wesabe.grendel.auth.tests; import static org.fest.assertions.Assertions.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response.Status; import org.junit.Before; import org.junit.Test; import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; import com.wesabe.grendel.auth.Credentials; import com.wesabe.grendel.auth.Session; import com.wesabe.grendel.entities.User; import com.wesabe.grendel.entities.dao.UserDAO; import com.wesabe.grendel.openpgp.CryptographicException; import com.wesabe.grendel.openpgp.KeySet; import com.wesabe.grendel.openpgp.UnlockedKeySet; @RunWith(Enclosed.class) public class CredentialsTest { public static class A_Set_Of_Credentials { private Credentials creds; @Before public void setup() throws Exception { this.creds = new Credentials("woo", "hah"); } @Test public void itHasAUsername() throws Exception { assertThat(creds.getUsername()).isEqualTo("woo"); } @Test public void itHasAPassword() throws Exception { assertThat(creds.getPassword()).isEqualTo("hah"); } } private static abstract class Session_Context { protected Credentials creds; protected UserDAO userDAO; protected KeySet keySet; protected UnlockedKeySet unlockedKeySet; protected User user; public void setup() throws Exception { this.unlockedKeySet = mock(UnlockedKeySet.class); this.keySet = mock(KeySet.class); when(keySet.unlock(any(char[].class))).thenReturn(unlockedKeySet); this.user = mock(User.class); when(user.getId()).thenReturn("woo"); when(user.getKeySet()).thenReturn(keySet); this.userDAO = mock(UserDAO.class); when(userDAO.findById("woo")).thenReturn(user); this.creds = new Credentials("woo", "hah"); } } public static class Building_A_Session_For_A_Nonexistent_User extends Session_Context { @Before @Override public void setup() throws Exception { super.setup(); when(userDAO.findById("woo")).thenReturn(null); } @Test public void itThrowsAnAuthChallenge() throws Exception { try { creds.buildSession(userDAO); fail("should have thrown an auth challenge, but didn't"); } catch (WebApplicationException e) { assertThat(e.getResponse()).isEqualTo(Credentials.CHALLENGE); } } } public static class Building_A_Session_For_A_Bad_Password extends Session_Context { @Before @Override public void setup() throws Exception { super.setup(); when(keySet.unlock(any(char[].class))).thenThrow(new CryptographicException("augh")); } @Test public void itAttemptsToUnlockTheKeySet() throws Exception { try { creds.buildSession(userDAO); } catch (WebApplicationException e) {} verify(keySet).unlock("hah".toCharArray()); } @Test public void itThrowsAnAuthChallenge() throws Exception { try { creds.buildSession(userDAO); fail("should have thrown an auth challenge, but didn't"); } catch (WebApplicationException e) { assertThat(e.getResponse()).isEqualTo(Credentials.CHALLENGE); } } } public static class Building_A_Session_For_Valid_Creds extends Session_Context { @Before @Override public void setup() throws Exception { super.setup(); } @Test public void itAttemptsToUnlockTheKeySet() throws Exception { try { creds.buildSession(userDAO); } catch (WebApplicationException e) {} verify(keySet).unlock("hah".toCharArray()); } @Test public void itReturnsASessionWithTheUserAndKeySet() throws Exception { final Session session = creds.buildSession(userDAO); assertThat(session.getUser()).isEqualTo(user); assertThat(session.getKeySet()).isEqualTo(unlockedKeySet); } } public static class Building_A_Session_For_Valid_Creds_With_An_Expected_id extends Session_Context { @Before @Override public void setup() throws Exception { super.setup(); } @Test public void itReturnsASessionWithTheUserAndKeySet() throws Exception { final Session session = creds.buildSession(userDAO, "woo"); assertThat(session.getUser()).isEqualTo(user); assertThat(session.getKeySet()).isEqualTo(unlockedKeySet); } } public static class Building_A_Session_For_Valid_Creds_With_An_Unxpected_Id extends Session_Context { @Before @Override public void setup() throws Exception { super.setup(); } @Test public void itThrowsAn401() throws Exception { try { creds.buildSession(userDAO, "whee"); fail("should have thrown an auth challenge, but didn't"); } catch (WebApplicationException e) { assertThat(e.getResponse().getStatus()).isEqualTo(Status.FORBIDDEN.getStatusCode()); } } } public static class An_Authentication_Challenge { @Test public void itReturnsA401() throws Exception { assertThat(Credentials.CHALLENGE.getStatus()).isEqualTo(Status.UNAUTHORIZED.getStatusCode()); } @Test public void itHasRealmInformation() throws Exception { assertThat(Credentials.CHALLENGE.getMetadata().getFirst(HttpHeaders.WWW_AUTHENTICATE)).isEqualTo("Basic realm=\"Grendel\""); } } }