Skip to content

Commit 7d6af74

Browse files
Konstantin PankratovKonstantin Pankratov
authored andcommitted
Enhance update process for meetings. Fix tests to suit latest features
1 parent 9e7f636 commit 7d6af74

File tree

10 files changed

+112
-24
lines changed

10 files changed

+112
-24
lines changed

server/src/main/java/com/studybuddies/server/services/MeetingService.java

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
import com.studybuddies.server.domain.MeetingEntity;
66
import com.studybuddies.server.domain.UserEntity;
77
import com.studybuddies.server.persistance.MeetingRepository;
8+
import com.studybuddies.server.services.exceptions.InvalidUUIDException;
89
import com.studybuddies.server.services.exceptions.MeetingNotFoundException;
910
import com.studybuddies.server.web.dto.MeetingChangeRequest;
1011
import com.studybuddies.server.web.dto.MeetingCreationRequest;
1112
import com.studybuddies.server.web.dto.MeetingResponse;
1213
import com.studybuddies.server.web.mapper.MeetingMapper;
14+
import com.studybuddies.server.web.mapper.MeetingMapperUtils;
1315
import jakarta.transaction.Transactional;
1416
import java.util.ArrayList;
15-
import java.util.function.Consumer;
1617
import lombok.AllArgsConstructor;
1718
import org.springframework.stereotype.Service;
1819

@@ -25,6 +26,7 @@ public class MeetingService {
2526
private final MeetingMapper meetingMapper;
2627
private final MeetingRepository meetingRepository;
2728
private final UserService userService;
29+
private final MeetingMapperUtils meetingMapperUtils;
2830

2931
@Transactional
3032
public Long saveMeetingToDatabase(MeetingCreationRequest mcr, String uuid) {
@@ -47,15 +49,15 @@ public void changeMeetingInDatabase(Long id, MeetingChangeRequest meetingChangeR
4749
throw new MeetingNotFoundException("");
4850
}
4951

50-
MeetingEntity changedMeeting = meetingMapper.meetingChangeRequestToMeetingEntity(
51-
meetingChangeRequest);
52+
if(meetingChangeRequest.getCreator() != null
53+
&& !userService.existsByUUID(UUIDService.parseUUID(uuid))
54+
) {
55+
throw new InvalidUUIDException("");
56+
}
57+
58+
MeetingEntity changedMeetingEntity = meetingMapper.meetingChangeRequestToMeetingEntity(meetingChangeRequest);
59+
MergingService.mergeObjects(changedMeetingEntity, meetingEntity);
5260

53-
setIfNotNull(changedMeeting.getTitle(), meetingEntity::setTitle);
54-
setIfNotNull(changedMeeting.getDescription(), meetingEntity::setDescription);
55-
setIfNotNull(changedMeeting.getDate_from(), meetingEntity::setDate_from);
56-
setIfNotNull(changedMeeting.getDate_until(), meetingEntity::setDate_until);
57-
setIfNotNull(changedMeeting.getPlace(), meetingEntity::setPlace);
58-
setIfNotNull(changedMeeting.getRepeatable(), meetingEntity::setRepeatable);
5961
meetingMapper.validate(meetingEntity);
6062
meetingRepository.save(meetingEntity);
6163
}
@@ -97,10 +99,4 @@ public ArrayList<MeetingResponse> findAllMeetingEntities() {
9799
}
98100
return meetings;
99101
}
100-
101-
private <T> void setIfNotNull(T value, Consumer<T> setFunc) {
102-
if (value != null) {
103-
setFunc.accept(value);
104-
}
105-
}
106102
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.studybuddies.server.services;
2+
3+
import com.studybuddies.server.services.exceptions.MergeFailedException;
4+
import java.lang.reflect.Field;
5+
import org.springframework.stereotype.Service;
6+
7+
@Service
8+
public class MergingService {
9+
public static void mergeObjects(Object source, Object target) {
10+
if (source == null || target == null) {
11+
throw new IllegalArgumentException("Source and target objects must not be null");
12+
}
13+
14+
Class<?> sourceClass = source.getClass();
15+
Class<?> targetClass = target.getClass();
16+
17+
if (!sourceClass.equals(targetClass)) {
18+
throw new IllegalArgumentException("Source and target objects must be of the same type");
19+
}
20+
21+
Field[] fields = sourceClass.getDeclaredFields();
22+
23+
for (Field field : fields) {
24+
field.setAccessible(true);
25+
try {
26+
Object sourceValue = field.get(source);
27+
if (sourceValue != null) {
28+
field.set(target, sourceValue);
29+
}
30+
} catch (IllegalAccessException e) {
31+
throw new MergeFailedException("");
32+
}
33+
}
34+
}
35+
}

server/src/main/java/com/studybuddies/server/services/UserService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,9 @@ public void deleteUser(String targetUuid, String senderUuid) {
4545
userRepository.deleteById(UUIDService.parseUUID(targetUuid));
4646
}
4747
}
48+
49+
@Transactional
50+
public boolean existsByUUID(UUID uuid) {
51+
return userRepository.existsById(uuid);
52+
}
4853
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.studybuddies.server.services.exceptions;
2+
3+
public class MergeFailedException extends StudyBuddiesException {
4+
5+
public MergeFailedException(String message) {
6+
super(message);
7+
}
8+
}

server/src/main/java/com/studybuddies/server/web/GlobalExceptionHandler.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.studybuddies.server.services.exceptions.InvalidUUIDException;
44
import com.studybuddies.server.services.exceptions.MeetingNotFoundException;
5+
import com.studybuddies.server.services.exceptions.MergeFailedException;
56
import com.studybuddies.server.services.exceptions.UserAccountSetupNotFinished;
67
import com.studybuddies.server.web.mapper.exceptions.AccountSetupAlreadyFinished;
78
import com.studybuddies.server.web.mapper.exceptions.DateFormatException;
@@ -49,4 +50,8 @@ protected ResponseEntity<?> handleInvalidUUIDException() {
4950
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid UUID provided");
5051
}
5152

53+
@ExceptionHandler(MergeFailedException.class)
54+
protected ResponseEntity<?> handleMergeFailedException() {
55+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Updating failed. Please create an issue on GitHub");
56+
}
5257
}

server/src/main/java/com/studybuddies/server/web/dto/MeetingChangeRequest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ public class MeetingChangeRequest {
1212
public String date_until;
1313
public String repeatable;
1414
public String place;
15+
public String creator;
1516
}

server/src/main/java/com/studybuddies/server/web/dto/MeetingResponse.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ public class MeetingResponse {
1414
public String date_until;
1515
public String repeatable;
1616
public String place;
17+
public String creator;
1718
}

