cleans up after trying to introduce integration tests
This commit is contained in:
18
pom.xml
18
pom.xml
@@ -58,25 +58,7 @@
|
||||
<artifactId>reactor-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>1.17.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>mongodb</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.flapdoodle.embed</groupId>
|
||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||
<version>3.4.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>app</finalName>
|
||||
<plugins>
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
spring:
|
||||
application:
|
||||
name: reactive-timesheet-app
|
||||
# data:
|
||||
# database: db_1
|
||||
# host: localhost
|
||||
# port: 27017
|
||||
|
||||
mongodb:
|
||||
embedded:
|
||||
version: 3.4.5
|
||||
data:
|
||||
mongodb:
|
||||
database: db_1
|
||||
host: localhost
|
||||
port: 27017
|
||||
@@ -1,92 +0,0 @@
|
||||
package net.szymonsawicki.reactivetimesheetapp.application.service;
|
||||
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.team.Team;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.team.TeamUtils;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.team.repository.TeamRepository;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.user.User;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.user.type.Role;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||
import org.springframework.test.context.DynamicPropertySource;
|
||||
import org.testcontainers.containers.MongoDBContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
import org.testcontainers.utility.DockerImageName;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.util.List;
|
||||
|
||||
@Testcontainers
|
||||
@SpringBootTest
|
||||
public class ITTest {
|
||||
|
||||
@Autowired
|
||||
private TeamRepository teamRepository;
|
||||
|
||||
@Container
|
||||
public static MongoDBContainer container = new MongoDBContainer(DockerImageName.parse("mongo:4.4.3"));
|
||||
|
||||
@BeforeAll
|
||||
static void initAll() {
|
||||
container.start();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void classAll() {
|
||||
container.stop();
|
||||
}
|
||||
|
||||
@DynamicPropertySource
|
||||
static void setProperties(DynamicPropertyRegistry registry) {
|
||||
registry.add("spring.data.mongodb.port", () -> container.getBoundPortNumbers().get(0));
|
||||
registry.add("spring.data.mongodb.host", () -> container.getHost());
|
||||
}
|
||||
|
||||
@Test
|
||||
void containerStartsAndPublicPortIsAvailable() {
|
||||
|
||||
|
||||
assertThatPortIsAvailable(container);
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveEmployee() {
|
||||
|
||||
String userId = "21344r23r34";
|
||||
String teamId = "2r872394r578";
|
||||
String teamName = "Some team";
|
||||
String username = "testsusrname";
|
||||
Role role = Role.DEVELOPER;
|
||||
|
||||
var member = User.builder()
|
||||
.username(username)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var team = Team.builder()
|
||||
.id(teamId)
|
||||
.name(teamName)
|
||||
.members(List.of(member))
|
||||
.build();
|
||||
|
||||
var insertedTeam = teamRepository.save(team);
|
||||
|
||||
var insertedTeamId = TeamUtils.toId.apply(teamRepository.save(team).block());
|
||||
|
||||
}
|
||||
|
||||
private void assertThatPortIsAvailable(MongoDBContainer container) {
|
||||
try {
|
||||
new Socket(container.getContainerIpAddress(), container.getFirstMappedPort());
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError("The expected port " + container.getFirstMappedPort() + " is not available!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,134 @@
|
||||
package net.szymonsawicki.reactivetimesheetapp.application.service;
|
||||
|
||||
import net.szymonsawicki.reactivetimesheetapp.application.service.utils.TimesheetAppMongoDbContainer;
|
||||
import net.szymonsawicki.reactivetimesheetapp.application.service.exception.TeamServiceException;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.team.Team;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.team.TeamUtils;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.team.dto.CreateTeamDto;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.team.dto.GetTeamDto;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.team.repository.TeamRepository;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.user.User;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.user.UserUtils;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.user.dto.GetUserDto;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.user.repository.UserRepository;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.user.type.Role;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.testcontainers.containers.MongoDBContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@SpringBootTest
|
||||
@ExtendWith(SpringExtension.class)
|
||||
public class TeamServiceTest {
|
||||
@Container
|
||||
private static final MongoDBContainer MONGO_DB_CONTAINER = TimesheetAppMongoDbContainer.getInstance();
|
||||
|
||||
@TestConfiguration
|
||||
public static class TeamServiceTestConfiguration {
|
||||
|
||||
@MockBean
|
||||
public TeamRepository teamRepository;
|
||||
@MockBean
|
||||
public UserRepository userRepository;
|
||||
|
||||
@Bean
|
||||
public TeamService teamService() {
|
||||
return new TeamService(teamRepository, userRepository);
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private TeamRepository teamRepository;
|
||||
public TeamRepository teamRepository;
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
public UserRepository userRepository;
|
||||
|
||||
@Autowired
|
||||
public TeamService teamService;
|
||||
|
||||
@Captor
|
||||
public ArgumentCaptor<List<User>> usersCaptor;
|
||||
|
||||
@Test
|
||||
void shouldReturnTeamOnGetById() {
|
||||
public void shouldReturnThreeTeamsOnFindAll() {
|
||||
|
||||
String userId1 = "21344r23r34";
|
||||
String userId2 = "21344r23r34";
|
||||
String teamId1 = "2r872394r578";
|
||||
String teamId2 = "2r872394r578";
|
||||
String teamName1 = "Some team";
|
||||
String teamName2 = "Some team";
|
||||
String username1 = "testsusrname";
|
||||
String username2 = "testsusrname2";
|
||||
|
||||
var member1 = new GetUserDto(
|
||||
userId1,
|
||||
username1,
|
||||
"some password",
|
||||
null, teamId1);
|
||||
|
||||
var member2 = new GetUserDto(
|
||||
userId2,
|
||||
username2,
|
||||
"some password",
|
||||
null, teamId2);
|
||||
|
||||
var expectedTeam1 = new GetTeamDto(
|
||||
teamId1,
|
||||
teamName1,
|
||||
List.of(member1));
|
||||
|
||||
var expectedTeam2 = new GetTeamDto(
|
||||
teamId2,
|
||||
teamName2,
|
||||
List.of(member2));
|
||||
|
||||
var memberFromDb1 = User.builder()
|
||||
.id(userId1)
|
||||
.username(username1)
|
||||
.password("some password")
|
||||
.teamId(teamId1)
|
||||
.build();
|
||||
|
||||
var memberFromDb2 = User.builder()
|
||||
.id(userId2)
|
||||
.username(username2)
|
||||
.password("some password")
|
||||
.teamId(teamId2)
|
||||
.build();
|
||||
|
||||
var teamFromDb1 = Team.builder()
|
||||
.id(teamId1)
|
||||
.name(teamName1)
|
||||
.members(List.of(memberFromDb1))
|
||||
.build();
|
||||
|
||||
var teamFromDb2 = Team.builder()
|
||||
.id(teamId2)
|
||||
.name(teamName2)
|
||||
.members(List.of(memberFromDb2))
|
||||
.build();
|
||||
|
||||
Mockito.when(teamRepository.findAll())
|
||||
.thenReturn(Flux.just(teamFromDb1, teamFromDb2));
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.findAllTeams())
|
||||
.expectNext(expectedTeam1)
|
||||
.expectNext(expectedTeam2)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnTeamWithOneMemberOnGetById() {
|
||||
|
||||
String userId = "21344r23r34";
|
||||
String teamId = "2r872394r578";
|
||||
@@ -42,17 +142,311 @@ public class TeamServiceTest {
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var team = Team.builder()
|
||||
var teamEntityMono = Mono.just(Team.builder()
|
||||
.id(teamId)
|
||||
.name(teamName)
|
||||
.members(List.of(member))
|
||||
.build();
|
||||
.build());
|
||||
|
||||
var insertedTeam = teamRepository.save(team);
|
||||
Mockito.when(teamRepository.findById(Mockito.anyString()))
|
||||
.thenReturn(teamEntityMono);
|
||||
|
||||
var insertedTeamId = TeamUtils.toId.apply(insertedTeam.block());
|
||||
|
||||
StepVerifier.create(teamRepository.findById(insertedTeamId))
|
||||
.expectNextMatches(t -> TeamUtils.toMembers.apply(t).size() == 1)
|
||||
StepVerifier
|
||||
.create(teamService.findById(userId))
|
||||
.assertNext(team -> {
|
||||
Assertions.assertThat(team.name().equals(teamName));
|
||||
Assertions.assertThat(team.members()).hasSize(1);
|
||||
Assertions.assertThat(team.members().get(0).username()).isEqualTo(username);
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnErrorOnGetByIdWhenTeamMissing() {
|
||||
|
||||
Mockito.when(teamRepository.findById(Mockito.anyString()))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.findById("some id"))
|
||||
.expectErrorMatches(error -> error instanceof TeamServiceException && error.getMessage().equals("Team with given id doesn't exist"))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindTeamByName() {
|
||||
|
||||
String userId = "21344r23r34";
|
||||
String teamId = "2r872394r578";
|
||||
String teamName = "Some team";
|
||||
String username = "testsusrname";
|
||||
|
||||
var member = User.builder()
|
||||
.id(userId)
|
||||
.username(username)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var expectedMemberDto = new GetUserDto(
|
||||
userId,
|
||||
username,
|
||||
"some password",
|
||||
null, teamId);
|
||||
|
||||
|
||||
var teamMono = Mono.just(Team.builder()
|
||||
.id(teamId)
|
||||
.name(teamName)
|
||||
.members(List.of(member))
|
||||
.build());
|
||||
|
||||
Mockito.when(teamRepository.findByName(Mockito.anyString()))
|
||||
.thenReturn(teamMono);
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.findByName(teamName))
|
||||
.expectNextMatches(resultingTeam -> resultingTeam.name().equals(teamName))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnErrorOnGetTeamByNameWhenMissing() {
|
||||
|
||||
Mockito.when(teamRepository.findByName(Mockito.anyString()))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.findByName("some name"))
|
||||
.expectErrorMatches(error -> error instanceof TeamServiceException && error.getMessage().equals("Team with given name doesn't exist"))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateNewTeamWithMembers() {
|
||||
|
||||
String userId1 = "21344r23r34";
|
||||
String userId2 = "21344r23r34";
|
||||
String teamId = "2r872394r578";
|
||||
String teamName = "Some team";
|
||||
String username1 = "testsusrname";
|
||||
String username2 = "testsusrname2";
|
||||
|
||||
ArgumentCaptor<Team> saveTeamCaptor = ArgumentCaptor.forClass(Team.class);
|
||||
|
||||
var member1 = new GetUserDto(
|
||||
userId1,
|
||||
username1,
|
||||
"some password",
|
||||
null, null);
|
||||
|
||||
var member2 = new GetUserDto(
|
||||
userId2,
|
||||
username2,
|
||||
"some password",
|
||||
null, null);
|
||||
|
||||
var savedMember1 = User.builder()
|
||||
.id(userId1)
|
||||
.username(username1)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var savedMember2 = User.builder()
|
||||
.id(userId2)
|
||||
.username(username2)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var teamToCreateMono = Mono.just(new CreateTeamDto(
|
||||
teamName
|
||||
, List.of(member1, member2)));
|
||||
|
||||
var createdTeamMono = Mono.just(Team.builder()
|
||||
.id(teamId)
|
||||
.name(teamName)
|
||||
.members(List.of(savedMember1, savedMember2))
|
||||
.build());
|
||||
|
||||
Mockito.when(teamRepository.findByName(Mockito.anyString()))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
Mockito.when(teamRepository.save(saveTeamCaptor.capture()))
|
||||
.thenReturn(createdTeamMono);
|
||||
|
||||
Mockito.when(userRepository.saveAll(usersCaptor.capture()))
|
||||
.thenReturn(Flux.just(savedMember1, savedMember2));
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.addTeam(teamToCreateMono))
|
||||
.assertNext(team -> {
|
||||
Assertions.assertThat(team.name()).isEqualTo(teamName);
|
||||
Assertions.assertThat(team.members()).hasSize(2);
|
||||
Assertions.assertThat(team.members().stream().map(GetUserDto::username).toList()).containsAll(List.of(username1, username2));
|
||||
Assertions.assertThat(team.members().stream().filter(member -> !member.teamId().equals(teamId)).toList()).isEmpty();
|
||||
// captor assertions
|
||||
Assertions.assertThat(TeamUtils.toMembers.apply(saveTeamCaptor.getValue())).hasSize(2);
|
||||
Assertions.assertThat(TeamUtils.toId.apply(saveTeamCaptor.getValue())).isEqualTo(teamId);
|
||||
Assertions.assertThat(usersCaptor.getValue()).hasSize(2);
|
||||
})
|
||||
.verifyComplete();
|
||||
|
||||
InOrder inOrder = Mockito.inOrder(teamRepository, userRepository);
|
||||
|
||||
inOrder.verify(teamRepository, Mockito.times(1)).findByName(teamName);
|
||||
inOrder.verify(teamRepository, Mockito.times(1)).save(Mockito.any(Team.class));
|
||||
inOrder.verify(userRepository, Mockito.times(1)).saveAll(Mockito.any());
|
||||
inOrder.verify(teamRepository, Mockito.times(1)).save(Mockito.any(Team.class));
|
||||
|
||||
Mockito.verifyNoMoreInteractions(teamRepository, userRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnExistingTeamWhenNameIsTakenOnAddTeam() {
|
||||
|
||||
String userId1 = "21344r23r34";
|
||||
String userId2 = "tzuh";
|
||||
String teamId = "2r872394r578";
|
||||
String teamName = "Some team";
|
||||
String username1 = "testsusrname";
|
||||
String username2 = "testsusrname2";
|
||||
|
||||
var member1 = new GetUserDto(
|
||||
userId1,
|
||||
username1,
|
||||
"some password",
|
||||
null, null);
|
||||
|
||||
var member2 = new GetUserDto(
|
||||
userId2,
|
||||
username2,
|
||||
"some password",
|
||||
null, null);
|
||||
|
||||
var expectedMember1 = new GetUserDto(
|
||||
userId1,
|
||||
username1,
|
||||
"some password",
|
||||
null, teamId);
|
||||
|
||||
var expectedMember2 = new GetUserDto(
|
||||
userId2,
|
||||
username2,
|
||||
"some password",
|
||||
null, teamId);
|
||||
|
||||
var savedMember1 = User.builder()
|
||||
.id(userId1)
|
||||
.username(username1)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var savedMember2 = User.builder()
|
||||
.id(userId2)
|
||||
.username(username2)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var teamToCreateMono = Mono.just(new CreateTeamDto(
|
||||
teamName
|
||||
, List.of(member1, member2)));
|
||||
|
||||
var expectedTeamDto = new GetTeamDto(
|
||||
teamId,
|
||||
teamName
|
||||
, List.of(expectedMember1, expectedMember2));
|
||||
|
||||
var existingTeamMono = Mono.just(Team.builder()
|
||||
.id(teamId)
|
||||
.name(teamName)
|
||||
.members(List.of(savedMember1, savedMember2))
|
||||
.build());
|
||||
|
||||
Mockito.when(teamRepository.findByName(Mockito.anyString()))
|
||||
.thenReturn(existingTeamMono);
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.addTeam(teamToCreateMono))
|
||||
.expectNext(expectedTeamDto)
|
||||
.verifyComplete();
|
||||
|
||||
Mockito.verify(teamRepository, Mockito.never())
|
||||
.save(Mockito.any());
|
||||
Mockito.verify(userRepository, Mockito.never())
|
||||
.saveAll(Mockito.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ShouldDeleteTeamOnDelete() {
|
||||
|
||||
String userId1 = "21344r23r34";
|
||||
String userId2 = "21344r23r34";
|
||||
String teamId = "2r872394r578";
|
||||
String teamName = "Some team";
|
||||
String username1 = "testsusrname";
|
||||
String username2 = "testsusrname2";
|
||||
|
||||
var existingMember1 = User.builder()
|
||||
.id(userId1)
|
||||
.username(username1)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var existingMember2 = User.builder()
|
||||
.id(userId2)
|
||||
.username(username2)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var existingTeam = Team.builder()
|
||||
.id(teamId)
|
||||
.name(teamName)
|
||||
.members(List.of(existingMember1, existingMember2))
|
||||
.build();
|
||||
|
||||
Mockito.when(teamRepository.findById(Mockito.anyString()))
|
||||
.thenReturn(Mono.just(existingTeam));
|
||||
|
||||
Mockito.when(userRepository.saveAll(usersCaptor.capture()))
|
||||
.thenReturn(Flux.just(existingMember1, existingMember2));
|
||||
|
||||
Mockito.when(teamRepository.delete(Mockito.anyString()))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.deleteTeam(teamId))
|
||||
.assertNext(team -> {
|
||||
Assertions.assertThat(team.name()).isEqualTo(teamName);
|
||||
Assertions.assertThat(team.members()).hasSize(2);
|
||||
Assertions.assertThat(team.members().stream().map(GetUserDto::username).toList()).containsAll(List.of(username1, username2));
|
||||
Assertions.assertThat(team.members().stream().filter(member -> !member.teamId().equals(teamId)).toList()).isEmpty();
|
||||
// captor assertions
|
||||
Assertions.assertThat(usersCaptor.getValue()).hasSize(2);
|
||||
Assertions.assertThat(usersCaptor.getValue().stream().filter(user -> UserUtils.toTeamId.apply(user) != null).toList()).isEmpty();
|
||||
})
|
||||
.verifyComplete();
|
||||
|
||||
Mockito.verify(teamRepository, Mockito.times(1))
|
||||
.delete(teamId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnErrorOnDeleteWhenNotExist() {
|
||||
|
||||
Mockito.when(teamRepository.findById(Mockito.anyString()))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.deleteTeam("some id"))
|
||||
.expectErrorMatches(error -> error instanceof TeamServiceException && error.getMessage().equals("cannot find team to delete"))
|
||||
.verify();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package net.szymonsawicki.reactivetimesheetapp.application.service.utils;
|
||||
|
||||
import org.testcontainers.containers.MongoDBContainer;
|
||||
|
||||
public class TimesheetAppMongoDbContainer extends MongoDBContainer {
|
||||
|
||||
private static final String IMAGE_VERSION = "mongo:4.0.10";
|
||||
|
||||
private static MongoDBContainer container;
|
||||
|
||||
public static synchronized MongoDBContainer getInstance() {
|
||||
if (container == null) {
|
||||
container = new TimesheetAppMongoDbContainer();
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
private TimesheetAppMongoDbContainer() {
|
||||
super(IMAGE_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
super.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
// do nothing, JVM handles shut down
|
||||
}
|
||||
}
|
||||
@@ -1,453 +0,0 @@
|
||||
package unit_tests.net.szymonsawicki.reactivetimesheetapp.application.service;
|
||||
|
||||
import net.szymonsawicki.reactivetimesheetapp.application.service.TeamService;
|
||||
import net.szymonsawicki.reactivetimesheetapp.application.service.exception.TeamServiceException;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.team.Team;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.team.TeamUtils;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.team.dto.CreateTeamDto;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.team.dto.GetTeamDto;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.team.repository.TeamRepository;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.user.User;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.user.UserUtils;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.user.dto.GetUserDto;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.user.repository.UserRepository;
|
||||
import net.szymonsawicki.reactivetimesheetapp.domain.user.type.Role;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
public class TeamServiceTest {
|
||||
|
||||
@TestConfiguration
|
||||
public static class TeamServiceTestConfiguration {
|
||||
|
||||
@MockBean
|
||||
public TeamRepository teamRepository;
|
||||
@MockBean
|
||||
public UserRepository userRepository;
|
||||
|
||||
@Bean
|
||||
public TeamService teamService() {
|
||||
return new TeamService(teamRepository, userRepository);
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public TeamRepository teamRepository;
|
||||
@Autowired
|
||||
public UserRepository userRepository;
|
||||
|
||||
@Autowired
|
||||
public TeamService teamService;
|
||||
|
||||
@Captor
|
||||
public ArgumentCaptor<List<User>> usersCaptor;
|
||||
|
||||
@Test
|
||||
public void shouldReturnThreeTeamsOnFindAll() {
|
||||
|
||||
String userId1 = "21344r23r34";
|
||||
String userId2 = "21344r23r34";
|
||||
String teamId1 = "2r872394r578";
|
||||
String teamId2 = "2r872394r578";
|
||||
String teamName1 = "Some team";
|
||||
String teamName2 = "Some team";
|
||||
String username1 = "testsusrname";
|
||||
String username2 = "testsusrname2";
|
||||
|
||||
var member1 = new GetUserDto(
|
||||
userId1,
|
||||
username1,
|
||||
"some password",
|
||||
null, teamId1);
|
||||
|
||||
var member2 = new GetUserDto(
|
||||
userId2,
|
||||
username2,
|
||||
"some password",
|
||||
null, teamId2);
|
||||
|
||||
var expectedTeam1 = new GetTeamDto(
|
||||
teamId1,
|
||||
teamName1,
|
||||
List.of(member1));
|
||||
|
||||
var expectedTeam2 = new GetTeamDto(
|
||||
teamId2,
|
||||
teamName2,
|
||||
List.of(member2));
|
||||
|
||||
var memberFromDb1 = User.builder()
|
||||
.id(userId1)
|
||||
.username(username1)
|
||||
.password("some password")
|
||||
.teamId(teamId1)
|
||||
.build();
|
||||
|
||||
var memberFromDb2 = User.builder()
|
||||
.id(userId2)
|
||||
.username(username2)
|
||||
.password("some password")
|
||||
.teamId(teamId2)
|
||||
.build();
|
||||
|
||||
var teamFromDb1 = Team.builder()
|
||||
.id(teamId1)
|
||||
.name(teamName1)
|
||||
.members(List.of(memberFromDb1))
|
||||
.build();
|
||||
|
||||
var teamFromDb2 = Team.builder()
|
||||
.id(teamId2)
|
||||
.name(teamName2)
|
||||
.members(List.of(memberFromDb2))
|
||||
.build();
|
||||
|
||||
Mockito.when(teamRepository.findAll())
|
||||
.thenReturn(Flux.just(teamFromDb1, teamFromDb2));
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.findAllTeams())
|
||||
.expectNext(expectedTeam1)
|
||||
.expectNext(expectedTeam2)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnTeamWithOneMemberOnGetById() {
|
||||
|
||||
String userId = "21344r23r34";
|
||||
String teamId = "2r872394r578";
|
||||
String teamName = "Some team";
|
||||
String username = "testsusrname";
|
||||
Role role = Role.DEVELOPER;
|
||||
|
||||
var member = User.builder()
|
||||
.username(username)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var teamEntityMono = Mono.just(Team.builder()
|
||||
.id(teamId)
|
||||
.name(teamName)
|
||||
.members(List.of(member))
|
||||
.build());
|
||||
|
||||
Mockito.when(teamRepository.findById(Mockito.anyString()))
|
||||
.thenReturn(teamEntityMono);
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.findById(userId))
|
||||
.assertNext(team -> {
|
||||
Assertions.assertThat(team.name().equals(teamName));
|
||||
Assertions.assertThat(team.members()).hasSize(1);
|
||||
Assertions.assertThat(team.members().get(0).username()).isEqualTo(username);
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnErrorOnGetByIdWhenTeamMissing() {
|
||||
|
||||
Mockito.when(teamRepository.findById(Mockito.anyString()))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.findById("some id"))
|
||||
.expectErrorMatches(error -> error instanceof TeamServiceException && error.getMessage().equals("Team with given id doesn't exist"))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindTeamByName() {
|
||||
|
||||
String userId = "21344r23r34";
|
||||
String teamId = "2r872394r578";
|
||||
String teamName = "Some team";
|
||||
String username = "testsusrname";
|
||||
|
||||
var member = User.builder()
|
||||
.id(userId)
|
||||
.username(username)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var expectedMemberDto = new GetUserDto(
|
||||
userId,
|
||||
username,
|
||||
"some password",
|
||||
null, teamId);
|
||||
|
||||
|
||||
var teamMono = Mono.just(Team.builder()
|
||||
.id(teamId)
|
||||
.name(teamName)
|
||||
.members(List.of(member))
|
||||
.build());
|
||||
|
||||
Mockito.when(teamRepository.findByName(Mockito.anyString()))
|
||||
.thenReturn(teamMono);
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.findByName(teamName))
|
||||
.expectNextMatches(resultingTeam -> resultingTeam.name().equals(teamName))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnErrorOnGetTeamByNameWhenMissing() {
|
||||
|
||||
Mockito.when(teamRepository.findByName(Mockito.anyString()))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.findByName("some name"))
|
||||
.expectErrorMatches(error -> error instanceof TeamServiceException && error.getMessage().equals("Team with given name doesn't exist"))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateNewTeamWithMembers() {
|
||||
|
||||
String userId1 = "21344r23r34";
|
||||
String userId2 = "21344r23r34";
|
||||
String teamId = "2r872394r578";
|
||||
String teamName = "Some team";
|
||||
String username1 = "testsusrname";
|
||||
String username2 = "testsusrname2";
|
||||
|
||||
ArgumentCaptor<Team> saveTeamCaptor = ArgumentCaptor.forClass(Team.class);
|
||||
|
||||
var member1 = new GetUserDto(
|
||||
userId1,
|
||||
username1,
|
||||
"some password",
|
||||
null, null);
|
||||
|
||||
var member2 = new GetUserDto(
|
||||
userId2,
|
||||
username2,
|
||||
"some password",
|
||||
null, null);
|
||||
|
||||
var savedMember1 = User.builder()
|
||||
.id(userId1)
|
||||
.username(username1)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var savedMember2 = User.builder()
|
||||
.id(userId2)
|
||||
.username(username2)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var teamToCreateMono = Mono.just(new CreateTeamDto(
|
||||
teamName
|
||||
, List.of(member1, member2)));
|
||||
|
||||
var createdTeamMono = Mono.just(Team.builder()
|
||||
.id(teamId)
|
||||
.name(teamName)
|
||||
.members(List.of(savedMember1, savedMember2))
|
||||
.build());
|
||||
|
||||
Mockito.when(teamRepository.findByName(Mockito.anyString()))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
Mockito.when(teamRepository.save(saveTeamCaptor.capture()))
|
||||
.thenReturn(createdTeamMono);
|
||||
|
||||
Mockito.when(userRepository.saveAll(usersCaptor.capture()))
|
||||
.thenReturn(Flux.just(savedMember1, savedMember2));
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.addTeam(teamToCreateMono))
|
||||
.assertNext(team -> {
|
||||
Assertions.assertThat(team.name()).isEqualTo(teamName);
|
||||
Assertions.assertThat(team.members()).hasSize(2);
|
||||
Assertions.assertThat(team.members().stream().map(GetUserDto::username).toList()).containsAll(List.of(username1, username2));
|
||||
Assertions.assertThat(team.members().stream().filter(member -> !member.teamId().equals(teamId)).toList()).isEmpty();
|
||||
// captor assertions
|
||||
Assertions.assertThat(TeamUtils.toMembers.apply(saveTeamCaptor.getValue())).hasSize(2);
|
||||
Assertions.assertThat(TeamUtils.toId.apply(saveTeamCaptor.getValue())).isEqualTo(teamId);
|
||||
Assertions.assertThat(usersCaptor.getValue()).hasSize(2);
|
||||
})
|
||||
.verifyComplete();
|
||||
|
||||
InOrder inOrder = Mockito.inOrder(teamRepository, userRepository);
|
||||
|
||||
inOrder.verify(teamRepository, Mockito.times(1)).findByName(teamName);
|
||||
inOrder.verify(teamRepository, Mockito.times(1)).save(Mockito.any(Team.class));
|
||||
inOrder.verify(userRepository, Mockito.times(1)).saveAll(Mockito.any());
|
||||
inOrder.verify(teamRepository, Mockito.times(1)).save(Mockito.any(Team.class));
|
||||
|
||||
Mockito.verifyNoMoreInteractions(teamRepository, userRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnExistingTeamWhenNameIsTakenOnAddTeam() {
|
||||
|
||||
String userId1 = "21344r23r34";
|
||||
String userId2 = "tzuh";
|
||||
String teamId = "2r872394r578";
|
||||
String teamName = "Some team";
|
||||
String username1 = "testsusrname";
|
||||
String username2 = "testsusrname2";
|
||||
|
||||
var member1 = new GetUserDto(
|
||||
userId1,
|
||||
username1,
|
||||
"some password",
|
||||
null, null);
|
||||
|
||||
var member2 = new GetUserDto(
|
||||
userId2,
|
||||
username2,
|
||||
"some password",
|
||||
null, null);
|
||||
|
||||
var expectedMember1 = new GetUserDto(
|
||||
userId1,
|
||||
username1,
|
||||
"some password",
|
||||
null, teamId);
|
||||
|
||||
var expectedMember2 = new GetUserDto(
|
||||
userId2,
|
||||
username2,
|
||||
"some password",
|
||||
null, teamId);
|
||||
|
||||
var savedMember1 = User.builder()
|
||||
.id(userId1)
|
||||
.username(username1)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var savedMember2 = User.builder()
|
||||
.id(userId2)
|
||||
.username(username2)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var teamToCreateMono = Mono.just(new CreateTeamDto(
|
||||
teamName
|
||||
, List.of(member1, member2)));
|
||||
|
||||
var expectedTeamDto = new GetTeamDto(
|
||||
teamId,
|
||||
teamName
|
||||
, List.of(expectedMember1, expectedMember2));
|
||||
|
||||
var existingTeamMono = Mono.just(Team.builder()
|
||||
.id(teamId)
|
||||
.name(teamName)
|
||||
.members(List.of(savedMember1, savedMember2))
|
||||
.build());
|
||||
|
||||
Mockito.when(teamRepository.findByName(Mockito.anyString()))
|
||||
.thenReturn(existingTeamMono);
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.addTeam(teamToCreateMono))
|
||||
.expectNext(expectedTeamDto)
|
||||
.verifyComplete();
|
||||
|
||||
Mockito.verify(teamRepository, Mockito.never())
|
||||
.save(Mockito.any());
|
||||
Mockito.verify(userRepository, Mockito.never())
|
||||
.saveAll(Mockito.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ShouldDeleteTeamOnDelete() {
|
||||
|
||||
String userId1 = "21344r23r34";
|
||||
String userId2 = "21344r23r34";
|
||||
String teamId = "2r872394r578";
|
||||
String teamName = "Some team";
|
||||
String username1 = "testsusrname";
|
||||
String username2 = "testsusrname2";
|
||||
|
||||
var existingMember1 = User.builder()
|
||||
.id(userId1)
|
||||
.username(username1)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var existingMember2 = User.builder()
|
||||
.id(userId2)
|
||||
.username(username2)
|
||||
.password("some password")
|
||||
.teamId(teamId)
|
||||
.build();
|
||||
|
||||
var existingTeam = Team.builder()
|
||||
.id(teamId)
|
||||
.name(teamName)
|
||||
.members(List.of(existingMember1, existingMember2))
|
||||
.build();
|
||||
|
||||
Mockito.when(teamRepository.findById(Mockito.anyString()))
|
||||
.thenReturn(Mono.just(existingTeam));
|
||||
|
||||
Mockito.when(userRepository.saveAll(usersCaptor.capture()))
|
||||
.thenReturn(Flux.just(existingMember1, existingMember2));
|
||||
|
||||
Mockito.when(teamRepository.delete(Mockito.anyString()))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.deleteTeam(teamId))
|
||||
.assertNext(team -> {
|
||||
Assertions.assertThat(team.name()).isEqualTo(teamName);
|
||||
Assertions.assertThat(team.members()).hasSize(2);
|
||||
Assertions.assertThat(team.members().stream().map(GetUserDto::username).toList()).containsAll(List.of(username1, username2));
|
||||
Assertions.assertThat(team.members().stream().filter(member -> !member.teamId().equals(teamId)).toList()).isEmpty();
|
||||
// captor assertions
|
||||
Assertions.assertThat(usersCaptor.getValue()).hasSize(2);
|
||||
Assertions.assertThat(usersCaptor.getValue().stream().filter(user -> UserUtils.toTeamId.apply(user) != null).toList()).isEmpty();
|
||||
})
|
||||
.verifyComplete();
|
||||
|
||||
Mockito.verify(teamRepository, Mockito.times(1))
|
||||
.delete(teamId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnErrorOnDeleteWhenNotExist() {
|
||||
|
||||
Mockito.when(teamRepository.findById(Mockito.anyString()))
|
||||
.thenReturn(Mono.empty());
|
||||
|
||||
StepVerifier
|
||||
.create(teamService.deleteTeam("some id"))
|
||||
.expectErrorMatches(error -> error instanceof TeamServiceException && error.getMessage().equals("cannot find team to delete"))
|
||||
.verify();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user