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
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package dev.flima.application.educations.usecases;

import dev.flima.application.educations.dtos.request.EducationDTORequest;
import dev.flima.application.educations.dtos.response.CreateEducationDTOResponse;
import dev.flima.domain.educations.Education;
import dev.flima.domain.educations.EducationRepository;
import dev.flima.domain.educations.TypeEducation;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

@ExtendWith(MockitoExtension.class)
class CreateEducationUseCaseTest {

@Mock
private EducationRepository educationRepository;

private CreateEducationUseCase createEducationUseCase;

@BeforeEach
void setUp() {
createEducationUseCase = new CreateEducationUseCase(educationRepository);
}

@Test
@DisplayName("Should create an education entry successfully")
void shouldCreateEducationSuccessfully() {
// Arrange
EducationDTORequest request = new EducationDTORequest(
TypeEducation.DEGREE,
"Bachelor",
"Computer Science",
"Tech University",
"2018-2022",
"Software Engineering",
List.of("Java", "Spring"),
List.of("Clean Architecture")
);

// Act
CreateEducationDTOResponse response = createEducationUseCase.execute(request);

// Assert
assertNotNull(response);
assertNotNull(response.id());
assertEquals("Computer Science", response.title());

// Verify repository interaction
ArgumentCaptor<Education> educationCaptor = ArgumentCaptor.forClass(Education.class);
verify(educationRepository, times(1)).save(educationCaptor.capture());

Education savedEducation = educationCaptor.getValue();
assertEquals(TypeEducation.DEGREE, savedEducation.getTypeEducation());
assertEquals("Bachelor", savedEducation.getDegree());
assertEquals("Computer Science", savedEducation.getTitle());
assertEquals("Tech University", savedEducation.getInstitution());
assertEquals("2018-2022", savedEducation.getPeriod());
assertEquals("Software Engineering", savedEducation.getSpecialization());
assertEquals(List.of("Java", "Spring"), savedEducation.getSkills());
assertEquals(List.of("Clean Architecture"), savedEducation.getArchitectures());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package dev.flima.application.educations.usecases;

import dev.flima.domain.educations.Education;
import dev.flima.domain.educations.EducationRepository;
import dev.flima.domain.educations.TypeEducation;
import dev.flima.domain.exceptions.EntityNotFoundException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class DeleteEducationUseCaseTest {

@Mock
private EducationRepository educationRepository;

private DeleteEducationUseCase deleteEducationUseCase;

@BeforeEach
void setUp() {
deleteEducationUseCase = new DeleteEducationUseCase(educationRepository);
}

@Test
@DisplayName("Should delete education successfully")
void shouldDeleteSuccessfully() {
// Arrange
UUID id = UUID.randomUUID();
Education education = new Education(TypeEducation.DEGREE, "D", "T", "I", "P", "S", List.of(), List.of());
when(educationRepository.getById(id)).thenReturn(Optional.of(education));

// Act
deleteEducationUseCase.execute(id);

// Assert
verify(educationRepository, times(1)).remove(education);
}

@Test
@DisplayName("Should throw EntityNotFoundException when deleting non-existent education")
void shouldThrowExceptionWhenNotFound() {
// Arrange
UUID id = UUID.randomUUID();
when(educationRepository.getById(id)).thenReturn(Optional.empty());

// Act & Assert
assertThrows(EntityNotFoundException.class, () -> deleteEducationUseCase.execute(id));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package dev.flima.application.educations.usecases;

import dev.flima.application.educations.dtos.request.EducationDTORequest;
import dev.flima.application.educations.dtos.response.EducationDTOResponse;
import dev.flima.domain.educations.Education;
import dev.flima.domain.educations.EducationRepository;
import dev.flima.domain.educations.TypeEducation;
import dev.flima.domain.exceptions.EntityNotFoundException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

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

@ExtendWith(MockitoExtension.class)
class UpdateEducationUseCaseTest {

@Mock
private EducationRepository educationRepository;

private UpdateEducationUseCase updateEducationUseCase;

@BeforeEach
void setUp() {
updateEducationUseCase = new UpdateEducationUseCase(educationRepository);
}

@Test
@DisplayName("Should update education successfully")
void shouldUpdateSuccessfully() {
// Arrange
UUID id = UUID.randomUUID();
Education existingEducation = new Education(
TypeEducation.DEGREE,
"Old Degree",
"Old Title",
"Old Inst",
"2020",
"Old Spec",
List.of(),
List.of()
);
// Set ID manually since it's usually generated by DB or set during creation
// But for mock existing we need to make sure it looks real

when(educationRepository.getById(id)).thenReturn(Optional.of(existingEducation));

EducationDTORequest updateRequest = new EducationDTORequest(
TypeEducation.DEGREE,
"New Degree",
"New Title",
"New Inst",
"2021",
"New Spec",
List.of("Skill"),
List.of("Arch")
);

// Act
EducationDTOResponse response = updateEducationUseCase.execute(id, updateRequest);

// Assert
assertNotNull(response);
assertEquals("New Title", response.title());
assertEquals("New Degree", response.degree());

verify(educationRepository, times(1)).modify(any(Education.class));
}

@Test
@DisplayName("Should throw EntityNotFoundException when education does not exist")
void shouldThrowExceptionWhenNotFound() {
// Arrange
UUID id = UUID.randomUUID();
when(educationRepository.getById(id)).thenReturn(Optional.empty());

EducationDTORequest request = new EducationDTORequest(
TypeEducation.DEGREE, "D", "T", "I", "P", "S", List.of(), List.of()
);

// Act & Assert
assertThrows(EntityNotFoundException.class, () -> updateEducationUseCase.execute(id, request));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package dev.flima.application.users.usecases;

import dev.flima.application.users.dtos.request.UserDTORequest;
import dev.flima.application.users.dtos.response.UserDTOResponse;
import dev.flima.domain.security.PasswordHasher;
import dev.flima.domain.users.Password;
import dev.flima.domain.users.Role;
import dev.flima.domain.users.User;
import dev.flima.domain.users.UserRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class CreateUserUseCaseTest {

@Mock
private UserRepository userRepository;

@Mock
private PasswordHasher passwordHasher;

private CreateUserUseCase createUserUseCase;

@BeforeEach
void setUp() {
createUserUseCase = new CreateUserUseCase(userRepository, passwordHasher);
}

@Test
@DisplayName("Should create a user successfully")
void shouldCreateUserSuccessfully() {
// Arrange
String passwordRaw = "password123";
String passwordHashed = "hashed_password";
UserDTORequest request = new UserDTORequest(
"johndoe",
"John",
"Doe",
"john@example.com",
Role.OWNER,
new Password(passwordRaw)
);

when(passwordHasher.hash(any(Password.class))).thenReturn(passwordHashed);

// Act
UserDTOResponse response = createUserUseCase.execute(request);

// Assert
assertNotNull(response);
assertEquals("johndoe", response.username());
assertEquals(Role.OWNER, response.role());

// Verify repository interaction
ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
verify(userRepository, times(1)).save(userCaptor.capture());

User savedUser = userCaptor.getValue();
assertEquals("johndoe", savedUser.getUsername());
assertEquals("John", savedUser.getName());
assertEquals("Doe", savedUser.getLastName());
assertEquals("john@example.com", savedUser.getEmail());
assertEquals(Role.OWNER, savedUser.getRole());
assertEquals(passwordHashed, savedUser.getPassword().password());

verify(passwordHasher, times(1)).hash(any(Password.class));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package dev.flima.infrastructure.exceptions;

import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.security.TestSecurity;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.UUID;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;

@QuarkusTest
class ExceptionHandlerTest {

@Test
@DisplayName("Should return consistent ErrorResponse for DomainException (404)")
@TestSecurity(user = "admin", roles = "OWNER")
void shouldReturnConsistentErrorResponse() {
given()
.when()
.get("/educations/" + UUID.randomUUID())
.then()
.statusCode(404)
.body("message", is("Education record not found."))
.body("status", is(404))
.body("timestamp", notNullValue());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package dev.flima.infrastructure.messaging;

import dev.flima.domain.messages.Message;
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.kafka.KafkaCompanionResource;
import io.quarkus.test.kafka.InjectKafkaCompanion;
import io.smallrye.reactive.messaging.kafka.companion.KafkaCompanion;
import jakarta.inject.Inject;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.time.Duration;
import java.util.UUID;

@QuarkusTest
@QuarkusTestResource(KafkaCompanionResource.class)
class ContactMessagingAdapterTest {

@Inject
ContactMessagingAdapter contactMessagingAdapter;

@InjectKafkaCompanion
KafkaCompanion companion;

@Test
@DisplayName("Should produce a message to Kafka topic when sendMessage is called")
void shouldProduceMessageToKafka() {
String uniqueUser = "tester-" + UUID.randomUUID();
// Arrange
Message message = new Message(
uniqueUser,
"tester@example.com",
"Subject",
"Body"
);

// Act
contactMessagingAdapter.sendMessage(message);

// Assert
Awaitility.await()
.atMost(Duration.ofSeconds(15))
.untilAsserted(() -> {
var records = companion.consumeStrings()
.fromTopics("contact-messages", 1)
.awaitCompletion(Duration.ofSeconds(10))
.getRecords();

boolean found = records.stream()
.anyMatch(record -> record.value().contains("\"username\":\"" + uniqueUser + "\""));
org.junit.jupiter.api.Assertions.assertTrue(found, "Message not found in Kafka topic: " + uniqueUser);
});
}
}
Loading