Skip to content
Snippets Groups Projects
Commit e1dddd0a authored by OZGCloud's avatar OZGCloud
Browse files

Merge branch 'master' into OZG-6710-update-common-lib

parents 4115c7ff 1b23fb7f
No related branches found
No related tags found
No related merge requests found
Showing with 165 additions and 67 deletions
package de.ozgcloud.user.common.migration;
import static de.ozgcloud.user.common.DocumentUtils.*;
import java.util.Map;
import org.bson.Document;
......@@ -9,8 +7,6 @@ import org.bson.Document;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import de.ozgcloud.user.User;
import de.ozgcloud.user.settings.UserSettings;
import io.mongock.api.annotations.ChangeUnit;
import io.mongock.api.annotations.Execution;
import io.mongock.api.annotations.RollbackExecution;
......@@ -20,11 +16,19 @@ import lombok.RequiredArgsConstructor;
@ChangeUnit(id = "2024-09-22 12:00:00 OZG-3539", order = "M001", author = "sbergandy", systemVersion = "1")
public class M001_SetNewAndMigrateUserSettings {
static final String USER_COLLECTION_NAME = "User";
static final String USER_SETTINGS_FIELD = "userSettings";
static final String NOTIFICATIONS_SEND_FOR_FIELD = "notificationsSendFor";
static final String VORGANG_CREATED_FIELD = "vorgangCreated";
static final String VORGANG_ASSIGNED_TO_USER_FIELD = "vorgangAssignedToUser";
static final String POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD = "postfachNachrichtFromAntragsteller";
static final String WIEDERVORLAGE_DUE_TODAY = "wiedervorlageDueToday";
private final MongoDatabase mongoDatabase;
@Execution
public void migrationMethod() {
var userCollection = mongoDatabase.getCollection(User.COLLECTION_NAME);
var userCollection = mongoDatabase.getCollection(USER_COLLECTION_NAME);
migrateNotificationsSendForALL(userCollection);
migrateNotificationsSendForNONE(userCollection);
migrateEmptySettings(userCollection);
......@@ -32,39 +36,43 @@ public class M001_SetNewAndMigrateUserSettings {
private void migrateNotificationsSendForALL(MongoCollection<Document> userCollection) {
userCollection.updateMany(
new Document(Map.of(buildFieldPath(User.USER_SETTINGS_FIELD, UserSettings.NOTIFICATIONS_SEND_FOR_FIELD), "ALL")),
new Document(Map.of("$set", Map.of(User.USER_SETTINGS_FIELD,
Map.of(UserSettings.NOTIFICATIONS_SEND_FOR_FIELD, "ALL",
UserSettings.VORGANG_CREATED_FIELD, true,
UserSettings.VORGANG_ASSIGNED_TO_USER_FIELD, true,
UserSettings.POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD, true,
UserSettings.WIEDERVORLAGE_OVERDUE_FIELD, true)))));
new Document(Map.of(buildFieldPath(USER_SETTINGS_FIELD, NOTIFICATIONS_SEND_FOR_FIELD), "ALL")),
new Document(Map.of("$set", Map.of(USER_SETTINGS_FIELD,
Map.of(NOTIFICATIONS_SEND_FOR_FIELD, "ALL",
VORGANG_CREATED_FIELD, true,
VORGANG_ASSIGNED_TO_USER_FIELD, true,
POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD, true,
WIEDERVORLAGE_DUE_TODAY, true)))));
}
private void migrateNotificationsSendForNONE(MongoCollection<Document> userCollection) {
userCollection.updateMany(
new Document(Map.of(buildFieldPath(User.USER_SETTINGS_FIELD, UserSettings.NOTIFICATIONS_SEND_FOR_FIELD), "NONE")),
new Document(Map.of("$set", Map.of(User.USER_SETTINGS_FIELD,
Map.of(UserSettings.NOTIFICATIONS_SEND_FOR_FIELD, "NONE",
UserSettings.VORGANG_CREATED_FIELD, false,
UserSettings.VORGANG_ASSIGNED_TO_USER_FIELD, true,
UserSettings.POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD, true,
UserSettings.WIEDERVORLAGE_OVERDUE_FIELD, true)))));
new Document(Map.of(buildFieldPath(USER_SETTINGS_FIELD, NOTIFICATIONS_SEND_FOR_FIELD), "NONE")),
new Document(Map.of("$set", Map.of(USER_SETTINGS_FIELD,
Map.of(NOTIFICATIONS_SEND_FOR_FIELD, "NONE",
VORGANG_CREATED_FIELD, false,
VORGANG_ASSIGNED_TO_USER_FIELD, true,
POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD, true,
WIEDERVORLAGE_DUE_TODAY, true)))));
}
private void migrateEmptySettings(MongoCollection<Document> userCollection) {
userCollection.updateMany(
new Document(Map.of(buildFieldPath(User.USER_SETTINGS_FIELD, UserSettings.NOTIFICATIONS_SEND_FOR_FIELD), Map.of("$exists", false))),
new Document(Map.of("$set", Map.of(User.USER_SETTINGS_FIELD,
Map.of(UserSettings.NOTIFICATIONS_SEND_FOR_FIELD, "NONE",
UserSettings.VORGANG_CREATED_FIELD, false,
UserSettings.VORGANG_ASSIGNED_TO_USER_FIELD, true,
UserSettings.POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD, true,
UserSettings.WIEDERVORLAGE_OVERDUE_FIELD, true)))));
new Document(Map.of(buildFieldPath(USER_SETTINGS_FIELD, NOTIFICATIONS_SEND_FOR_FIELD), Map.of("$exists", false))),
new Document(Map.of("$set", Map.of(USER_SETTINGS_FIELD,
Map.of(NOTIFICATIONS_SEND_FOR_FIELD, "NONE",
VORGANG_CREATED_FIELD, false,
VORGANG_ASSIGNED_TO_USER_FIELD, true,
POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD, true,
WIEDERVORLAGE_DUE_TODAY, true)))));
}
@RollbackExecution
public void rollback() {
// kein rollback implementiert
}
private String buildFieldPath(String... fields) {
return String.join(".", fields);
}
}
......@@ -35,16 +35,12 @@ import lombok.Setter;
public class UserSettings {
public static final String NOTIFICATIONS_SEND_FOR_FIELD = "notificationsSendFor";
public static final String VORGANG_CREATED_FIELD = "vorgangCreated";
public static final String VORGANG_ASSIGNED_TO_USER_FIELD = "vorgangAssignedToUser";
public static final String POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD = "postfachNachrichtFromAntragsteller";
public static final String WIEDERVORLAGE_OVERDUE_FIELD = "wiedervorlageOverdue";
private NotificationsSendFor notificationsSendFor;
private boolean vorgangCreated;
private boolean vorgangAssignedToUser;
private boolean postfachNachrichtFromAntragsteller;
private boolean wiedervorlageOverdue;
private boolean wiedervorlageDueToday;
public UserSettings(NotificationsSendFor notificationsSendFor) {
this(notificationsSendFor, notificationsSendFor == NotificationsSendFor.ALL, true, true, true);
......
......@@ -28,6 +28,7 @@ import java.util.Objects;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.PATCH;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
......@@ -75,6 +76,7 @@ public class UserSettingsResource {
return resourceAssembler.toResource(userSettingsService.getByUserId(userId), userId, userManagerUrl);
}
@Deprecated
@PATCH
@ResponseStatus(200)
@Path("/{id}/settings")
......@@ -91,6 +93,22 @@ public class UserSettingsResource {
.orElseThrow(() -> new FunctionalException(() -> "Invalid user id"));
}
@PUT
@ResponseStatus(200)
@Path("/{id}/settings")
@Produces({ MediaType.APPLICATION_JSON, RestMediaType.APPLICATION_HAL_JSON })
public HalEntityWrapper putUserSettings(@PathParam("id") String userId, UserSettings userSettings) {
checkUserAccess(userId);
if (Objects.isNull(userSettings)) {
throw new FunctionalException(() -> "Request Body missing.");
}
return userSettingsService.updateByUserId(userId, userSettings)
.map(updatedSettings -> resourceAssembler.toResource(updatedSettings, userId, userManagerUrl))
.orElseThrow(() -> new FunctionalException(() -> "Invalid user id"));
}
void checkUserAccess(String userId) {
var user = userService.findByExternalId(jwt.getSubject());
......
package de.ozgcloud.user.common.migration;
import static de.ozgcloud.user.common.migration.M001_SetNewAndMigrateUserSettings.*;
import static org.assertj.core.api.Assertions.*;
import java.util.Map;
......@@ -14,9 +15,7 @@ import org.junit.jupiter.api.Test;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoCollection;
import de.ozgcloud.user.User;
import de.ozgcloud.user.common.MongoDbTestProfile;
import de.ozgcloud.user.settings.UserSettings;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.TestProfile;
......@@ -24,6 +23,8 @@ import io.quarkus.test.junit.TestProfile;
@TestProfile(MongoDbTestProfile.class)
class M001_SetNewAndMigrateUserSettingsITCase {
static final String USERNAME_FIELD = "username";
@ConfigProperty(name = "quarkus.mongodb.database")
String database;
......@@ -40,55 +41,55 @@ class M001_SetNewAndMigrateUserSettingsITCase {
@BeforeEach
void initDatabase() {
userCollection = mongoClient.getDatabase(database).getCollection(User.COLLECTION_NAME);
userCollection = mongoClient.getDatabase(database).getCollection(USER_COLLECTION_NAME);
userCollection.drop();
userCollection.insertOne(new Document(
Map.of(User.USERNAME_FIELD, "alluser",
User.USER_SETTINGS_FIELD, Map.of(UserSettings.NOTIFICATIONS_SEND_FOR_FIELD, "ALL"))));
userCollection.insertOne(new Document(Map.of(User.USERNAME_FIELD, "noneuser",
User.USER_SETTINGS_FIELD, Map.of(UserSettings.NOTIFICATIONS_SEND_FOR_FIELD, "NONE"))));
userCollection.insertOne(new Document(Map.of(User.USERNAME_FIELD, "nosettings")));
Map.of(USERNAME_FIELD, "alluser",
USER_SETTINGS_FIELD, Map.of(NOTIFICATIONS_SEND_FOR_FIELD, "ALL"))));
userCollection.insertOne(new Document(Map.of(USERNAME_FIELD, "noneuser",
USER_SETTINGS_FIELD, Map.of(NOTIFICATIONS_SEND_FOR_FIELD, "NONE"))));
userCollection.insertOne(new Document(Map.of(USERNAME_FIELD, "nosettings")));
}
@Test
void shouldMigrateNotificationSendFor_ALL() {
migration.migrationMethod();
var user = userCollection.find(new Document(Map.of(User.USERNAME_FIELD, "alluser")));
var user = userCollection.find(new Document(Map.of(USERNAME_FIELD, "alluser")));
assertThat(user.first()).contains(
entry(User.USER_SETTINGS_FIELD, new Document(Map.of(
UserSettings.NOTIFICATIONS_SEND_FOR_FIELD, "ALL",
UserSettings.VORGANG_CREATED_FIELD, true,
UserSettings.VORGANG_ASSIGNED_TO_USER_FIELD, true,
UserSettings.POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD, true,
UserSettings.WIEDERVORLAGE_OVERDUE_FIELD, true))));
entry(USER_SETTINGS_FIELD, new Document(Map.of(
NOTIFICATIONS_SEND_FOR_FIELD, "ALL",
VORGANG_CREATED_FIELD, true,
VORGANG_ASSIGNED_TO_USER_FIELD, true,
POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD, true,
WIEDERVORLAGE_DUE_TODAY, true))));
}
@Test
void shouldMigrateNotificationSendFor_NONE() {
migration.migrationMethod();
var user = userCollection.find(new Document(Map.of(User.USERNAME_FIELD, "noneuser")));
var user = userCollection.find(new Document(Map.of(USERNAME_FIELD, "noneuser")));
assertThat(user.first()).contains(
entry(User.USER_SETTINGS_FIELD, new Document(Map.of(
UserSettings.NOTIFICATIONS_SEND_FOR_FIELD, "NONE",
UserSettings.VORGANG_CREATED_FIELD, false,
UserSettings.VORGANG_ASSIGNED_TO_USER_FIELD, true,
UserSettings.POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD, true,
UserSettings.WIEDERVORLAGE_OVERDUE_FIELD, true))));
entry(USER_SETTINGS_FIELD, new Document(Map.of(
NOTIFICATIONS_SEND_FOR_FIELD, "NONE",
VORGANG_CREATED_FIELD, false,
VORGANG_ASSIGNED_TO_USER_FIELD, true,
POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD, true,
WIEDERVORLAGE_DUE_TODAY, true))));
}
@Test
void shouldSetDefaultSettings() {
migration.migrationMethod();
var user = userCollection.find(new Document(Map.of(User.USERNAME_FIELD, "nosettings")));
var user = userCollection.find(new Document(Map.of(USERNAME_FIELD, "nosettings")));
assertThat(user.first()).contains(
entry(User.USER_SETTINGS_FIELD, new Document(Map.of(
UserSettings.NOTIFICATIONS_SEND_FOR_FIELD, "NONE",
UserSettings.VORGANG_CREATED_FIELD, false,
UserSettings.VORGANG_ASSIGNED_TO_USER_FIELD, true,
UserSettings.POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD, true,
UserSettings.WIEDERVORLAGE_OVERDUE_FIELD, true))));
entry(USER_SETTINGS_FIELD, new Document(Map.of(
NOTIFICATIONS_SEND_FOR_FIELD, "NONE",
VORGANG_CREATED_FIELD, false,
VORGANG_ASSIGNED_TO_USER_FIELD, true,
POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER_FIELD, true,
WIEDERVORLAGE_DUE_TODAY, true))));
}
}
\ No newline at end of file
......@@ -198,6 +198,81 @@ class UserSettingsResourceTest {
}
}
@DisplayName("Update Usersettings")
@Nested
class TestPutUserSettings {
private final UserSettings userSettings = UserSettingsTestFactory.create();
private final UserSettings updatedUserSettings = UserSettingsTestFactory.create();
@BeforeEach
void mockAccess() {
doNothing().when(resource).checkUserAccess(anyString());
}
@Test
void shouldCheckAccess() {
when(userSettingsService.updateByUserId(USER_ID, userSettings)).thenReturn(Optional.of(updatedUserSettings));
when(resourceAssembler.toResource(any(), anyString(), anyString())).thenReturn(new HalEntityWrapper(null));
resource.putUserSettings(USER_ID, userSettings);
verify(resource).checkUserAccess(USER_ID);
}
@DisplayName("with empty body")
@Nested
class TestOnEmptyBody {
@Test
void shouldThrowFunctionalExceptionOnMissingBody() {
assertThatExceptionOfType(FunctionalException.class).isThrownBy(() -> resource.putUserSettings(USER_ID, null))
.withMessageStartingWith("Functional error: Request Body missing");
}
}
@Nested
class TestUserIdNotExist {
@Test
void shouldThrowFunctionalException() {
when(userSettingsService.updateByUserId(USER_ID, userSettings)).thenReturn(Optional.empty());
assertThatExceptionOfType(FunctionalException.class)
.isThrownBy(() -> resource.putUserSettings(USER_ID, userSettings))
.withMessageStartingWith("Functional error: Invalid user id");
}
}
@Nested
class TestFilledBody {
@BeforeEach
void setUp() {
when(userSettingsService.updateByUserId(USER_ID, userSettings)).thenReturn(Optional.of(updatedUserSettings));
}
@Test
void shouldCallUserSettingsService() {
when(resourceAssembler.toResource(updatedUserSettings, USER_ID, USER_MANAGER_URL)).thenReturn(new HalEntityWrapper(null));
resource.putUserSettings(USER_ID, userSettings);
verify(userSettingsService).updateByUserId(USER_ID, userSettings);
}
@Test
void
shouldCallResourceAssembler() {
when(resourceAssembler.toResource(updatedUserSettings, USER_ID, USER_MANAGER_URL)).thenReturn(new HalEntityWrapper(null));
resource.putUserSettings(USER_ID, userSettings);
verify(resourceAssembler).toResource(updatedUserSettings, USER_ID, USER_MANAGER_URL);
}
}
}
@DisplayName("Check User access")
@Nested
class TestCheckUserAccess {
......
......@@ -79,13 +79,13 @@ class UserSettingsServiceTest {
UserSettings::isVorgangCreated,
UserSettings::isVorgangAssignedToUser,
UserSettings::isPostfachNachrichtFromAntragsteller,
UserSettings::isWiedervorlageOverdue)
UserSettings::isWiedervorlageDueToday)
.containsExactly(
NotificationsSendFor.ALL,
true,
UserSettingsTestFactory.VORGANG_ASSIGNED_TO_USER,
UserSettingsTestFactory.POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER,
UserSettingsTestFactory.WIEDERVORLAGE_OVERDUE);
UserSettingsTestFactory.WIEDERVORLAGE_DUE_TODAY);
}
@Test
......@@ -99,13 +99,13 @@ class UserSettingsServiceTest {
UserSettings::isVorgangCreated,
UserSettings::isVorgangAssignedToUser,
UserSettings::isPostfachNachrichtFromAntragsteller,
UserSettings::isWiedervorlageOverdue)
UserSettings::isWiedervorlageDueToday)
.containsExactly(
NotificationsSendFor.NONE,
false,
UserSettingsTestFactory.VORGANG_ASSIGNED_TO_USER,
UserSettingsTestFactory.POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER,
UserSettingsTestFactory.WIEDERVORLAGE_OVERDUE);
UserSettingsTestFactory.WIEDERVORLAGE_DUE_TODAY);
}
}
......
......@@ -38,7 +38,7 @@ class UserSettingsTest {
void shouldHaveDefaultSettings() {
assertThat(UserSettings.createDefault()).usingRecursiveComparison().isEqualTo(
UserSettings.builder().notificationsSendFor(NotificationsSendFor.NONE).vorgangCreated(false).vorgangAssignedToUser(true)
.postfachNachrichtFromAntragsteller(true).wiedervorlageOverdue(true).build());
.postfachNachrichtFromAntragsteller(true).wiedervorlageDueToday(true).build());
}
}
......
......@@ -29,7 +29,7 @@ public class UserSettingsTestFactory {
public static final boolean VORGANG_CREATED = false;
public static final boolean VORGANG_ASSIGNED_TO_USER = true;
public static final boolean POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER = true;
public static final boolean WIEDERVORLAGE_OVERDUE = true;
public static final boolean WIEDERVORLAGE_DUE_TODAY = true;
public static UserSettings create() {
return createBuilder().build();
......@@ -41,6 +41,6 @@ public class UserSettingsTestFactory {
.vorgangCreated(VORGANG_CREATED)
.vorgangAssignedToUser(VORGANG_ASSIGNED_TO_USER)
.postfachNachrichtFromAntragsteller(POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER)
.wiedervorlageOverdue(WIEDERVORLAGE_OVERDUE);
.wiedervorlageDueToday(WIEDERVORLAGE_DUE_TODAY);
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment