You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
8.7 KiB

  1. package de.fd.fh.server.access;
  2. import com.mongodb.WriteResult;
  3. import de.fd.fh.server.user.UserId;
  4. import de.fd.fh.shared.network.messages.LoginRequest;
  5. import de.fd.fh.shared.network.messages.RegistrateRequest;
  6. import org.junit.jupiter.api.BeforeEach;
  7. import org.junit.jupiter.api.Test;
  8. import org.mockito.ArgumentCaptor;
  9. import spark.HaltException;
  10. import java.time.LocalDateTime;
  11. import java.util.Base64;
  12. import java.util.Observable;
  13. import java.util.Observer;
  14. import static org.hamcrest.MatcherAssert.assertThat;
  15. import static org.hamcrest.Matchers.notNullValue;
  16. import static org.junit.jupiter.api.Assertions.*;
  17. import static org.mockito.ArgumentMatchers.any;
  18. import static org.mockito.BDDMockito.then;
  19. import static org.mockito.Mockito.*;
  20. class AccessServiceTest implements Observer
  21. {
  22. private Object event;
  23. @BeforeEach
  24. void before()
  25. {
  26. this.event = null;
  27. }
  28. @Test
  29. void given_authenticatedUser_when_serverAuthenticateUser_should_authenticateUser()
  30. {
  31. final Access access = new Access(
  32. "testId",
  33. "testName",
  34. "testPwd",
  35. UserId.of("12345"),
  36. new AccessToken(
  37. "testToken",
  38. LocalDateTime.now(),
  39. Role.USER,
  40. UserId.of("12345")
  41. ),
  42. Role.USER);
  43. final AccessRepository repository = mock(AccessRepository.class);
  44. when(repository.findByToken(any()))
  45. .thenReturn(access);
  46. final String path = "/test/path";
  47. final String token = "testToken";
  48. final AccessToken result = new AccessService(repository).before(path, token);
  49. assertThat("User is not authenticated", result, notNullValue());
  50. then(repository).should().findByToken(any());
  51. then(repository).shouldHaveNoMoreInteractions();
  52. }
  53. @Test
  54. void given_notAuthenticatedUser_when_serverAuthenticateUser_should_denyUser()
  55. {
  56. final Access access = new Access(
  57. "testId",
  58. "testName",
  59. "testPwd",
  60. UserId.of("12345"),
  61. null,
  62. Role.USER);
  63. final AccessRepository repository = mock(AccessRepository.class);
  64. when(repository.findByToken(any()))
  65. .thenReturn(access);
  66. final String path = "/test/path";
  67. final String token = "testToken";
  68. assertThrows(HaltException.class, () ->new AccessService(repository).before(path, token));
  69. then(repository).should().findByToken(any());
  70. then(repository).shouldHaveNoMoreInteractions();
  71. }
  72. @Test
  73. void given_newUser_when_createUser_should_storeNewUser()
  74. {
  75. final RegistrateRequest request =
  76. RegistrateRequest.of("testUser", "testPwd");
  77. final AccessRepository repository = mock(AccessRepository.class);
  78. when(repository.findByUserName(any()))
  79. .thenReturn(null);
  80. ArgumentCaptor<Access> accessCaptor = ArgumentCaptor.forClass(Access.class);
  81. final AccessService service = new AccessService(repository);
  82. service.addObserver(this);
  83. final boolean result = service.createPlayer(request);
  84. assertTrue(result);
  85. assertThat("No event thrown", this.event, notNullValue());
  86. verify(repository).save(accessCaptor.capture());
  87. final Access createdAccess = accessCaptor.getValue();
  88. assertNotNull(createdAccess, "No Access created");
  89. assertNotNull(createdAccess.get_id(), "No Id created");
  90. assertNotNull(createdAccess.getUserId(), "No UserId created");
  91. assertEquals("testUser", createdAccess.getName(), "Wrong Username");
  92. assertEquals("testPwd", createdAccess.getPassword(), "Wrong Password");
  93. assertEquals(Role.USER.name(), createdAccess.getRole().name(), "Should be USER");
  94. assertNull(createdAccess.getToken(), "User should not be logged in");
  95. then(repository).should().findByUserName(any());
  96. then(repository).should().save(any(Access.class));
  97. then(repository).shouldHaveNoMoreInteractions();
  98. }
  99. @Test
  100. void given_loggedInUser_when_logout_should_logoutUser()
  101. {
  102. final Access access = new Access(
  103. "testId",
  104. "testName",
  105. "testPwd",
  106. UserId.of("12345"),
  107. null,
  108. Role.USER
  109. );
  110. final AccessToken token = AccessToken.of(access);
  111. access.setToken(token);
  112. final AccessRepository repository = mock(AccessRepository.class);
  113. when(repository.findByToken(any()))
  114. .thenReturn(access);
  115. ArgumentCaptor<Access> accessCaptor = ArgumentCaptor.forClass(Access.class);
  116. final AccessService service = new AccessService(repository);
  117. final boolean result = service.logout("testToken");
  118. assertTrue(result);
  119. verify(repository).save(accessCaptor.capture());
  120. final Access createdAccess = accessCaptor.getValue();
  121. assertNotNull(createdAccess, "No Access created");
  122. assertNotNull(createdAccess.get_id(), "No Id created");
  123. assertNotNull(createdAccess.getUserId(), "No UserId created");
  124. assertEquals("testName", createdAccess.getName(), "Wrong Username");
  125. assertEquals("testPwd", createdAccess.getPassword(), "Wrong Password");
  126. assertEquals(Role.USER.name(), createdAccess.getRole().name(), "Should be USER");
  127. assertNull(createdAccess.getToken(), "User should logged out");
  128. then(repository).should().findByToken(any());
  129. then(repository).should().save(any(Access.class));
  130. then(repository).shouldHaveNoMoreInteractions();
  131. }
  132. @Test
  133. void given_storedUser_when_loginUser_should_returnLoginRequest()
  134. {
  135. final byte[] message = Base64.getEncoder().encode("testName:testPassword".getBytes());
  136. final String header = "Basic " + new String(message);
  137. final Access access = new Access(
  138. "testId",
  139. "testName",
  140. "testPassword",
  141. UserId.of("12345"),
  142. null,
  143. Role.USER
  144. );
  145. final AccessRepository repository = mock(AccessRepository.class);
  146. when(repository.findByUserName(any()))
  147. .thenReturn(access);
  148. final LoginRequest result = new AccessService(repository).authorization(header);
  149. assertNotNull(result);
  150. assertEquals(result.getName(), "testName", "Wrong UserName");
  151. assertEquals(result.getUserId(), "12345", "Wrong Password");
  152. assertNotNull(result.getToken(), "Not logged in");
  153. }
  154. @Test
  155. void given_storedUserWithWrongPassword_when_loginUser_should_returnAccessDeny()
  156. {
  157. final byte[] message = Base64.getEncoder().encode("testName:testPassword".getBytes());
  158. final String header = "Basic " + new String(message);
  159. final AccessRepository repository = mock(AccessRepository.class);
  160. final LoginRequest result = new AccessService(repository).authorization(header);
  161. assertNull(result, "Return LoginRequest but wrong permissions");
  162. }
  163. @Test
  164. void given_storedUser_when_deleteUser_should_deleteUser()
  165. {
  166. final UserId userId = UserId.of("12345");
  167. final AccessToken token = new AccessToken(null, null, null, UserId.of("12345"));
  168. final AccessRepository repository = mock(AccessRepository.class);
  169. when(repository.deleteLoginByUserId(any(UserId.class)))
  170. .thenReturn(new WriteResult(1, false, null));
  171. final AccessService service = new AccessService(repository);
  172. service.addObserver(this);
  173. final boolean result = service.deleteAccount(userId, token);
  174. assertTrue(result);
  175. assertNotNull(event);
  176. then(repository).should().deleteLoginByUserId(any(UserId.class));
  177. then(repository).shouldHaveNoMoreInteractions();
  178. }
  179. @Test
  180. void given_storedUser_when_deleteUserWithWrongPermission_should_doNothing()
  181. {
  182. final UserId userId = UserId.of("12345");
  183. final AccessToken token = new AccessToken(null, null, null, UserId.of("98765"));
  184. final AccessRepository repository = mock(AccessRepository.class);
  185. when(repository.deleteLoginByUserId(any(UserId.class)))
  186. .thenReturn(new WriteResult(1, false, null));
  187. final AccessService service = new AccessService(repository);
  188. service.addObserver(this);
  189. final boolean result = service.deleteAccount(userId, token);
  190. assertFalse(result);
  191. assertNull(event);
  192. then(repository).shouldHaveNoInteractions();
  193. }
  194. @Override
  195. public void update(Observable o, Object arg)
  196. {
  197. this.event = arg;
  198. }
  199. }