diff --git a/backend/pom.xml b/backend/pom.xml index 85d8c2f765..bccc6830f2 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -99,12 +99,16 @@ 0.8.8 - ch/puzzle/okr/service/persistence/OverviewPersistenceService* ch/puzzle/okr/models/** ch/puzzle/okr/dto/** ch/puzzle/okr/mapper/** - **/OkrApplication.* + ch/puzzle/okr/OkrApplication.* + ch/puzzle/okr/Constants.java + ch/puzzle/okr/ErrorKey.java ch/puzzle/okr/SecurityConfig.java + ch/puzzle/okr/SpringCachingConfig.java + ch/puzzle/okr/OkrErrorAttributes.java + ch/puzzle/okr/OpenAPI30Configuration.java diff --git a/backend/src/main/java/ch/puzzle/okr/service/authorization/AuthorizationServiceBase.java b/backend/src/main/java/ch/puzzle/okr/service/authorization/AuthorizationServiceBase.java index 2bdffd6aaf..a2c4bc366e 100644 --- a/backend/src/main/java/ch/puzzle/okr/service/authorization/AuthorizationServiceBase.java +++ b/backend/src/main/java/ch/puzzle/okr/service/authorization/AuthorizationServiceBase.java @@ -16,7 +16,7 @@ public abstract class AuthorizationServiceBase businessService; private final AuthorizationService authorizationService; - public AuthorizationServiceBase(BusinessServiceInterface businessService, + protected AuthorizationServiceBase(BusinessServiceInterface businessService, AuthorizationService authorizationService) { this.businessService = businessService; this.authorizationService = authorizationService; diff --git a/backend/src/main/java/ch/puzzle/okr/service/business/TeamBusinessService.java b/backend/src/main/java/ch/puzzle/okr/service/business/TeamBusinessService.java index 8367c6cda7..d8603ccf22 100644 --- a/backend/src/main/java/ch/puzzle/okr/service/business/TeamBusinessService.java +++ b/backend/src/main/java/ch/puzzle/okr/service/business/TeamBusinessService.java @@ -23,8 +23,8 @@ public class TeamBusinessService { private final CacheService cacheService; public TeamBusinessService(TeamPersistenceService teamPersistenceService, - ObjectiveBusinessService objectiveBusinessService, QuarterBusinessService quarterBusinessService, - TeamValidationService validator, CacheService cacheService) { + ObjectiveBusinessService objectiveBusinessService, TeamValidationService validator, + CacheService cacheService) { this.teamPersistenceService = teamPersistenceService; this.objectiveBusinessService = objectiveBusinessService; this.validator = validator; diff --git a/backend/src/test/java/ch/puzzle/okr/controller/ObjectiveControllerIT.java b/backend/src/test/java/ch/puzzle/okr/controller/ObjectiveControllerIT.java index f95680f5c8..5735d99ffa 100644 --- a/backend/src/test/java/ch/puzzle/okr/controller/ObjectiveControllerIT.java +++ b/backend/src/test/java/ch/puzzle/okr/controller/ObjectiveControllerIT.java @@ -5,7 +5,6 @@ import ch.puzzle.okr.models.*; import ch.puzzle.okr.service.authorization.AuthorizationService; import ch.puzzle.okr.service.authorization.ObjectiveAuthorizationService; -import ch.puzzle.okr.service.business.ObjectiveBusinessService; import org.hamcrest.core.Is; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -66,7 +65,7 @@ class ObjectiveControllerIT { """; private static final String RESPONSE_NEW_OBJECTIVE = """ {"id":null,"version":1,"title":"Program Faster","teamId":1,"quarterId":1,"description":"Just be faster","state":"DRAFT","createdOn":null,"modifiedOn":null,"writeable":true}"""; - + private static final String JSON_PATH_TITLE = "$.title"; private static final Objective objective1 = Objective.Builder.builder().withId(5L).withTitle(OBJECTIVE_TITLE_1) .build(); private static final Objective objective2 = Objective.Builder.builder().withId(7L).withTitle(OBJECTIVE_TITLE_2) @@ -88,8 +87,6 @@ class ObjectiveControllerIT { @MockBean private ObjectiveAuthorizationService objectiveAuthorizationService; @Mock - private ObjectiveBusinessService objectiveBusinessService; - @Mock private AuthorizationService authorizationService; @MockBean private ObjectiveMapper objectiveMapper; @@ -106,7 +103,7 @@ void getObjectiveById() throws Exception { mvc.perform(get(URL_OBJECTIVE_5).contentType(MediaType.APPLICATION_JSON)) .andExpect(MockMvcResultMatchers.status().isOk()).andExpect(jsonPath("$.id", Is.is(5))) - .andExpect(jsonPath("$.title", Is.is(OBJECTIVE_TITLE_1))); + .andExpect(jsonPath(JSON_PATH_TITLE, Is.is(OBJECTIVE_TITLE_1))); } @Test @@ -158,7 +155,7 @@ void shouldReturnUpdatedObjective() throws Exception { .with(SecurityMockMvcRequestPostProcessors.csrf())).andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(jsonPath("$.id", Is.is(1))) .andExpect(jsonPath("$.description", Is.is(EVERYTHING_FINE_DESCRIPTION))) - .andExpect(jsonPath("$.title", Is.is(TITLE))); + .andExpect(jsonPath(JSON_PATH_TITLE, Is.is(TITLE))); } @Test @@ -224,7 +221,7 @@ void shouldReturnIsCreatedWhenObjectiveWasDuplicated() throws Exception { .andExpect(MockMvcResultMatchers.status().isCreated()) .andExpect(jsonPath("$.id", Is.is(objective1Dto.id().intValue()))) .andExpect(jsonPath("$.description", Is.is(objective1Dto.description()))) - .andExpect(jsonPath("$.title", Is.is(objective1Dto.title()))); + .andExpect(jsonPath(JSON_PATH_TITLE, Is.is(objective1Dto.title()))); verify(objectiveMapper, times(1)).toObjective(any()); verify(objectiveMapper, times(1)).toDto(any()); diff --git a/backend/src/test/java/ch/puzzle/okr/controller/OverviewControllerIT.java b/backend/src/test/java/ch/puzzle/okr/controller/OverviewControllerIT.java index 22298578d3..2fce6de9ec 100644 --- a/backend/src/test/java/ch/puzzle/okr/controller/OverviewControllerIT.java +++ b/backend/src/test/java/ch/puzzle/okr/controller/OverviewControllerIT.java @@ -43,6 +43,7 @@ class OverviewControllerIT { private OverviewAuthorizationService overviewAuthorizationService; @MockBean OrganisationBusinessService organisationBusinessService; + // Dashboard and OverviewMapper are required for testing @SpyBean private DashboardMapper dashboardMapper; @SpyBean @@ -55,6 +56,7 @@ class OverviewControllerIT { public static final String CHF = "CHF"; public static final String JSON_PATH_TEAM_NAME = "$.overviews[0].team.name"; public static final String JSON_PATH_TEAM_ID = "$.overviews[0].team.id"; + public static final String JSON_PATH_OVERVIEWS = "$.overviews"; static List overviewPuzzle = List.of( Overview.Builder.builder().withOverviewId(OverviewId.of(1L, 1L, 20L, 20L)).withTeamName(PUZZLE) @@ -100,7 +102,7 @@ void shouldGetAllTeamsWithObjective() throws Exception { mvc.perform(get("/api/v2/overview?quarter=2&team=1,2,3,4").contentType(MediaType.APPLICATION_JSON)) .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(jsonPath("$.overviews", Matchers.hasSize(3))) + .andExpect(jsonPath(JSON_PATH_OVERVIEWS, Matchers.hasSize(3))) .andExpect(jsonPath("$.adminAccess", Is.is(true))).andExpect(jsonPath(JSON_PATH_TEAM_ID, Is.is(1))) .andExpect(jsonPath(JSON_PATH_TEAM_NAME, Is.is(PUZZLE))) .andExpect(jsonPath("$.overviews[0].objectives[0].id", Is.is(1))) @@ -122,7 +124,7 @@ void shouldGetAllTeamsWithObjectiveIfNoTeamsExists() throws Exception { mvc.perform(get("/api/v2/overview").contentType(MediaType.APPLICATION_JSON)) .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(jsonPath("$.overviews", Matchers.hasSize(0))) + .andExpect(jsonPath(JSON_PATH_OVERVIEWS, Matchers.hasSize(0))) .andExpect(jsonPath("$.adminAccess", Is.is(true))); } @@ -135,7 +137,7 @@ void shouldReturnOnlyFilteredObjectivesByQuarterAndTeam() throws Exception { mvc.perform(get("/api/v2/overview?quarter=2&team=1,3").contentType(MediaType.APPLICATION_JSON)) .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(jsonPath("$.overviews", Matchers.hasSize(2))) + .andExpect(jsonPath(JSON_PATH_OVERVIEWS, Matchers.hasSize(2))) .andExpect(jsonPath(JSON_PATH_TEAM_ID, Is.is(1))) .andExpect(jsonPath(JSON_PATH_TEAM_NAME, Is.is(PUZZLE))) .andExpect(jsonPath("$.overviews[0].objectives[0].id", Is.is(1))) @@ -152,7 +154,7 @@ void shouldReturnTeamWithEmptyObjectiveListWhenNoObjectiveInFilteredQuarter() th mvc.perform(get("/api/v2/overview?quarter=2&team=4").contentType(MediaType.APPLICATION_JSON)) .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(jsonPath("$.overviews", Matchers.hasSize(1))) + .andExpect(jsonPath(JSON_PATH_OVERVIEWS, Matchers.hasSize(1))) .andExpect(jsonPath(JSON_PATH_TEAM_ID, Is.is(4))) .andExpect(jsonPath(JSON_PATH_TEAM_NAME, Is.is(TEAM_KUCHEN))) .andExpect(jsonPath("$.overviews[0].objectives.size()", Is.is(0))); diff --git a/backend/src/test/java/ch/puzzle/okr/service/authorization/AuthorizationRegistrationServiceIT.java b/backend/src/test/java/ch/puzzle/okr/service/authorization/AuthorizationRegistrationServiceIT.java index 32738d60ef..4a15a317a7 100644 --- a/backend/src/test/java/ch/puzzle/okr/service/authorization/AuthorizationRegistrationServiceIT.java +++ b/backend/src/test/java/ch/puzzle/okr/service/authorization/AuthorizationRegistrationServiceIT.java @@ -91,10 +91,11 @@ void registerAuthorizationUserShouldSetTeamOrganisations() { @Test void registerAuthorizationUserShouldSetChampions() { - User user = User.Builder.builder().withFirstname("firstname").withLastname("lastname").withUsername("peggimann") - .withEmail("mail@puzzle.ch").build(); - Jwt token = mockJwtToken(user, List.of(ORGANISATION_FIRST_LEVEL, ORGANISATION_SECOND_LEVEL)); - AuthorizationUser authorizationUser = authorizationRegistrationService.registerAuthorizationUser(user, token); + User testUser = User.Builder.builder().withFirstname("firstname").withLastname("lastname") + .withUsername("peggimann").withEmail("mail@puzzle.ch").build(); + Jwt token = mockJwtToken(testUser, List.of(ORGANISATION_FIRST_LEVEL, ORGANISATION_SECOND_LEVEL)); + AuthorizationUser authorizationUser = authorizationRegistrationService.registerAuthorizationUser(testUser, + token); assertRoles(List.of(READ_ALL_DRAFT, READ_ALL_PUBLISHED, WRITE_ALL), authorizationUser); } diff --git a/backend/src/test/java/ch/puzzle/okr/service/persistence/ActionPersistenceServiceIT.java b/backend/src/test/java/ch/puzzle/okr/service/persistence/ActionPersistenceServiceIT.java index c8a1bdd35a..f9b26ace95 100644 --- a/backend/src/test/java/ch/puzzle/okr/service/persistence/ActionPersistenceServiceIT.java +++ b/backend/src/test/java/ch/puzzle/okr/service/persistence/ActionPersistenceServiceIT.java @@ -36,6 +36,8 @@ private static Action createAction(Long id, int version) { .build(); } + private static final String UPDATED_ACTION = "Updated Action"; + @AfterEach void tearDown() { try { @@ -67,13 +69,13 @@ void saveActionShouldSaveNewAction() { void updateActionShouldUpdateAction() { Action action = createAction(null); createdAction = actionPersistenceService.save(action); - createdAction.setAction("Updated Action"); + createdAction.setAction(UPDATED_ACTION); createdAction.setPriority(4); Action updateAction = actionPersistenceService.save(createdAction); assertEquals(createdAction.getId(), updateAction.getId()); - assertEquals("Updated Action", updateAction.getAction()); + assertEquals(UPDATED_ACTION, updateAction.getAction()); assertEquals(4, updateAction.getPriority()); } @@ -81,7 +83,7 @@ void updateActionShouldUpdateAction() { void updateActionShouldThrowExceptionWhenAlreadyUpdated() { createdAction = actionPersistenceService.save(createAction(null)); Action changedAction = createAction(createdAction.getId(), 0); - changedAction.setAction("Updated Action"); + changedAction.setAction(UPDATED_ACTION); OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, () -> actionPersistenceService.save(changedAction)); diff --git a/backend/src/test/java/ch/puzzle/okr/service/persistence/AuthorizationCriteriaIT.java b/backend/src/test/java/ch/puzzle/okr/service/persistence/AuthorizationCriteriaIT.java index 9546287112..8e9d0a9e5d 100644 --- a/backend/src/test/java/ch/puzzle/okr/service/persistence/AuthorizationCriteriaIT.java +++ b/backend/src/test/java/ch/puzzle/okr/service/persistence/AuthorizationCriteriaIT.java @@ -1,6 +1,5 @@ package ch.puzzle.okr.service.persistence; -import ch.puzzle.okr.dto.ErrorDto; import ch.puzzle.okr.models.Objective; import ch.puzzle.okr.models.authorization.AuthorizationUser; import ch.puzzle.okr.models.overview.Overview; @@ -16,7 +15,6 @@ @SpringIntegrationTest class AuthorizationCriteriaIT { - private static final String REASON = "not authorized to read objective"; @Autowired ObjectivePersistenceService objectivePersistenceService; diff --git a/backend/src/test/java/ch/puzzle/okr/service/persistence/CompletedPersistenceServiceIT.java b/backend/src/test/java/ch/puzzle/okr/service/persistence/CompletedPersistenceServiceIT.java index e85ff9f9b8..cad631afb4 100644 --- a/backend/src/test/java/ch/puzzle/okr/service/persistence/CompletedPersistenceServiceIT.java +++ b/backend/src/test/java/ch/puzzle/okr/service/persistence/CompletedPersistenceServiceIT.java @@ -34,6 +34,8 @@ private static Completed createCompleted(Long id, int version) { .withComment("Wir haben es gut geschafft").build(); } + private static final String COMPLETED = "Completed"; + @AfterEach void tearDown() { try { @@ -79,7 +81,7 @@ void updateCompletedShouldThrowExceptionWhenAlreadyUpdated() { OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, () -> completedPersistenceService.save(updateCompleted)); - List expectedErrors = List.of(new ErrorDto("DATA_HAS_BEEN_UPDATED", List.of("Completed"))); + List expectedErrors = List.of(new ErrorDto("DATA_HAS_BEEN_UPDATED", List.of(COMPLETED))); assertEquals(UNPROCESSABLE_ENTITY, exception.getStatus()); assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); @@ -104,7 +106,7 @@ void deleteCompletedIdShouldDeleteExistingCompletedByObjectiveId() { OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, () -> completedPersistenceService.findById(3L)); - List expectedErrors = List.of(new ErrorDto("MODEL_WITH_ID_NOT_FOUND", List.of("Completed", "3"))); + List expectedErrors = List.of(new ErrorDto("MODEL_WITH_ID_NOT_FOUND", List.of(COMPLETED, "3"))); assertEquals(NOT_FOUND, exception.getStatus()); assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); @@ -120,7 +122,7 @@ void deleteCompletedShouldThrowExceptionWhenCompletedNotFound() { OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, () -> completedPersistenceService.findById(completedId)); - List expectedErrors = List.of(new ErrorDto("MODEL_WITH_ID_NOT_FOUND", List.of("Completed", "200"))); + List expectedErrors = List.of(new ErrorDto("MODEL_WITH_ID_NOT_FOUND", List.of(COMPLETED, "200"))); assertEquals(NOT_FOUND, exception.getStatus()); assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); diff --git a/backend/src/test/java/ch/puzzle/okr/service/persistence/KeyResultPersistenceServiceIT.java b/backend/src/test/java/ch/puzzle/okr/service/persistence/KeyResultPersistenceServiceIT.java index 2f1bbb0d9b..577862c811 100644 --- a/backend/src/test/java/ch/puzzle/okr/service/persistence/KeyResultPersistenceServiceIT.java +++ b/backend/src/test/java/ch/puzzle/okr/service/persistence/KeyResultPersistenceServiceIT.java @@ -50,6 +50,8 @@ private static KeyResult createKeyResultOrdinal(Long id, int version) { private static final String KEY_RESULT_UPDATED = "Updated Key Result"; private static final String THIS_IS_DESCRIPTION = "This is a new description"; + private static final String MODEL_NOT_FOUND = "MODEL_WITH_ID_NOT_FOUND"; + private static final String KEYRESULT = "KeyResult"; @AfterEach void tearDown() { @@ -92,7 +94,7 @@ void getKeyResultByIdShouldThrowExceptionWhenKeyResultNotFound() { OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, () -> keyResultPersistenceService.findById(321L)); - List expectedErrors = List.of(new ErrorDto("MODEL_WITH_ID_NOT_FOUND", List.of("KeyResult", "321"))); + List expectedErrors = List.of(new ErrorDto(MODEL_NOT_FOUND, List.of(KEYRESULT, "321"))); assertEquals(NOT_FOUND, exception.getStatus()); assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); @@ -104,7 +106,7 @@ void getKeyResultByIdShouldThrowExceptionWhenKeyResultIdIsNull() { OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, () -> keyResultPersistenceService.findById(null)); - List expectedErrors = List.of(new ErrorDto("ATTRIBUTE_NULL", List.of("ID", "KeyResult"))); + List expectedErrors = List.of(new ErrorDto("ATTRIBUTE_NULL", List.of("ID", KEYRESULT))); assertEquals(BAD_REQUEST, exception.getStatus()); assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); @@ -129,8 +131,7 @@ void recreateEntityShouldUpdateKeyResultNoTypeChange() { // Should delete the old KeyResult OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, this::execute); - List expectedErrors = List - .of(ErrorDto.of("MODEL_WITH_ID_NOT_FOUND", List.of("KeyResult", keyResultId))); + List expectedErrors = List.of(ErrorDto.of(MODEL_NOT_FOUND, List.of(KEYRESULT, keyResultId))); assertEquals(NOT_FOUND, exception.getStatus()); assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); @@ -164,8 +165,7 @@ void recreateEntityShouldUpdateKeyResultWithTypeChange() { OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, () -> keyResultPersistenceService.findById(keyResultId)); - List expectedErrors = List - .of(ErrorDto.of("MODEL_WITH_ID_NOT_FOUND", List.of("KeyResult", keyResultId))); + List expectedErrors = List.of(ErrorDto.of(MODEL_NOT_FOUND, List.of(KEYRESULT, keyResultId))); assertEquals(NOT_FOUND, exception.getStatus()); assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); @@ -204,7 +204,7 @@ void updateEntityShouldThrowExceptionWhenAlreadyUpdated() { OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, () -> keyResultPersistenceService.updateEntity(updateKeyResult)); - List expectedErrors = List.of(new ErrorDto("DATA_HAS_BEEN_UPDATED", List.of("KeyResult"))); + List expectedErrors = List.of(new ErrorDto("DATA_HAS_BEEN_UPDATED", List.of(KEYRESULT))); assertEquals(UNPROCESSABLE_ENTITY, exception.getStatus()); assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); @@ -228,8 +228,7 @@ void deleteKeyResultByIdShouldDeleteExistingKeyResult() { OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, () -> keyResultPersistenceService.findById(keyResultId)); - List expectedErrors = List - .of(ErrorDto.of("MODEL_WITH_ID_NOT_FOUND", List.of("KeyResult", keyResultId))); + List expectedErrors = List.of(ErrorDto.of(MODEL_NOT_FOUND, List.of(KEYRESULT, keyResultId))); assertEquals(NOT_FOUND, exception.getStatus()); assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); @@ -246,8 +245,7 @@ void deleteKeyResultShouldThrowExceptionWhenKeyResultNotFound() { OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, () -> keyResultPersistenceService.findById(keyResultId)); - List expectedErrors = List - .of(ErrorDto.of("MODEL_WITH_ID_NOT_FOUND", List.of("KeyResult", keyResultId))); + List expectedErrors = List.of(ErrorDto.of(MODEL_NOT_FOUND, List.of(KEYRESULT, keyResultId))); assertEquals(NOT_FOUND, exception.getStatus()); assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); diff --git a/backend/src/test/java/ch/puzzle/okr/service/persistence/ObjectivePersistenceServiceIT.java b/backend/src/test/java/ch/puzzle/okr/service/persistence/ObjectivePersistenceServiceIT.java index 7b6fefd7b0..2bfb2bab87 100644 --- a/backend/src/test/java/ch/puzzle/okr/service/persistence/ObjectivePersistenceServiceIT.java +++ b/backend/src/test/java/ch/puzzle/okr/service/persistence/ObjectivePersistenceServiceIT.java @@ -24,6 +24,9 @@ class ObjectivePersistenceServiceIT { private static final String REASON = "not authorized to read objective"; private static final OkrResponseStatusException exception = OkrResponseStatusException.of(REASON); private static final String HIGHER_CUSTOMER_HAPPINESS = "Wir wollen die Kundenzufriedenheit steigern"; + private static final String MODEL_WITH_ID_NOT_FOUND = "MODEL_WITH_ID_NOT_FOUND"; + private static final String OBJECTIVE = "Objective"; + private static final String ATTRIBUTE_NULL = "ATTRIBUTE_NULL"; private final AuthorizationUser authorizationUser = defaultAuthorizationUser(); private Objective createdObjective; @@ -78,25 +81,25 @@ void findObjectiveByIdShouldReturnObjectiveProperly() { @Test void findObjectiveByIdShouldThrowExceptionWhenObjectiveNotFound() { - ResponseStatusException exception = assertThrows(OkrResponseStatusException.class, + ResponseStatusException findObjectiveException = assertThrows(OkrResponseStatusException.class, () -> objectivePersistenceService.findObjectiveById(321L, authorizationUser, ObjectivePersistenceServiceIT.exception)); - assertEquals(UNAUTHORIZED, exception.getStatus()); - assertEquals(REASON, exception.getReason()); + assertEquals(UNAUTHORIZED, findObjectiveException.getStatus()); + assertEquals(REASON, findObjectiveException.getReason()); } @Test void findObjectiveByIdShouldThrowExceptionWhenObjectiveIdIsNull() { - OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, + OkrResponseStatusException findObjectiveException = assertThrows(OkrResponseStatusException.class, () -> objectivePersistenceService.findObjectiveById(null, authorizationUser, ObjectivePersistenceServiceIT.exception)); - List expectedErrors = List.of(new ErrorDto("ATTRIBUTE_NULL", List.of("ID", "Objective"))); + List expectedErrors = List.of(new ErrorDto(ATTRIBUTE_NULL, List.of("ID", OBJECTIVE))); - assertEquals(BAD_REQUEST, exception.getStatus()); - assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); - assertTrue(TestHelper.getAllErrorKeys(expectedErrors).contains(exception.getReason())); + assertEquals(BAD_REQUEST, findObjectiveException.getStatus()); + assertThat(expectedErrors).hasSameElementsAs(findObjectiveException.getErrors()); + assertTrue(TestHelper.getAllErrorKeys(expectedErrors).contains(findObjectiveException.getReason())); } @Test @@ -109,25 +112,25 @@ void findObjectiveByKeyResultIdShouldReturnObjectiveProperly() { @Test void findObjectiveByKeyResultIdShouldThrowExceptionWhenObjectiveNotFound() { - ResponseStatusException exception = assertThrows(ResponseStatusException.class, + ResponseStatusException objectiveByKeyResultException = assertThrows(ResponseStatusException.class, () -> objectivePersistenceService.findObjectiveByKeyResultId(321L, authorizationUser, ObjectivePersistenceServiceIT.exception)); - assertEquals(UNAUTHORIZED, exception.getStatus()); - assertEquals(REASON, exception.getReason()); + assertEquals(UNAUTHORIZED, objectiveByKeyResultException.getStatus()); + assertEquals(REASON, objectiveByKeyResultException.getReason()); } @Test void findObjectiveByKeyResultIdShouldThrowExceptionWhenObjectiveIdIsNull() { - OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, + OkrResponseStatusException objectiveByKeyResultException = assertThrows(OkrResponseStatusException.class, () -> objectivePersistenceService.findObjectiveByKeyResultId(null, authorizationUser, ObjectivePersistenceServiceIT.exception)); - List expectedErrors = List.of(new ErrorDto("ATTRIBUTE_NULL", List.of("ID", "Objective"))); + List expectedErrors = List.of(new ErrorDto(ATTRIBUTE_NULL, List.of("ID", OBJECTIVE))); - assertEquals(BAD_REQUEST, exception.getStatus()); - assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); - assertTrue(TestHelper.getAllErrorKeys(expectedErrors).contains(exception.getReason())); + assertEquals(BAD_REQUEST, objectiveByKeyResultException.getStatus()); + assertThat(expectedErrors).hasSameElementsAs(objectiveByKeyResultException.getErrors()); + assertTrue(TestHelper.getAllErrorKeys(expectedErrors).contains(objectiveByKeyResultException.getReason())); } @Test @@ -140,25 +143,25 @@ void findObjectiveByCheckInIdShouldReturnObjectiveProperly() { @Test void findObjectiveByCheckInIdShouldThrowExceptionWhenObjectiveNotFound() { - ResponseStatusException exception = assertThrows(ResponseStatusException.class, + ResponseStatusException objectiveByCheckInException = assertThrows(ResponseStatusException.class, () -> objectivePersistenceService.findObjectiveByCheckInId(321L, authorizationUser, ObjectivePersistenceServiceIT.exception)); - assertEquals(UNAUTHORIZED, exception.getStatus()); - assertEquals(REASON, exception.getReason()); + assertEquals(UNAUTHORIZED, objectiveByCheckInException.getStatus()); + assertEquals(REASON, objectiveByCheckInException.getReason()); } @Test void findObjectiveByCheckInIdShouldThrowExceptionWhenObjectiveIdIsNull() { - OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, + OkrResponseStatusException objectiveByCheckInException = assertThrows(OkrResponseStatusException.class, () -> objectivePersistenceService.findObjectiveByCheckInId(null, authorizationUser, ObjectivePersistenceServiceIT.exception)); - List expectedErrors = List.of(new ErrorDto("ATTRIBUTE_NULL", List.of("ID", "Objective"))); + List expectedErrors = List.of(new ErrorDto(ATTRIBUTE_NULL, List.of("ID", OBJECTIVE))); - assertEquals(BAD_REQUEST, exception.getStatus()); - assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); - assertTrue(TestHelper.getAllErrorKeys(expectedErrors).contains(exception.getReason())); + assertEquals(BAD_REQUEST, objectiveByCheckInException.getStatus()); + assertThat(expectedErrors).hasSameElementsAs(objectiveByCheckInException.getErrors()); + assertTrue(TestHelper.getAllErrorKeys(expectedErrors).contains(objectiveByCheckInException.getReason())); } @Test @@ -191,13 +194,13 @@ void updateObjectiveShouldThrowExceptionWhenAlreadyUpdated() { Objective updateObjective = createObjective(createdObjective.getId(), 0); updateObjective.setState(State.ONGOING); - OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, + OkrResponseStatusException objectiveSaveException = assertThrows(OkrResponseStatusException.class, () -> objectivePersistenceService.save(updateObjective)); - List expectedErrors = List.of(new ErrorDto("DATA_HAS_BEEN_UPDATED", List.of("Objective"))); + List expectedErrors = List.of(new ErrorDto("DATA_HAS_BEEN_UPDATED", List.of(OBJECTIVE))); - assertEquals(UNPROCESSABLE_ENTITY, exception.getStatus()); - assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); - assertTrue(TestHelper.getAllErrorKeys(expectedErrors).contains(exception.getReason())); + assertEquals(UNPROCESSABLE_ENTITY, objectiveSaveException.getStatus()); + assertThat(expectedErrors).hasSameElementsAs(objectiveSaveException.getErrors()); + assertTrue(TestHelper.getAllErrorKeys(expectedErrors).contains(objectiveSaveException.getReason())); } @Test @@ -207,35 +210,35 @@ void deleteObjectiveShouldThrowExceptionWhenKeyResultNotFound() { objectivePersistenceService.deleteById(createdObjective.getId()); Long objectiveId = createdObjective.getId(); - OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, + OkrResponseStatusException findObjectiveException = assertThrows(OkrResponseStatusException.class, () -> objectivePersistenceService.findById(objectiveId)); - List expectedErrors = List.of(new ErrorDto("MODEL_WITH_ID_NOT_FOUND", List.of("Objective", "200"))); + List expectedErrors = List.of(new ErrorDto(MODEL_WITH_ID_NOT_FOUND, List.of(OBJECTIVE, "200"))); - assertEquals(NOT_FOUND, exception.getStatus()); - assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); - assertTrue(TestHelper.getAllErrorKeys(expectedErrors).contains(exception.getReason())); + assertEquals(NOT_FOUND, findObjectiveException.getStatus()); + assertThat(expectedErrors).hasSameElementsAs(findObjectiveException.getErrors()); + assertTrue(TestHelper.getAllErrorKeys(expectedErrors).contains(findObjectiveException.getReason())); } @Test void countByTeamAndQuarterShouldThrowErrorIfQuarterDoesNotExist() { Team teamId5 = teamPersistenceService.findById(5L); - OkrResponseStatusException exception = assertThrows(OkrResponseStatusException.class, + OkrResponseStatusException countByTeamException = assertThrows(OkrResponseStatusException.class, () -> objectivePersistenceService.countByTeamAndQuarter(teamId5, quarterPersistenceService.findById(12L))); - List expectedErrors = List.of(new ErrorDto("MODEL_WITH_ID_NOT_FOUND", List.of("Quarter", "12"))); + List expectedErrors = List.of(new ErrorDto(MODEL_WITH_ID_NOT_FOUND, List.of("Quarter", "12"))); - assertEquals(NOT_FOUND, exception.getStatus()); - assertThat(expectedErrors).hasSameElementsAs(exception.getErrors()); - assertTrue(TestHelper.getAllErrorKeys(expectedErrors).contains(exception.getReason())); + assertEquals(NOT_FOUND, countByTeamException.getStatus()); + assertThat(expectedErrors).hasSameElementsAs(countByTeamException.getErrors()); + assertTrue(TestHelper.getAllErrorKeys(expectedErrors).contains(countByTeamException.getReason())); Quarter quarterId2 = quarterPersistenceService.findById(2L); OkrResponseStatusException exceptionTeam = assertThrows(OkrResponseStatusException.class, () -> objectivePersistenceService.countByTeamAndQuarter(teamPersistenceService.findById(500L), quarterId2)); - List expectedErrorsTeam = List.of(new ErrorDto("MODEL_WITH_ID_NOT_FOUND", List.of("Team", "500"))); + List expectedErrorsTeam = List.of(new ErrorDto(MODEL_WITH_ID_NOT_FOUND, List.of("Team", "500"))); assertEquals(NOT_FOUND, exceptionTeam.getStatus()); assertThat(expectedErrorsTeam).hasSameElementsAs(exceptionTeam.getErrors()); diff --git a/backend/src/test/java/ch/puzzle/okr/service/persistence/OrganisationPersistenceIT.java b/backend/src/test/java/ch/puzzle/okr/service/persistence/OrganisationPersistenceIT.java index 3c4b1dc9e3..84eb8accd7 100644 --- a/backend/src/test/java/ch/puzzle/okr/service/persistence/OrganisationPersistenceIT.java +++ b/backend/src/test/java/ch/puzzle/okr/service/persistence/OrganisationPersistenceIT.java @@ -141,8 +141,6 @@ void getEmptyListIfNoTeamWithIdFound() { @Test void getActiveOrganisations() { List organisations = organisationPersistenceService.getActiveOrganisations(); - organisations.forEach(organisation -> { - assertNotSame(OrganisationState.INACTIVE, organisation.getState()); - }); + organisations.forEach(organisation -> assertNotSame(OrganisationState.INACTIVE, organisation.getState())); } } diff --git a/backend/src/test/java/ch/puzzle/okr/service/persistence/TeamPersistenceServiceIT.java b/backend/src/test/java/ch/puzzle/okr/service/persistence/TeamPersistenceServiceIT.java index 3c370a6f83..0d61b92bee 100644 --- a/backend/src/test/java/ch/puzzle/okr/service/persistence/TeamPersistenceServiceIT.java +++ b/backend/src/test/java/ch/puzzle/okr/service/persistence/TeamPersistenceServiceIT.java @@ -28,7 +28,7 @@ class TeamPersistenceServiceIT { private static final Logger logger = LoggerFactory.getLogger(TeamPersistenceServiceIT.class); - + private static final String NEW_TEAM = "New Team"; private Team createdTeam; @Autowired private TeamPersistenceService teamPersistenceService; @@ -90,7 +90,7 @@ void shouldSaveANewTeam() { @Test void shouldUpdateTeamProperly() { - Team team = Team.Builder.builder().withName("New Team").build(); + Team team = Team.Builder.builder().withName(NEW_TEAM).build(); createdTeam = teamPersistenceService.save(team); createdTeam.setName("Updated Team"); @@ -102,7 +102,7 @@ void shouldUpdateTeamProperly() { @Test void updateTeamShouldThrowExceptionWhenAlreadyUpdated() { - Team team = Team.Builder.builder().withVersion(1).withName("New Team").build(); + Team team = Team.Builder.builder().withVersion(1).withName(NEW_TEAM).build(); createdTeam = teamPersistenceService.save(team); Team changedTeam = Team.Builder.builder().withId(createdTeam.getId()).withVersion(0).withName("Changed Team") .build(); @@ -118,7 +118,7 @@ void updateTeamShouldThrowExceptionWhenAlreadyUpdated() { @Test void shouldDeleteTeam() { - Team team = Team.Builder.builder().withName("New Team").build(); + Team team = Team.Builder.builder().withName(NEW_TEAM).build(); createdTeam = teamPersistenceService.save(team); teamPersistenceService.deleteById(createdTeam.getId()); @@ -145,9 +145,9 @@ void findTeamIdsByOrganisationNamesShouldReturnFirstLevelTeams(List orga @Test void shouldFindTeamsByName() { - Team team = Team.Builder.builder().withName("New Team").build(); + Team team = Team.Builder.builder().withName(NEW_TEAM).build(); createdTeam = teamPersistenceService.save(team); - List teams = teamPersistenceService.findTeamsByName("New Team"); + List teams = teamPersistenceService.findTeamsByName(NEW_TEAM); assertThat(teams).contains(createdTeam); } diff --git a/frontend/src/app/action-plan/action-plan.component.spec.ts b/frontend/src/app/action-plan/action-plan.component.spec.ts index da4d94db83..9aab1bde34 100644 --- a/frontend/src/app/action-plan/action-plan.component.spec.ts +++ b/frontend/src/app/action-plan/action-plan.component.spec.ts @@ -8,6 +8,7 @@ import { ActionService } from '../shared/services/action.service'; import { action1, action2, action3, addedAction } from '../shared/testData'; import { BehaviorSubject, of } from 'rxjs'; import { Action } from '../shared/types/model/Action'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; const actionServiceMock = { deleteAction: jest.fn(), @@ -21,8 +22,9 @@ describe('ActionPlanComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [ActionPlanComponent], - imports: [HttpClientTestingModule, MatDialogModule, CdkDropList, CdkDrag], + imports: [HttpClientTestingModule, MatDialogModule, CdkDropList, CdkDrag, TranslateModule.forRoot()], providers: [ + TranslateService, { provide: ActionService, useValue: actionServiceMock, diff --git a/frontend/src/app/application-top-bar/application-top-bar.component.ts b/frontend/src/app/application-top-bar/application-top-bar.component.ts index 072a8e5853..800520390a 100644 --- a/frontend/src/app/application-top-bar/application-top-bar.component.ts +++ b/frontend/src/app/application-top-bar/application-top-bar.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; import { OAuthService } from 'angular-oauth2-oidc'; -import { map, Observable, ReplaySubject } from 'rxjs'; +import { map, ReplaySubject } from 'rxjs'; import { ConfigService } from '../config.service'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { TeamManagementComponent } from '../shared/dialog/team-management/team-management.component'; diff --git a/frontend/src/app/quarter-filter/quarter-filter.component.scss b/frontend/src/app/quarter-filter/quarter-filter.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/frontend/src/app/shared/dialog/checkin/check-in-form-ordinal/check-in-form-ordinal.component.ts b/frontend/src/app/shared/dialog/checkin/check-in-form-ordinal/check-in-form-ordinal.component.ts index 76850e2553..ce4b89342b 100644 --- a/frontend/src/app/shared/dialog/checkin/check-in-form-ordinal/check-in-form-ordinal.component.ts +++ b/frontend/src/app/shared/dialog/checkin/check-in-form-ordinal/check-in-form-ordinal.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { KeyResultOrdinal } from '../../../types/model/KeyResultOrdinal'; import { Zone } from '../../../types/enums/Zone'; diff --git a/frontend/src/app/shared/dialog/checkin/check-in-form/check-in-form.component.ts b/frontend/src/app/shared/dialog/checkin/check-in-form/check-in-form.component.ts index c5f6c406ab..b78a4be988 100644 --- a/frontend/src/app/shared/dialog/checkin/check-in-form/check-in-form.component.ts +++ b/frontend/src/app/shared/dialog/checkin/check-in-form/check-in-form.component.ts @@ -89,7 +89,7 @@ export class CheckInFormComponent implements OnInit { if (this.keyResult.keyResultType === 'metric') { checkIn = { ...this.dialogForm.value, - value: this.parserPipe.transform(this.dialogForm?.controls['value'].value!), + value: this.parserPipe.transform(this.dialogForm.controls['value'].value), keyResultId: this.keyResult.id, id: this.checkIn.id, version: this.checkIn.version, diff --git a/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.spec.ts b/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.spec.ts index 5efa8680fa..01761a3fcf 100644 --- a/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.spec.ts +++ b/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.spec.ts @@ -10,6 +10,7 @@ import { MatSelectModule } from '@angular/material/select'; import { MatInputModule } from '@angular/material/input'; import { MatRadioModule } from '@angular/material/radio'; import { ReactiveFormsModule } from '@angular/forms'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; const dialogMock = { close: jest.fn(), @@ -29,9 +30,11 @@ describe('ConfirmDialogComponent', () => { MatInputModule, MatRadioModule, ReactiveFormsModule, + TranslateModule.forRoot(), ], declarations: [ConfirmDialogComponent], providers: [ + TranslateService, { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: MatDialogRef, useValue: dialogMock }, ], diff --git a/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.ts b/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.ts index 849a79493e..0bc46eb3cf 100644 --- a/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.ts +++ b/frontend/src/app/shared/dialog/confirm-dialog/confirm-dialog.component.ts @@ -1,5 +1,6 @@ import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'app-confirm-dialog', @@ -12,6 +13,7 @@ export class ConfirmDialogComponent implements OnInit { constructor( @Inject(MAT_DIALOG_DATA) public data: any, public dialogRef: MatDialogRef, + private translate: TranslateService, ) {} ngOnInit() { @@ -19,21 +21,29 @@ export class ConfirmDialogComponent implements OnInit { this.dialogTitle = 'Check-in im Draft-Status'; this.dialogText = 'Dein Objective befindet sich noch im DRAFT Status. Möchtest du das Check-in trotzdem erfassen?'; + } else if (this.data.action) { + if (this.data.action === 'release') { + this.dialogTitle = this.data.title + ' veröffentlichen'; + this.dialogText = 'Soll dieses ' + this.data.title + ' veröffentlicht werden?'; + } } else { - if (this.data.action) { - if (this.data.action === 'release') { - this.dialogTitle = this.data.title + ' veröffentlichen'; - this.dialogText = 'Soll dieses ' + this.data.title + ' veröffentlicht werden?'; - } + this.dialogTitle = this.data.title + ' löschen'; + if (this.data.isAction) { + this.dialogText = 'Möchtest du diese Action wirklich löschen?'; } else { - this.dialogTitle = this.data.title + ' löschen'; - this.dialogText = this.data.isAction - ? 'Möchtest du diese Action wirklich löschen?' - : 'Möchtest du dieses ' + - this.data.title + - ' wirklich löschen? Zugehörige ' + - (this.data.title == 'Objective' ? 'Key Results' : 'Check-ins') + - ' werden dadurch ebenfalls gelöscht!'; + let error; + switch (this.data.title) { + case 'Team': + error = 'DELETE_TEAM'; + break; + case 'Objective': + error = 'DELETE_OBJECTIVE'; + break; + case 'Key Result': + error = 'DELETE_KEY_RESULT'; + break; + } + this.dialogText = this.translate.instant('INFORMATION.' + error); } } } diff --git a/frontend/src/app/shared/types/model/Organisation.ts b/frontend/src/app/shared/types/model/Organisation.ts index 5c88b4e3e7..5e1e3a4737 100644 --- a/frontend/src/app/shared/types/model/Organisation.ts +++ b/frontend/src/app/shared/types/model/Organisation.ts @@ -4,7 +4,7 @@ import { OrganisationState } from '../enums/OrganisationState'; export interface Organisation { id: number; version: number; - orgName: String; + orgName: string; teams: Team[]; state: OrganisationState; } diff --git a/frontend/src/assets/i18n/de.json b/frontend/src/assets/i18n/de.json index cddb852d62..a7b684b843 100644 --- a/frontend/src/assets/i18n/de.json +++ b/frontend/src/assets/i18n/de.json @@ -22,7 +22,10 @@ "ordinal": "Ordinal" }, "INFORMATION": { - "OBJECTIVE_STATE_TOOLTIP": "Der Status dieses Objectives ist" + "OBJECTIVE_STATE_TOOLTIP": "Der Status dieses Objectives ist", + "DELETE_TEAM": "Möchtest du dieses Team wirklich löschen? Zugehörige Objectives werden dadurch in allen Quartalen ebenfalls gelöscht!", + "DELETE_OBJECTIVE": "Möchtest du dieses Objective wirklich löschen? Zugehörige Key Results werden dadruch ebenfalls gelöscht!", + "DELETE_KEY_RESULT": "Möchtest du dieses Key Result wirklich löschen? Zugehörige Check-ins werden dadurch ebenfalls gelöscht!" }, "ERROR": { "UNAUTHORIZED": "Du bist nicht autorisiert, um das Objekt mit der Id {1} zu öffnen", diff --git a/frontend/src/global.ts b/frontend/src/global.ts index e00f3ffa5f..a9a8df6207 100644 --- a/frontend/src/global.ts +++ b/frontend/src/global.ts @@ -7,7 +7,7 @@ declare global { String.prototype.format = function () { const args = Array.from(arguments).flat(); - return this.replace(/{([0-9]+)}/g, function (match, index) { + return this.replace(/{(\d+)}/g, function (match, index) { return typeof args[index] == 'undefined' ? match : args[index]; }); }; diff --git a/frontend/src/style/custom_angular.components.scss b/frontend/src/style/custom_angular.components.scss index 8a53ae4d1f..a4aa2c1d91 100644 --- a/frontend/src/style/custom_angular.components.scss +++ b/frontend/src/style/custom_angular.components.scss @@ -24,14 +24,6 @@ margin-left: 8px !important; } -.mdc-dialog__title::before { - display: none !important; -} - -.mat-mdc-dialog-surface { - padding: 1rem 0 1rem 0; -} - .ordinal-zone .mdc-form-field, .mdc-label { width: 100% !important;