From 3f146a63e43e65e09c8f4f38e6fb2a76f239cf58 Mon Sep 17 00:00:00 2001 From: Ade Date: Thu, 26 Nov 2020 04:58:34 +0000 Subject: [PATCH 01/11] Enable Retrieval of Existing Users based on userid --- integration-tests/features/User.feature | 6 ++++++ integration-tests/features/support/payloads.js | 2 +- .../useraccountservice/services/IdentityService.java | 12 +++++++++--- .../UserAccountServiceApplicationTest.java | 4 ++-- .../services/IdentityServiceTest.java | 10 +++++----- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/integration-tests/features/User.feature b/integration-tests/features/User.feature index 9f3c300..862dd34 100644 --- a/integration-tests/features/User.feature +++ b/integration-tests/features/User.feature @@ -6,6 +6,12 @@ Feature: Features related to User Management When I make a POST to the function at '/organisations/validOrg/users' Then I should get a status code 201 And the response should be a superset of all the keys and values set from 'newUserRequest' + + @getUserFromOrg @createdUserInOrg + Scenario: GET to /users/{userId} with valid userId returns user + When I make a GET to the function at '/organisations/validOrg/users/newUser' + Then I should get a status code 200 + And the response should be a superset of all the keys and values set from 'newUserRequest' @createUserInOrg @errorHandling Scenario: POST to /users with invalid body returns bad request diff --git a/integration-tests/features/support/payloads.js b/integration-tests/features/support/payloads.js index 5caa398..2134f5d 100644 --- a/integration-tests/features/support/payloads.js +++ b/integration-tests/features/support/payloads.js @@ -17,7 +17,7 @@ module.exports.payloads = { invalidParam: "ivalidValue" }, newUserRequest: { - id: "user-identifier-for-mongo", + id: "newUser", accountVerified: false, name: "some name", profileImageLink: "https://my.image.domain.com/it.jpg" diff --git a/src/main/java/io/mathdojo/useraccountservice/services/IdentityService.java b/src/main/java/io/mathdojo/useraccountservice/services/IdentityService.java index 6774e26..a5e443d 100644 --- a/src/main/java/io/mathdojo/useraccountservice/services/IdentityService.java +++ b/src/main/java/io/mathdojo/useraccountservice/services/IdentityService.java @@ -1,5 +1,6 @@ package io.mathdojo.useraccountservice.services; +import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.logging.Level; @@ -20,6 +21,7 @@ public class IdentityService { private static final String PRECONDITIONED_UNKNOWN_USER_ID = "unknownUserId"; + private static final String PRECONDITIONED_KNOWN_USER_ID = "knownUserId"; private static final String PRECONDITIONED_UNKNOWN_ORGANISATION_ID = "unknownOrganisationId"; public static final String NEW_ENTITY_CANNOT_BE_ALREADY_VERIFIED_ERROR_MSG = "a new organisation cannot be created with a true verification status"; public static final String ORG_LESS_NEW_USER_ERROR_MSG = "a new user cannot be made without specifying a valid parent org"; @@ -122,13 +124,17 @@ private boolean isValidAccountModificationRequest(AccountRequest request) { } public User getUserInOrg(String expectedOrganisationId, String userId) { - String returnedOrgId = (getOrganisationById(expectedOrganisationId)).getId(); - if (PRECONDITIONED_UNKNOWN_USER_ID.equals(userId)) { + String returnedOrgId = (getOrganisationById(expectedOrganisationId)).getId(); + Optional userToReturn = userRepo.findById(userId); + if (PRECONDITIONED_KNOWN_USER_ID.equals(userId)){ + return new User(userId, true, "", "", expectedOrganisationId); + } + if (PRECONDITIONED_UNKNOWN_USER_ID.equals(userId) || !userToReturn.isPresent() || !returnedOrgId.equals(userToReturn.get().getBelongsToOrgWithId())) { targetExecutionContext.getLogger().log(Level.WARNING, String.format("UserId %s in Org %s could not be found", userId, expectedOrganisationId)); throw new IdentityServiceException(UNKNOWN_USERID_EXCEPTION_MSG); } - return new User(userId, false, "a name", "https://domain.com/img.png", returnedOrgId); + return userToReturn.get(); } /** diff --git a/src/test/java/io/mathdojo/useraccountservice/UserAccountServiceApplicationTest.java b/src/test/java/io/mathdojo/useraccountservice/UserAccountServiceApplicationTest.java index 11b36f5..745ec6a 100644 --- a/src/test/java/io/mathdojo/useraccountservice/UserAccountServiceApplicationTest.java +++ b/src/test/java/io/mathdojo/useraccountservice/UserAccountServiceApplicationTest.java @@ -210,7 +210,7 @@ public void testGetUserInOrgFunctionReturnsKnownUser() { when(mockExecContext.getFunctionName()).thenReturn("getUserInOrg"); String parentOrgId = "customOrgId"; - String userId = "my coolName"; + String userId = "knownUserId"; User result = (User) handlerSpy.handleRequest(mockMessage, new AccountModificationRequest(userId, parentOrgId, false, null, null), mockExecContext); @@ -313,7 +313,7 @@ public void testUpdatePermissionsThrowsNoErrorIfSuccessful() { ,UserPermission.ORG_ADMIN}; AccountModificationRequest permissionsModificationRequest = AccountModificationRequest .Builder.createBuilder() - .withAccountId("someValidUserId") + .withAccountId("knownUserId") .withParentOrgId("validOrgId") .withUserPermissions(permissionsToSet) .build(); diff --git a/src/test/java/io/mathdojo/useraccountservice/services/IdentityServiceTest.java b/src/test/java/io/mathdojo/useraccountservice/services/IdentityServiceTest.java index 87fe877..8394640 100644 --- a/src/test/java/io/mathdojo/useraccountservice/services/IdentityServiceTest.java +++ b/src/test/java/io/mathdojo/useraccountservice/services/IdentityServiceTest.java @@ -1,12 +1,12 @@ package io.mathdojo.useraccountservice.services; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import java.util.HashSet; +import java.util.Optional; import java.util.Set; import java.util.logging.Logger; @@ -57,6 +57,7 @@ public User answer(InvocationOnMock invocation) { } }); + } @Test @@ -345,12 +346,11 @@ public void throwsExceptionIfAttemptToRetrieveUnknownUserFromKnownOrg() { @Test public void updateUserWithIdReturnsResultIfOrgAndAllParamsFilledAndValid() { - String orgId = "knownOrg"; + String orgId = "aKnownOrg"; AccountRequest accountCreationRequest = new AccountRequest(false, "aName iWillChange", - "https://my.custom.domain/image-i-dont-like.png"); + "https://my.custom.domain/image-i-dont-like.png", "knownUserId"); User oldUser = organisationService.createUserInOrg(orgId, accountCreationRequest); - String newName = "aName iWillNotChange"; String newProfileImageLink = "https://my.custom.domain/image-i-like.png"; AccountRequest accountModificationRequest = new AccountRequest(true, newName, newProfileImageLink); @@ -473,7 +473,7 @@ public void throwsNoErrorIfSettingValidPermissionsForValidUserInValidOrgId() { permissionsToSet.add(UserPermission.CONSUMER); permissionsToSet.add(UserPermission.CREATOR); permissionsToSet.add(UserPermission.ORG_ADMIN); - User modifiedUser = organisationService.updateUserPermissions("knownOrganisationId", "knownUserId", + User modifiedUser = organisationService.updateUserPermissions("aKnownOrg", "knownUserId", permissionsToSet); Set modifiedUserPermissions = modifiedUser.getPermissions(); From 3509d3e2ee18c134e3666b1524c21c3eea941da1 Mon Sep 17 00:00:00 2001 From: Ade Date: Thu, 26 Nov 2020 05:21:45 +0000 Subject: [PATCH 02/11] update schema --- openapi.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openapi.yaml b/openapi.yaml index 8df12fc..566c10f 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -92,7 +92,7 @@ paths: parameters: - $ref: '#/components/parameters/organisationIdUrlParam' post: - summary: "creates a new user with a specified/randomly generated id in an organisation" + summary: "creates a new user with a specified id in an organisation" requestBody: $ref: '#/components/requestBodies/UserRequestBody' responses: @@ -331,6 +331,8 @@ components: type: string profileImageLink: type: string + id: + type: string UserPermissionsRequestBody: description: A JSON object containing the permissions to set for a user required: true From 7d7083471361f64c9d228b295a8aa4ef7b4547c3 Mon Sep 17 00:00:00 2001 From: Ade Date: Thu, 26 Nov 2020 09:02:43 +0000 Subject: [PATCH 03/11] revert schema update --- openapi.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index 566c10f..8df12fc 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -92,7 +92,7 @@ paths: parameters: - $ref: '#/components/parameters/organisationIdUrlParam' post: - summary: "creates a new user with a specified id in an organisation" + summary: "creates a new user with a specified/randomly generated id in an organisation" requestBody: $ref: '#/components/requestBodies/UserRequestBody' responses: @@ -331,8 +331,6 @@ components: type: string profileImageLink: type: string - id: - type: string UserPermissionsRequestBody: description: A JSON object containing the permissions to set for a user required: true From e759aae717fc7627ebde7c3e991cb9a5015ee9cb Mon Sep 17 00:00:00 2001 From: Ade Date: Sun, 13 Dec 2020 19:12:10 +0000 Subject: [PATCH 04/11] remove preconfigured users and update tests --- integration-tests/features/User.feature | 35 ++-- .../step_definitions/request_steps.js | 1 + .../features/support/payloads.js | 18 ++ .../services/IdentityService.java | 29 +--- .../useraccountservice/TestConfig.java | 161 ++++++++++++++++++ .../UserAccountServiceApplicationTest.java | 27 +-- .../services/IdentityServiceTest.java | 18 +- 7 files changed, 233 insertions(+), 56 deletions(-) create mode 100644 src/test/java/io/mathdojo/useraccountservice/TestConfig.java diff --git a/integration-tests/features/User.feature b/integration-tests/features/User.feature index 862dd34..1dfab97 100644 --- a/integration-tests/features/User.feature +++ b/integration-tests/features/User.feature @@ -6,12 +6,15 @@ Feature: Features related to User Management When I make a POST to the function at '/organisations/validOrg/users' Then I should get a status code 201 And the response should be a superset of all the keys and values set from 'newUserRequest' - + @getUserFromOrg @createdUserInOrg Scenario: GET to /users/{userId} with valid userId returns user - When I make a GET to the function at '/organisations/validOrg/users/newUser' + Given I generate a json payload called 'newUserRequestWithSpecificId' + And I make a POST to the function at '/organisations/validOrg/users' + And the response should be a superset of all the keys and values set from 'newUserRequestWithSpecificId' + Given I make a GET to the function at '/organisations/validOrg/users/specificId' Then I should get a status code 200 - And the response should be a superset of all the keys and values set from 'newUserRequest' + And the response should be a superset of all the keys and values set from 'newUserRequestWithSpecificId' @createUserInOrg @errorHandling Scenario: POST to /users with invalid body returns bad request @@ -21,7 +24,9 @@ Feature: Features related to User Management @getUserFromOrg Scenario: GET to /users/{userId} with valid userId returns user - When I make a GET to the function at '/organisations/validOrg/users/knownUserId' + Given I generate a json payload called 'userWithKnownId' + And I make a POST to the function at '/organisations/validOrg/users' + Given I make a GET to the function at '/organisations/validOrg/users/knownUserId' Then I should get a status code 200 And the response should contain a key 'id' with value 'knownUserId' @@ -32,8 +37,10 @@ Feature: Features related to User Management @updateUserById Scenario: PUT to /users/{userId} with pre-conditioned knownUserId and valid body returns 204 - Given I generate a json payload called 'userModificationRequest' - When I make a PUT to the function at '/organisations/knownOrgId/users/knownUserId' + Given I generate a json payload called 'userWithKnownId' + And I make a POST to the function at '/organisations/validOrg/users' + And I generate a json payload called 'userModificationRequest' + Given I make a PUT to the function at '/organisations/validOrg/users/knownUserId' Then I should get a status code 204 And the response should have no body @@ -57,7 +64,9 @@ Feature: Features related to User Management @deleteUserById Scenario: DELETE to /users/{userId} with pre-conditioned knownOrgId and valid userId returns 204 - When I make a DELETE to the function at '/organisations/knownOrgId/users/knownUserId' + Given I generate a json payload called 'userWithKnownId' + And I make a POST to the function at '/organisations/validOrg/users' + Given I make a DELETE to the function at '/organisations/validOrg/users/knownUserId' Then I should get a status code 204 @deleteUserById @errorHandling @@ -69,13 +78,15 @@ Feature: Features related to User Management Scenario: DELETE to /users/{userId} with pre-conditioned unknownUserId returns 404 When I make a DELETE to the function at '/organisations/knownOrganisationId/users/unknownUserId' Then I should get a status code 404 - + @updateUserPermissions Scenario: PUT to /permissions with pre-conditioned knownUserId and valid body returns 204 - Given I generate a json payload called 'userPermissionsModificationRequest' - When I make a PUT to the function at '/organisations/knownOrgId/users/knownUserId/permissions' - Then I should get a status code 204 - And the response should have no body + Given I generate a json payload called 'newUserToBeUpdatedRequest' + And I make a POST to the function at '/organisations/knownOrgId/users' + And I generate a json payload called 'userPermissionsModificationRequest' + Given I make a PUT to the function at '/organisations/knownOrgId/users/newUserToBeUpdated/permissions' + Then I should get a status code 204 + And the response should have no body @updateUserPermissions @errorHandling Scenario: PUT to /permissions with pre-conditioned knownOrgId and invalid body returns 400 diff --git a/integration-tests/features/step_definitions/request_steps.js b/integration-tests/features/step_definitions/request_steps.js index 7ebc386..73b540d 100644 --- a/integration-tests/features/step_definitions/request_steps.js +++ b/integration-tests/features/step_definitions/request_steps.js @@ -12,6 +12,7 @@ Given(/I generate a json payload called \'(.*)\'/, function (payloadIdentifier) } }); + When(/I make a (\w+) to the function at \'(.*)\'/, function (httpMethod, path) { this.world.response = axios.request({ url: path, diff --git a/integration-tests/features/support/payloads.js b/integration-tests/features/support/payloads.js index 2134f5d..f529675 100644 --- a/integration-tests/features/support/payloads.js +++ b/integration-tests/features/support/payloads.js @@ -22,6 +22,24 @@ module.exports.payloads = { name: "some name", profileImageLink: "https://my.image.domain.com/it.jpg" }, + newUserToBeUpdatedRequest: { + id: "newUserToBeUpdated", + accountVerified: false, + name: "some name", + profileImageLink: "https://my.image.domain.com/it.jpg" + }, + newUserRequestWithSpecificId: { + id: "specificId", + accountVerified: false, + name: "some name", + profileImageLink: "https://my.image.domain.com/it.jpg" + }, + userWithKnownId: { + id: "knownUserId", + accountVerified: false, + name: "some name", + profileImageLink: "https://my.image.domain.com/it.jpg" + }, badNewUserRequest: { accountVerified: true, name: "", diff --git a/src/main/java/io/mathdojo/useraccountservice/services/IdentityService.java b/src/main/java/io/mathdojo/useraccountservice/services/IdentityService.java index a5e443d..cf56fd7 100644 --- a/src/main/java/io/mathdojo/useraccountservice/services/IdentityService.java +++ b/src/main/java/io/mathdojo/useraccountservice/services/IdentityService.java @@ -19,9 +19,6 @@ @Service public class IdentityService { - - private static final String PRECONDITIONED_UNKNOWN_USER_ID = "unknownUserId"; - private static final String PRECONDITIONED_KNOWN_USER_ID = "knownUserId"; private static final String PRECONDITIONED_UNKNOWN_ORGANISATION_ID = "unknownOrganisationId"; public static final String NEW_ENTITY_CANNOT_BE_ALREADY_VERIFIED_ERROR_MSG = "a new organisation cannot be created with a true verification status"; public static final String ORG_LESS_NEW_USER_ERROR_MSG = "a new user cannot be made without specifying a valid parent org"; @@ -32,7 +29,7 @@ public class IdentityService { @Autowired private ExecutionContext targetExecutionContext; - @Autowired + @Autowired private MathDojoUserRepository userRepo; public String aString = "hii"; @@ -126,10 +123,7 @@ private boolean isValidAccountModificationRequest(AccountRequest request) { public User getUserInOrg(String expectedOrganisationId, String userId) { String returnedOrgId = (getOrganisationById(expectedOrganisationId)).getId(); Optional userToReturn = userRepo.findById(userId); - if (PRECONDITIONED_KNOWN_USER_ID.equals(userId)){ - return new User(userId, true, "", "", expectedOrganisationId); - } - if (PRECONDITIONED_UNKNOWN_USER_ID.equals(userId) || !userToReturn.isPresent() || !returnedOrgId.equals(userToReturn.get().getBelongsToOrgWithId())) { + if (!userToReturn.isPresent() || !returnedOrgId.equals(userToReturn.get().getBelongsToOrgWithId())) { targetExecutionContext.getLogger().log(Level.WARNING, String.format("UserId %s in Org %s could not be found", userId, expectedOrganisationId)); throw new IdentityServiceException(UNKNOWN_USERID_EXCEPTION_MSG); @@ -147,11 +141,6 @@ public User getUserInOrg(String expectedOrganisationId, String userId) { */ public User updateUserWithId(String orgId, String userId, AccountRequest accountModificationRequest) { String returnedOrgId = (getOrganisationById(orgId)).getId(); - if (PRECONDITIONED_UNKNOWN_USER_ID.equals(userId)) { - targetExecutionContext.getLogger().log(Level.WARNING, - String.format("UserId %s in Org %s could not be found", userId, orgId)); - throw new IdentityServiceException(UNKNOWN_USERID_EXCEPTION_MSG); - } if (!isValidAccountModificationRequest(accountModificationRequest)) { String errorMessage = "One or more of the properties to update for the user are incorrect."; @@ -170,16 +159,13 @@ public User updateUserWithId(String orgId, String userId, AccountRequest account boolean verificationStatusToUpdate = (!foundUser.isAccountVerified() && accountModificationRequest.isAccountVerified()) ? accountModificationRequest.isAccountVerified() : foundUser.isAccountVerified(); - return new User(userId, verificationStatusToUpdate, nameToUpdate, profileToUpdate, returnedOrgId); + return userRepo.save(new User(userId, verificationStatusToUpdate, nameToUpdate, profileToUpdate, returnedOrgId)); } public void deleteUserFromOrg(String orgId, String userId) { - String returnedOrgId = (getOrganisationById(orgId)).getId(); - if (PRECONDITIONED_UNKNOWN_USER_ID.equals(userId)) { - targetExecutionContext.getLogger().log(Level.WARNING, - String.format("UserId %s in Org %s could not be found", userId, orgId)); - throw new IdentityServiceException(UNKNOWN_USERID_EXCEPTION_MSG); - } + User retrievedUser = getUserInOrg(orgId, userId); + userRepo.delete(retrievedUser); + } public User updateUserPermissions(String orgId, String userId, final Set permissions) { @@ -188,11 +174,10 @@ public User updateUserPermissions(String orgId, String userId, final Set 1)) { throw new IdentityServiceException("A user can only hold global-admin privileges exclusive of all others."); } - User retrievedUser = getUserInOrg(orgId, userId); retrievedUser.setPermissions(permissions); - return retrievedUser; + return userRepo.save(retrievedUser); } @Override diff --git a/src/test/java/io/mathdojo/useraccountservice/TestConfig.java b/src/test/java/io/mathdojo/useraccountservice/TestConfig.java new file mode 100644 index 0000000..8bf82f1 --- /dev/null +++ b/src/test/java/io/mathdojo/useraccountservice/TestConfig.java @@ -0,0 +1,161 @@ +package io.mathdojo.useraccountservice; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; + +import io.mathdojo.useraccountservice.model.User; + +/** + * + * Used for injecting mock mongodb repository beans into spring application context when + * testing with @RunWith(SpringRunner.class) + * + */ +@TestConfiguration +public class TestConfig { + Map createdUsers = new HashMap<>(); + + @Bean + MathDojoUserRepository userRepo() { + // configured known user + createdUsers.put("aKnownUser", new User("aKnownUser", false, "", "", "aKnownOrg")); + MathDojoUserRepository userRepo = new MathDojoUserRepository() { + + @Override + public Optional findOne(Example example) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Page findAll(Example example, Pageable pageable) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean exists(Example example) { + // TODO Auto-generated method stub + return false; + } + + @Override + public long count(Example example) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public S save(S entity) { + createdUsers.put(entity.getId(), entity); + return entity; + } + + @Override + public Optional findById(String id) { + return Optional.of(createdUsers.get(id)); + } + + @Override + public Iterable findAllById(Iterable ids) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean existsById(String id) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void deleteById(String id) { + // TODO Auto-generated method stub + + } + + @Override + public void deleteAll(Iterable entities) { + // TODO Auto-generated method stub + + } + + @Override + public void deleteAll() { + // TODO Auto-generated method stub + + } + + @Override + public void delete(User entity) { + // Do nothing for now + + } + + @Override + public long count() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public Page findAll(Pageable pageable) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List saveAll(Iterable entities) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List insert(Iterable entities) { + // TODO Auto-generated method stub + return null; + } + + @Override + public S insert(S entity) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List findAll(Example example, Sort sort) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List findAll(Example example) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List findAll(Sort sort) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List findAll() { + // TODO Auto-generated method stub + return null; + } + }; + return userRepo; + } + +} diff --git a/src/test/java/io/mathdojo/useraccountservice/UserAccountServiceApplicationTest.java b/src/test/java/io/mathdojo/useraccountservice/UserAccountServiceApplicationTest.java index 745ec6a..a276e4d 100644 --- a/src/test/java/io/mathdojo/useraccountservice/UserAccountServiceApplicationTest.java +++ b/src/test/java/io/mathdojo/useraccountservice/UserAccountServiceApplicationTest.java @@ -7,19 +7,18 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.util.HashSet; -import java.util.Set; import java.util.logging.Logger; -import com.microsoft.azure.functions.ExecutionContext; -import com.microsoft.azure.functions.HttpRequestMessage; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; +import com.microsoft.azure.functions.ExecutionContext; +import com.microsoft.azure.functions.HttpRequestMessage; + import io.mathdojo.useraccountservice.model.DummyUser; import io.mathdojo.useraccountservice.model.Greeting; import io.mathdojo.useraccountservice.model.Organisation; @@ -33,6 +32,8 @@ import io.mathdojo.useraccountservice.services.SystemService; @RunWith(SpringRunner.class) +@ContextConfiguration(classes = TestConfig.class) +@SuppressWarnings({"rawtypes","unchecked"}) public class UserAccountServiceApplicationTest { private ExecutionContext mockExecContext; @@ -209,8 +210,8 @@ public void testGetUserInOrgFunctionReturnsKnownUser() { Mockito.doReturn(mockSystemService).when(handlerSpy).getSystemService(); when(mockExecContext.getFunctionName()).thenReturn("getUserInOrg"); - String parentOrgId = "customOrgId"; - String userId = "knownUserId"; + String parentOrgId = "aKnownOrg"; + String userId = "aKnownUser"; User result = (User) handlerSpy.handleRequest(mockMessage, new AccountModificationRequest(userId, parentOrgId, false, null, null), mockExecContext); @@ -232,11 +233,11 @@ public void testUpdateUserInOrgFunctionReturnsKnownUser() { Mockito.doReturn(mockSystemService).when(createUserHandlerSpy).getSystemService(); when(mockExecContext.getFunctionName()).thenReturn("createUserInOrg"); - String parentOrgId = "customOrgId"; + String parentOrgId = "aKnownOrg"; String name = "My Name"; String imageLink = "https://superdomain.com/cool.img"; User result = (User) createUserHandlerSpy.handleRequest(mockMessage, - new AccountModificationRequest(null, parentOrgId, false, name, imageLink), + new AccountModificationRequest("aKnownUser", parentOrgId, false, name, imageLink), mockExecContext); createUserHandlerSpy.close(); assertThat(result.getBelongsToOrgWithId()).isEqualTo(parentOrgId); @@ -274,8 +275,8 @@ public void testDeleteUserThrowsNoErrorIfSuccessful() { UserAccountServiceApplication.class); HTTPRequestSignatureVerificationEnabledHandler handlerSpy = Mockito.spy(handler); Mockito.doReturn(mockSystemService).when(handlerSpy).getSystemService(); - AccountModificationRequest accountDeletionRequest = new AccountModificationRequest("someUserId", - "someOrgId",false, null, null); + AccountModificationRequest accountDeletionRequest = new AccountModificationRequest("aKnownUser", + "aKnownOrg",false, null, null); when(mockExecContext.getFunctionName()).thenReturn("deleteUserFromOrg"); assertDoesNotThrow(() -> { handlerSpy.handleRequest(mockMessage, accountDeletionRequest, mockExecContext); @@ -313,8 +314,8 @@ public void testUpdatePermissionsThrowsNoErrorIfSuccessful() { ,UserPermission.ORG_ADMIN}; AccountModificationRequest permissionsModificationRequest = AccountModificationRequest .Builder.createBuilder() - .withAccountId("knownUserId") - .withParentOrgId("validOrgId") + .withAccountId("aKnownUser") + .withParentOrgId("aKnownOrg") .withUserPermissions(permissionsToSet) .build(); when(mockExecContext.getFunctionName()).thenReturn("updateUserPermissions"); diff --git a/src/test/java/io/mathdojo/useraccountservice/services/IdentityServiceTest.java b/src/test/java/io/mathdojo/useraccountservice/services/IdentityServiceTest.java index 8394640..b17c574 100644 --- a/src/test/java/io/mathdojo/useraccountservice/services/IdentityServiceTest.java +++ b/src/test/java/io/mathdojo/useraccountservice/services/IdentityServiceTest.java @@ -41,14 +41,17 @@ public class IdentityServiceTest { private MathDojoUserRepository userRepo; @InjectMocks - private IdentityService organisationService = new IdentityService(); + private IdentityService organisationService; private String PRECONDITIONED_UNKNOWN_ORG_ID = "unknownOrganisationId"; private String PRECONDITIONED_UNKNOWN_USER_ID = "unknownUserId"; + private String PRECONDITIONED_KNOWN_USER_ID = "aKnownUser"; + private String PRECONDITIONED_KNOWN_ORG_ID = "aKnownOrg"; @Before public void setUp() { + Logger testLogger = mock(Logger.class); Mockito.when(targetExecutionContext.getLogger()).thenReturn(testLogger); Mockito.when(userRepo.save(Mockito.any(User.class))).thenAnswer(new Answer() { @@ -56,7 +59,7 @@ public User answer(InvocationOnMock invocation) { return (User) invocation.getArguments()[0]; } }); - + Mockito.when(userRepo.findById(PRECONDITIONED_KNOWN_USER_ID)).thenReturn(Optional.of(new User(PRECONDITIONED_KNOWN_USER_ID, false, "", "", PRECONDITIONED_KNOWN_ORG_ID))); } @@ -304,12 +307,9 @@ public void throwErrorIfAttemptToCreateUserWithNullName() { @Test public void returnsUserWithMatchingIdIfPossibleToFindInOrg() { - String expectedOrganisationId = "aKnownOrg"; - String userId = "knownUserId"; - + String userId = "aKnownUser"; User createdUser = organisationService.getUserInOrg(expectedOrganisationId, userId); - assertEquals(expectedOrganisationId, createdUser.getBelongsToOrgWithId()); } @@ -349,7 +349,7 @@ public void updateUserWithIdReturnsResultIfOrgAndAllParamsFilledAndValid() { String orgId = "aKnownOrg"; AccountRequest accountCreationRequest = new AccountRequest(false, "aName iWillChange", - "https://my.custom.domain/image-i-dont-like.png", "knownUserId"); + "https://my.custom.domain/image-i-dont-like.png", "aKnownUser"); User oldUser = organisationService.createUserInOrg(orgId, accountCreationRequest); String newName = "aName iWillNotChange"; String newProfileImageLink = "https://my.custom.domain/image-i-like.png"; @@ -444,7 +444,7 @@ public void throwsErrorIfAttemptToUpdateValidUserWithNullParams() { @Test public void throwsNoErrorIfDeletingForValidUserInValidOrgId() { - organisationService.deleteUserFromOrg("knownOrganisationId", "knownUserId"); + organisationService.deleteUserFromOrg("aKnownOrg", "aKnownUser"); } @Test @@ -473,7 +473,7 @@ public void throwsNoErrorIfSettingValidPermissionsForValidUserInValidOrgId() { permissionsToSet.add(UserPermission.CONSUMER); permissionsToSet.add(UserPermission.CREATOR); permissionsToSet.add(UserPermission.ORG_ADMIN); - User modifiedUser = organisationService.updateUserPermissions("aKnownOrg", "knownUserId", + User modifiedUser = organisationService.updateUserPermissions("aKnownOrg", "aKnownUser", permissionsToSet); Set modifiedUserPermissions = modifiedUser.getPermissions(); From 245ad0e207caa2b76893c232279c0ffbba445a37 Mon Sep 17 00:00:00 2001 From: Ade Date: Sun, 13 Dec 2020 19:55:45 +0000 Subject: [PATCH 05/11] test update --- integration-tests/features/User.feature | 8 -------- 1 file changed, 8 deletions(-) diff --git a/integration-tests/features/User.feature b/integration-tests/features/User.feature index 1dfab97..f688c71 100644 --- a/integration-tests/features/User.feature +++ b/integration-tests/features/User.feature @@ -22,14 +22,6 @@ Feature: Features related to User Management When I make a POST to the function at '/organisations/validOrg/users' Then I should get a status code 400 - @getUserFromOrg - Scenario: GET to /users/{userId} with valid userId returns user - Given I generate a json payload called 'userWithKnownId' - And I make a POST to the function at '/organisations/validOrg/users' - Given I make a GET to the function at '/organisations/validOrg/users/knownUserId' - Then I should get a status code 200 - And the response should contain a key 'id' with value 'knownUserId' - @getUserFromOrg @errorHandling Scenario: GET to /users/{userId} with invalid userId returns 404 When I make a GET to the function at '/organisations/validOrg/users/unknownUserId' From 92eb73da2366d6ef839c18bcaedfa617f0f0b1d8 Mon Sep 17 00:00:00 2001 From: Ade Date: Thu, 17 Dec 2020 23:16:40 +0000 Subject: [PATCH 06/11] test update --- integration-tests/features/User.feature | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/integration-tests/features/User.feature b/integration-tests/features/User.feature index f688c71..f1667f0 100644 --- a/integration-tests/features/User.feature +++ b/integration-tests/features/User.feature @@ -11,8 +11,7 @@ Feature: Features related to User Management Scenario: GET to /users/{userId} with valid userId returns user Given I generate a json payload called 'newUserRequestWithSpecificId' And I make a POST to the function at '/organisations/validOrg/users' - And the response should be a superset of all the keys and values set from 'newUserRequestWithSpecificId' - Given I make a GET to the function at '/organisations/validOrg/users/specificId' + When I make a GET to the function at '/organisations/validOrg/users/specificId' Then I should get a status code 200 And the response should be a superset of all the keys and values set from 'newUserRequestWithSpecificId' @@ -31,8 +30,8 @@ Feature: Features related to User Management Scenario: PUT to /users/{userId} with pre-conditioned knownUserId and valid body returns 204 Given I generate a json payload called 'userWithKnownId' And I make a POST to the function at '/organisations/validOrg/users' - And I generate a json payload called 'userModificationRequest' - Given I make a PUT to the function at '/organisations/validOrg/users/knownUserId' + Given I generate a json payload called 'userModificationRequest' + When I make a PUT to the function at '/organisations/validOrg/users/knownUserId' Then I should get a status code 204 And the response should have no body @@ -75,8 +74,8 @@ Feature: Features related to User Management Scenario: PUT to /permissions with pre-conditioned knownUserId and valid body returns 204 Given I generate a json payload called 'newUserToBeUpdatedRequest' And I make a POST to the function at '/organisations/knownOrgId/users' - And I generate a json payload called 'userPermissionsModificationRequest' - Given I make a PUT to the function at '/organisations/knownOrgId/users/newUserToBeUpdated/permissions' + Given I generate a json payload called 'userPermissionsModificationRequest' + When I make a PUT to the function at '/organisations/knownOrgId/users/newUserToBeUpdated/permissions' Then I should get a status code 204 And the response should have no body From 5be7a9279f91ed806f272ec1255122f412e4bb16 Mon Sep 17 00:00:00 2001 From: Ade Date: Fri, 18 Dec 2020 20:02:40 +0000 Subject: [PATCH 07/11] add backcround step for pre-configured user --- integration-tests/features/User.feature | 24 ++++++++----------- .../features/support/payloads.js | 12 ---------- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/integration-tests/features/User.feature b/integration-tests/features/User.feature index f1667f0..7184a40 100644 --- a/integration-tests/features/User.feature +++ b/integration-tests/features/User.feature @@ -1,5 +1,9 @@ Feature: Features related to User Management - + Background: Create pre-configured user + Given I generate a json payload called 'userWithKnownId' + And I make a POST to the function at '/organisations/validOrg/users' + + @createUserInOrg Scenario: POST to /users with valid body returns created user Given I generate a json payload called 'newUserRequest' @@ -7,13 +11,11 @@ Feature: Features related to User Management Then I should get a status code 201 And the response should be a superset of all the keys and values set from 'newUserRequest' - @getUserFromOrg @createdUserInOrg + @getUserFromOrg Scenario: GET to /users/{userId} with valid userId returns user - Given I generate a json payload called 'newUserRequestWithSpecificId' - And I make a POST to the function at '/organisations/validOrg/users' - When I make a GET to the function at '/organisations/validOrg/users/specificId' + When I make a GET to the function at '/organisations/validOrg/users/knownUserId' Then I should get a status code 200 - And the response should be a superset of all the keys and values set from 'newUserRequestWithSpecificId' + And the response should be a superset of all the keys and values set from 'userWithKnownId' @createUserInOrg @errorHandling Scenario: POST to /users with invalid body returns bad request @@ -28,8 +30,6 @@ Feature: Features related to User Management @updateUserById Scenario: PUT to /users/{userId} with pre-conditioned knownUserId and valid body returns 204 - Given I generate a json payload called 'userWithKnownId' - And I make a POST to the function at '/organisations/validOrg/users' Given I generate a json payload called 'userModificationRequest' When I make a PUT to the function at '/organisations/validOrg/users/knownUserId' Then I should get a status code 204 @@ -55,8 +55,6 @@ Feature: Features related to User Management @deleteUserById Scenario: DELETE to /users/{userId} with pre-conditioned knownOrgId and valid userId returns 204 - Given I generate a json payload called 'userWithKnownId' - And I make a POST to the function at '/organisations/validOrg/users' Given I make a DELETE to the function at '/organisations/validOrg/users/knownUserId' Then I should get a status code 204 @@ -71,11 +69,9 @@ Feature: Features related to User Management Then I should get a status code 404 @updateUserPermissions - Scenario: PUT to /permissions with pre-conditioned knownUserId and valid body returns 204 - Given I generate a json payload called 'newUserToBeUpdatedRequest' - And I make a POST to the function at '/organisations/knownOrgId/users' + Scenario: PUT to /permissions with pre-conditioned knownUserId and valid body returns 204 Given I generate a json payload called 'userPermissionsModificationRequest' - When I make a PUT to the function at '/organisations/knownOrgId/users/newUserToBeUpdated/permissions' + When I make a PUT to the function at '/organisations/validOrg/users/knownUserId/permissions' Then I should get a status code 204 And the response should have no body diff --git a/integration-tests/features/support/payloads.js b/integration-tests/features/support/payloads.js index f529675..12adc77 100644 --- a/integration-tests/features/support/payloads.js +++ b/integration-tests/features/support/payloads.js @@ -21,18 +21,6 @@ module.exports.payloads = { accountVerified: false, name: "some name", profileImageLink: "https://my.image.domain.com/it.jpg" - }, - newUserToBeUpdatedRequest: { - id: "newUserToBeUpdated", - accountVerified: false, - name: "some name", - profileImageLink: "https://my.image.domain.com/it.jpg" - }, - newUserRequestWithSpecificId: { - id: "specificId", - accountVerified: false, - name: "some name", - profileImageLink: "https://my.image.domain.com/it.jpg" }, userWithKnownId: { id: "knownUserId", From 90445c8428f7b6b3ff929aa44dd17b9a31bf48cd Mon Sep 17 00:00:00 2001 From: Ade Date: Tue, 22 Dec 2020 14:15:39 +0000 Subject: [PATCH 08/11] add timeout to integration tests before http request --- integration-tests/features/step_definitions/request_steps.js | 1 + 1 file changed, 1 insertion(+) diff --git a/integration-tests/features/step_definitions/request_steps.js b/integration-tests/features/step_definitions/request_steps.js index 73b540d..92005f0 100644 --- a/integration-tests/features/step_definitions/request_steps.js +++ b/integration-tests/features/step_definitions/request_steps.js @@ -14,6 +14,7 @@ Given(/I generate a json payload called \'(.*)\'/, function (payloadIdentifier) When(/I make a (\w+) to the function at \'(.*)\'/, function (httpMethod, path) { + timeout: 100 this.world.response = axios.request({ url: path, baseURL: this.world.getFunctionBaseUri(), From 33739e751bf23e37ae0b13d61d02a841d2192d19 Mon Sep 17 00:00:00 2001 From: Ade Date: Tue, 22 Dec 2020 14:19:30 +0000 Subject: [PATCH 09/11] fix timeout to integration tests --- integration-tests/features/step_definitions/request_steps.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/integration-tests/features/step_definitions/request_steps.js b/integration-tests/features/step_definitions/request_steps.js index 92005f0..ae66133 100644 --- a/integration-tests/features/step_definitions/request_steps.js +++ b/integration-tests/features/step_definitions/request_steps.js @@ -13,8 +13,9 @@ Given(/I generate a json payload called \'(.*)\'/, function (payloadIdentifier) }); -When(/I make a (\w+) to the function at \'(.*)\'/, function (httpMethod, path) { - timeout: 100 +When(/I make a (\w+) to the function at \'(.*)\'/,{ + timeout: 100 +}, function (httpMethod, path) { this.world.response = axios.request({ url: path, baseURL: this.world.getFunctionBaseUri(), From cc8727df0dacbaf3833776026c5200a039e0089b Mon Sep 17 00:00:00 2001 From: Ade Date: Tue, 22 Dec 2020 18:08:48 +0000 Subject: [PATCH 10/11] fix merge conflicts with develop --- .../useraccountservice/UserAccountServiceApplicationTest.java | 1 + .../useraccountservice/services/IdentityServiceTest.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/io/mathdojo/useraccountservice/UserAccountServiceApplicationTest.java b/src/test/java/io/mathdojo/useraccountservice/UserAccountServiceApplicationTest.java index 6987589..9375f7e 100644 --- a/src/test/java/io/mathdojo/useraccountservice/UserAccountServiceApplicationTest.java +++ b/src/test/java/io/mathdojo/useraccountservice/UserAccountServiceApplicationTest.java @@ -17,6 +17,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mockito; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import com.microsoft.azure.functions.ExecutionContext; diff --git a/src/test/java/io/mathdojo/useraccountservice/services/IdentityServiceTest.java b/src/test/java/io/mathdojo/useraccountservice/services/IdentityServiceTest.java index c532245..d05881e 100644 --- a/src/test/java/io/mathdojo/useraccountservice/services/IdentityServiceTest.java +++ b/src/test/java/io/mathdojo/useraccountservice/services/IdentityServiceTest.java @@ -59,7 +59,7 @@ public User answer(InvocationOnMock invocation) { return (User) invocation.getArguments()[0]; } }); - Mockito.when(userRepo.findById(PRECONDITIONED_KNOWN_USER_ID)).thenReturn(Optional.of(new User(PRECONDITIONED_KNOWN_USER_ID, false, "", "", PRECONDITIONED_KNOWN_ORG_ID))); + Mockito.lenient().when(userRepo.findById(PRECONDITIONED_KNOWN_USER_ID)).thenReturn(Optional.of(new User(PRECONDITIONED_KNOWN_USER_ID, false, "", "", PRECONDITIONED_KNOWN_ORG_ID))); } From a3fe66dadeb98645f31f7ff1edf4091fde23ef40 Mon Sep 17 00:00:00 2001 From: Ade Date: Tue, 22 Dec 2020 21:31:25 +0000 Subject: [PATCH 11/11] remove timeout --- integration-tests/features/step_definitions/request_steps.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/integration-tests/features/step_definitions/request_steps.js b/integration-tests/features/step_definitions/request_steps.js index ae66133..7ebc386 100644 --- a/integration-tests/features/step_definitions/request_steps.js +++ b/integration-tests/features/step_definitions/request_steps.js @@ -12,10 +12,7 @@ Given(/I generate a json payload called \'(.*)\'/, function (payloadIdentifier) } }); - -When(/I make a (\w+) to the function at \'(.*)\'/,{ - timeout: 100 -}, function (httpMethod, path) { +When(/I make a (\w+) to the function at \'(.*)\'/, function (httpMethod, path) { this.world.response = axios.request({ url: path, baseURL: this.world.getFunctionBaseUri(),