Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions server/lombok.config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lombok.addLombokGeneratedAnnotation = true
6 changes: 6 additions & 0 deletions server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,12 @@
</goals>
</execution>
</executions>
<configuration>
<excludes>
<exclude>**/com/studybuddies/server/services/**</exclude>
<exclude>**/com/studybuddies/server/web/mapper/MeetingMapperImpl.class</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public class MeetingEntity {
String title;

String description;
String links;

@Column(nullable = false)
LocalDateTime date_from;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.studybuddies.server.web.mapper.exceptions.DateFormatException;
import com.studybuddies.server.web.mapper.exceptions.EndDateAfterStartDateException;
import com.studybuddies.server.web.mapper.exceptions.InvalidRepeatStringException;
import com.studybuddies.server.web.mapper.exceptions.TimeFormatException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
Expand All @@ -17,11 +16,6 @@ protected ResponseEntity<?> handleDateFormatException() {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Wrong date format. Please use dd-MM-yyyy:HH:mm");
}

@ExceptionHandler(TimeFormatException.class)
protected ResponseEntity<?> handleTimeFormatException() {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Minutes must be divisible by 15");
}

@ExceptionHandler(InvalidRepeatStringException.class)
protected ResponseEntity<?> handleInvalidRepeatStringException() {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Not allowed. (daily, weekly, monthly, never)");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.studybuddies.server.web.dto;

import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class MeetingChangeRequest {
public String title;
public String description;
public String links;
public String date_from;
public String date_until;
public String repeatable;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ public class MeetingCreationRequest {
@NotBlank
public String title;
public String description;
public String links;
@NotBlank
public String date_from;
@NotBlank
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
import jakarta.validation.constraints.NotBlank;

public class MeetingResponse {
@NotBlank
public Long id;
@NotBlank
public String title;
public String description;
public String links;
@NotBlank
public String date_from;
@NotBlank
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public interface MeetingMapper {
// Mappings for MeetingCreationRequestToMeetingEntity
@Mapping(source = "title", target = "title")
@Mapping(source = "description", target = "description")
@Mapping(source = "links", target = "links")
@Mapping(source = "place", target = "place")
@Mapping(source = "date_from", target = "date_from", qualifiedByName = "stringToLocalDate")
@Mapping(source = "date_until", target = "date_until", qualifiedByName = "stringToLocalDate")
Expand All @@ -25,9 +24,9 @@ public interface MeetingMapper {
MeetingEntity MeetingCreationRequestToMeetingEntity(MeetingCreationRequest meetingCreationRequest);

// Mappings for MeetingChangeRequestToMeetingEntity
@Mapping(source = "id", target = "id")
@Mapping(source = "title", target = "title")
@Mapping(source = "description", target = "description")
@Mapping(source = "links", target = "links")
@Mapping(source = "place", target = "place")
@Mapping(source = "date_from", target = "date_from", qualifiedByName = "changeStringToLocalDate")
@Mapping(source = "date_until", target = "date_until", qualifiedByName = "changeStringToLocalDate")
Expand All @@ -40,10 +39,6 @@ default void validate(@MappingTarget MeetingEntity meetingEntity) {
LocalDateTime start = meetingEntity.getDate_from();
LocalDateTime end = meetingEntity.getDate_until();

if(start == null || end == null) {
return;
}

if(start.isAfter(end)) {
throw new EndDateAfterStartDateException("");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.studybuddies.server.domain.Repeat;
import com.studybuddies.server.web.mapper.exceptions.DateFormatException;
import com.studybuddies.server.web.mapper.exceptions.InvalidRepeatStringException;
import com.studybuddies.server.web.mapper.exceptions.TimeFormatException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
Expand Down Expand Up @@ -52,15 +51,12 @@ private Repeat stringToRepeat(String repeatString) {
}

private LocalDateTime stringToLocalDateTime(String dateString) {
// only accept values in following format: dd-MM-yyyy:hh:mm while mm is divisible by 15
// only accept values in following format: dd-MM-yyyy:hh:mm
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy:HH:mm");
LocalDateTime dueDate;

try {
dueDate = LocalDateTime.parse(dateString, format);
if(dueDate.getMinute() % 15 != 0) {
throw new TimeFormatException("");
}
} catch(DateTimeParseException e) {
throw new DateFormatException("");
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package com.studybuddies.server.services;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.studybuddies.server.domain.MeetingEntity;
import com.studybuddies.server.domain.Repeat;
import com.studybuddies.server.persistance.MeetingRepository;
import com.studybuddies.server.services.exceptions.MeetingNotFoundException;
import com.studybuddies.server.web.dto.MeetingChangeRequest;
import com.studybuddies.server.web.dto.MeetingCreationRequest;
import com.studybuddies.server.web.mapper.MeetingMapper;
import com.studybuddies.server.web.mapper.exceptions.InvalidRepeatStringException;
import java.time.LocalDateTime;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
Expand All @@ -38,7 +40,6 @@ public void saveMeetingToDatabaseTest_invalidRepeatable_throwsException() {
MeetingCreationRequest mockMeeting = new MeetingCreationRequest();
mockMeeting.setTitle("Invalid Repeatable Meeting");
mockMeeting.setDescription("Meeting with invalid repeatable value.");
mockMeeting.setLinks("");
mockMeeting.setPlace("");
mockMeeting.setRepeatable("invalid_value");
mockMeeting.setDate_from("23-11-2020:15:30");
Expand All @@ -56,4 +57,103 @@ public void saveMeetingToDatabaseTest_invalidRepeatable_throwsException() {
// Verify that save was never called
verify(meetingRepository, never()).save(any(MeetingEntity.class));
}
@Test
public void saveMeetingToDatabase_success() {
// given
MeetingCreationRequest mockMeeting = new MeetingCreationRequest();
mockMeeting.setTitle("Valid Meeting");
mockMeeting.setDescription("");
mockMeeting.setPlace("");
mockMeeting.setRepeatable("NEVER");
mockMeeting.setDate_from("23-11-2020:15:30");
mockMeeting.setDate_until("26-11-2020:15:30");

MeetingEntity mockMeetingEntity = new MeetingEntity();
mockMeetingEntity.setId(1L);

when(meetingMapper.MeetingCreationRequestToMeetingEntity(mockMeeting)).thenReturn(mockMeetingEntity);

when(meetingRepository.save(any(MeetingEntity.class))).thenReturn(mockMeetingEntity);

// when
Long meetingId = meetingService.saveMeetingToDatabase(mockMeeting);

// then
assertNotNull(meetingId);
assertEquals(1L, meetingId);

verify(meetingMapper).MeetingCreationRequestToMeetingEntity(mockMeeting);
verify(meetingRepository).save(mockMeetingEntity);
}

@Test
public void changeMeetingInDatabaseTest_meetingNotFound_throwsException() {
// given
Long meetingId = 1L;
MeetingChangeRequest mockChangeRequest = new MeetingChangeRequest();
when(meetingRepository.findById(meetingId)).thenReturn(Optional.empty());

// then
assertThrows(MeetingNotFoundException.class, () -> {
meetingService.changeMeetingInDatabase(meetingId, mockChangeRequest);
});

verify(meetingRepository, never()).save(any(MeetingEntity.class));
}

@Test
public void retrieveMeetingFromDatabaseTest_meetingNotFound_throwsException() {
// given
Long meetingId = 1L;
when(meetingRepository.findById(meetingId)).thenReturn(Optional.empty());

// then
assertThrows(MeetingNotFoundException.class, () -> {
meetingService.retrieveMeetingFromDatabase(meetingId);
});
}

@Test
public void deleteMeetingFromDatabaseTest_validId_deletesMeeting() {
// given
Long meetingId = 1L;

// when
meetingService.deleteMeetingFromDatabase(meetingId);

// then
verify(meetingRepository, times(1)).deleteById(meetingId);
}
@Test
public void changeMeetingInDatabaseTest_updatesOnlyNonNullFields() {
// given
Long meetingId = 1L;
MeetingEntity existingMeeting = new MeetingEntity();
existingMeeting.setTitle("Old Title");
existingMeeting.setDescription("Old Description");
existingMeeting.setPlace("Old Place");

MeetingChangeRequest mockChangeRequest = new MeetingChangeRequest();
mockChangeRequest.setTitle("New Title"); // Should be updated
mockChangeRequest.setDescription(null); // Should NOT be updated
mockChangeRequest.setPlace(null); // Should NOT be updated

MeetingEntity changedMeeting = new MeetingEntity();
changedMeeting.setTitle("New Title");
changedMeeting.setDescription(null);
changedMeeting.setPlace(null);

when(meetingRepository.findById(meetingId)).thenReturn(Optional.of(existingMeeting));
when(meetingMapper.MeetingChangeRequestToMeetingEntity(mockChangeRequest)).thenReturn(changedMeeting);

// when
meetingService.changeMeetingInDatabase(meetingId, mockChangeRequest);

// then
assertEquals("New Title", existingMeeting.getTitle()); // Updated
assertEquals("Old Description", existingMeeting.getDescription()); // Not updated
assertEquals("Old Place", existingMeeting.getPlace()); // Not updated

verify(meetingRepository, times(1)).save(existingMeeting);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.studybuddies.server.web.mapper;

import static org.junit.jupiter.api.Assertions.*;

import com.studybuddies.server.domain.MeetingEntity;
import com.studybuddies.server.web.mapper.exceptions.EndDateAfterStartDateException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mapstruct.factory.Mappers;

import java.time.LocalDateTime;

@ExtendWith(MockitoExtension.class)
class MeetingMapperTest {

private MeetingMapper meetingMapper;

// Mockito cant work with interfaces apparently
@BeforeEach
void setUp() {
meetingMapper = Mappers.getMapper(MeetingMapper.class);
}

@Test
void validate_shouldThrowException_whenStartDateIsAfterEndDate() {
// given
MeetingEntity meetingEntity = new MeetingEntity();
meetingEntity.setDate_from(LocalDateTime.of(2024, 2, 10, 10, 0));
meetingEntity.setDate_until(LocalDateTime.of(2024, 2, 9, 10, 0)); // End date before start date

// when then
EndDateAfterStartDateException exception = assertThrows(
EndDateAfterStartDateException.class,
() -> meetingMapper.validate(meetingEntity)
);
assertNotNull(exception);
}

@Test
void validate_shouldNotThrowException_whenStartDateIsBeforeEndDate() {
// Arrange
MeetingEntity meetingEntity = new MeetingEntity();
meetingEntity.setDate_from(LocalDateTime.of(2024, 2, 9, 10, 0));
meetingEntity.setDate_until(LocalDateTime.of(2024, 2, 10, 10, 0));

// Act & Assert
assertDoesNotThrow(() -> meetingMapper.validate(meetingEntity));
}
}
Loading
Loading