server/src/main/java/com/studybuddies/server/web/mapper/MeetingMapper.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public interface MeetingMapper {
2929
@Mapping(source = "date_from", target = "date_from")
3030
@Mapping(source = "date_until", target = "date_until")
3131
@Mapping(source = "repeatable", target = "repeatable")
32+
@Mapping(source = "creator", target = "creator", qualifiedByName = "userEntityToUUIDString")
3233
MeetingResponse meetingEntityToMeetingResponse(MeetingEntity meetingEntity);
3334

3435
// Mappings for meetingChangeRequestToMeetingEntity
@@ -37,11 +38,15 @@ public interface MeetingMapper {
3738
@Mapping(source = "place", target = "place")
3839
@Mapping(source = "date_from", target = "date_from", qualifiedByName = "changeStringToLocalDate")
3940
@Mapping(source = "date_until", target = "date_until", qualifiedByName = "changeStringToLocalDate")
40-
@Mapping(source = "repeatable", target = "repeatable", qualifiedByName = "stringToRepeatEnum")
41+
@Mapping(source = "repeatable", target = "repeatable", qualifiedByName = "changeStringToRepeatEnum")
42+
@Mapping(source = "creator", target = "creator", qualifiedByName = "stringToUserEntity")
4143
MeetingEntity meetingChangeRequestToMeetingEntity(MeetingChangeRequest meetingChangeRequest);
4244

4345
@AfterMapping
4446
default void validate(@MappingTarget MeetingEntity meetingEntity) {
47+
if(meetingEntity.getDate_from() == null || meetingEntity.getDate_until() == null) {
48+
return;
49+
}
4550
LocalDateTime start = meetingEntity.getDate_from();
4651
LocalDateTime end = meetingEntity.getDate_until();
4752

server/src/main/java/com/studybuddies/server/web/mapper/MeetingMapperUtils.java

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,36 @@
11
package com.studybuddies.server.web.mapper;
22

33
import com.studybuddies.server.domain.Repeat;
4+
import com.studybuddies.server.domain.UserEntity;
5+
import com.studybuddies.server.services.UUIDService;
6+
import com.studybuddies.server.services.UserService;
47
import com.studybuddies.server.web.mapper.exceptions.DateFormatException;
58
import com.studybuddies.server.web.mapper.exceptions.InvalidRepeatStringException;
69
import java.time.LocalDateTime;
710
import java.time.format.DateTimeFormatter;
811
import java.time.format.DateTimeParseException;
12+
import lombok.AllArgsConstructor;
913
import org.mapstruct.Named;
1014
import org.springframework.stereotype.Component;
1115

1216
@Component
17+
@AllArgsConstructor
1318
public class MeetingMapperUtils {
19+
20+
private final UserService userService;
21+
1422
// MeetingCreationRequest
1523
@Named("stringToLocalDate")
1624
public LocalDateTime stringToLocalDate(String dateString) {
1725
return stringToLocalDateTime(dateString);
1826
}
1927

28+
// MeetingCreationRequest
29+
@Named("stringToRepeatEnum")
30+
public Repeat stringToRepeatEnum(String repeatString) {
31+
return stringToRepeat(repeatString);
32+
}
33+
2034
// MeetingChangeRequest
2135
@Named("changeStringToLocalDate")
2236
public LocalDateTime changeStringToLocalDate(String dateString) {
@@ -26,20 +40,29 @@ public LocalDateTime changeStringToLocalDate(String dateString) {
2640
return stringToLocalDateTime(dateString);
2741
}
2842

29-
// MeetingCreationRequest
30-
@Named("stringToRepeatEnum")
31-
public Repeat stringToRepeatEnum(String repeatString) {
32-
return stringToRepeat(repeatString);
33-
}
34-
3543
// MeetingChangeRequest
3644
@Named("changeStringToRepeatEnum")
3745
public Repeat changeStringToRepeatEnum(String repeatString) {
3846
if (repeatString == null || repeatString.trim().isEmpty()) {
3947
return null;
4048
}
4149
return stringToRepeat(repeatString);
50+
}
51+
52+
@Named("stringToUserEntity")
53+
public UserEntity stringToUserEntity(String uuidString) {
54+
if(uuidString == null || uuidString.trim().isEmpty()) {
55+
return null;
56+
}
57+
return userService.findByUUID(UUIDService.parseUUID(uuidString));
58+
}
4259

60+
@Named("userEntityToUUIDString")
61+
public String userEntityToUUIDString(UserEntity userEntity) {
62+
if(userEntity == null) {
63+
return null;
64+
}
65+
return userEntity.getUuid().toString();
4366
}
4467

4568
private Repeat stringToRepeat(String repeatString) {

server/src/test/java/com/studybuddies/server/services/MeetingServiceTest.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ public void saveMeetingToDatabaseTest_invalidRepeatable_throwsException() {
5050
// when
5151
when(meetingMapper.meetingCreationRequestToMeetingEntity(mockMeeting))
5252
.thenThrow(new InvalidRepeatStringException("Invalid repeatable value"));
53-
when(userService.findByUUID(uuid)).thenReturn(any(UserEntity.class));
5453

5554
// then
5655
assertThrows(InvalidRepeatStringException.class, () -> {
@@ -95,6 +94,7 @@ public void saveMeetingToDatabase_success() {
9594
public void changeMeetingInDatabaseTest_meetingNotFound_throwsException() {
9695
// given
9796
UserEntity mockUser = new UserEntity();
97+
mockUser.setUuid(UUID.randomUUID());
9898

9999
Long meetingId = 1L;
100100
MeetingChangeRequest mockChangeRequest = new MeetingChangeRequest();
@@ -123,8 +123,14 @@ public void retrieveMeetingFromDatabaseTest_meetingNotFound_throwsException() {
123123
@Test
124124
public void deleteMeetingFromDatabaseTest_validId_deletesMeeting() {
125125
// given
126-
UserEntity mockUser = new UserEntity();
127126
Long meetingId = 1L;
127+
UserEntity mockUser = new UserEntity();
128+
mockUser.setUuid(UUID.randomUUID());
129+
130+
MeetingEntity mockMeetingEntity = new MeetingEntity();
131+
mockMeetingEntity.setId(meetingId);
132+
mockMeetingEntity.setCreator(mockUser);
133+
when(meetingRepository.findById(meetingId)).thenReturn(Optional.of(mockMeetingEntity));
128134

129135
// when
130136
meetingService.deleteMeetingFromDatabase(meetingId, mockUser.getUuid().toString());
@@ -136,11 +142,14 @@ public void deleteMeetingFromDatabaseTest_validId_deletesMeeting() {
136142
public void changeMeetingInDatabaseTest_updatesOnlyNonNullFields() {
137143
// given
138144
UserEntity mockUser = new UserEntity();
145+
mockUser.setUuid(UUID.randomUUID());
139146
Long meetingId = 1L;
140147
MeetingEntity existingMeeting = new MeetingEntity();
141148
existingMeeting.setTitle("Old Title");
142149
existingMeeting.setDescription("Old Description");
143150
existingMeeting.setPlace("Old Place");
151+
existingMeeting.setCreator(mockUser);
152+
144153

145154
MeetingChangeRequest mockChangeRequest = new MeetingChangeRequest();
146155
mockChangeRequest.setTitle("New Title"); // Should be updated

0 commit comments

Comments
 (0)