test: add unit and integration tests
This commit is contained in:
@@ -149,6 +149,24 @@
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.pablotj.restemailbridge.infrastructure.persistence;
|
||||
package com.pablotj.restemailbridge.infrastructure.encryption;
|
||||
|
||||
import jakarta.persistence.AttributeConverter;
|
||||
import jakarta.persistence.Converter;
|
||||
@@ -1,13 +1,13 @@
|
||||
package com.pablotj.restemailbridge.infrastructure.persistence;
|
||||
package com.pablotj.restemailbridge.infrastructure.encryption;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public class EncryptionUtils {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.pablotj.restemailbridge.infrastructure.persistence;
|
||||
|
||||
import com.pablotj.restemailbridge.domain.model.EmailStatus;
|
||||
import com.pablotj.restemailbridge.infrastructure.encryption.EncryptionConverter;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Convert;
|
||||
import jakarta.persistence.Entity;
|
||||
|
||||
@@ -17,4 +17,10 @@ public class GlobalExceptionHandler {
|
||||
errors.put(error.getField(), error.getDefaultMessage()));
|
||||
return ResponseEntity.badRequest().body(errors);
|
||||
}
|
||||
|
||||
@ExceptionHandler(RuntimeException.class)
|
||||
public ResponseEntity<Map<String, String>> handleRuntimeException(RuntimeException ex) {
|
||||
Map<String, String> error = Map.of("error", ex.getMessage());
|
||||
return ResponseEntity.unprocessableEntity().body(error); // 422
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.pablotj.restemailbridge.infrastructure;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
@SpringBootApplication(scanBasePackages = "com.pablotj.restemailbridge")
|
||||
@EnableJpaRepositories(basePackages = "com.pablotj.restemailbridge")
|
||||
@EntityScan(basePackages = "com.pablotj.restemailbridge")
|
||||
public class RestEmailBridgeTestApplication {
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.pablotj.restemailbridge.infrastructure.persistence;
|
||||
|
||||
import com.pablotj.restemailbridge.domain.model.Email;
|
||||
import com.pablotj.restemailbridge.domain.model.EmailStatus;
|
||||
import com.pablotj.restemailbridge.infrastructure.config.JpaConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@Import(JpaConfig.class)
|
||||
@DataJpaTest
|
||||
class MailRepositoryAdapterIT {
|
||||
|
||||
@Autowired
|
||||
private SpringDataMailRepository springDataMailRepository;
|
||||
|
||||
@Test
|
||||
void shouldSaveEmailSuccessfully() {
|
||||
MailRepositoryAdapter adapter = new MailRepositoryAdapter(springDataMailRepository);
|
||||
|
||||
Email email = Email.create("sender@example.com", "recipient@example.com", "Subject", "Body");
|
||||
|
||||
Email saved = adapter.save(email);
|
||||
|
||||
assertThat(saved.getFrom()).isEqualTo("sender@example.com");
|
||||
assertThat(saved.getTo()).isEqualTo("recipient@example.com");
|
||||
assertThat(saved.getSubject()).isEqualTo("Subject");
|
||||
assertThat(saved.getBody()).isEqualTo("Body");
|
||||
assertThat(saved.getStatus()).isEqualTo(EmailStatus.PENDING);
|
||||
|
||||
assertThat(springDataMailRepository.findAll())
|
||||
.hasSize(1)
|
||||
.first()
|
||||
.extracting("sender", "recipient")
|
||||
.containsExactly("sender@example.com", "recipient@example.com");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.pablotj.restemailbridge.infrastructure.rest;
|
||||
|
||||
import com.pablotj.restemailbridge.application.port.out.EmailPort;
|
||||
import com.pablotj.restemailbridge.infrastructure.RestEmailBridgeTestApplication;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@SpringBootTest(
|
||||
classes = RestEmailBridgeTestApplication.class,
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
|
||||
)
|
||||
@AutoConfigureMockMvc
|
||||
@ActiveProfiles("test")
|
||||
class MailControllerIT {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
private EmailPort emailPort;
|
||||
|
||||
@Test
|
||||
void shouldReturn200WhenEmailIsSent() throws Exception {
|
||||
when(emailPort.sendEmail(any())).thenAnswer(invocation -> invocation.getArgument(0));
|
||||
|
||||
mockMvc.perform(post("/v1/mail")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"from\":\"sender@example.com\",\"subject\":\"Subject\",\"body\":\"Body\"}"))
|
||||
.andExpect(status().isOk());
|
||||
|
||||
verify(emailPort).sendEmail(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturn400WhenRequestIsInvalid() throws Exception {
|
||||
mockMvc.perform(post("/v1/mail")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"subject\":\"Subject\",\"body\":\"Body\"}"))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
}
|
||||
27
infrastructure/src/test/resources/application.yml
Normal file
27
infrastructure/src/test/resources/application.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
spring:
|
||||
application:
|
||||
name: restemailbridge
|
||||
datasource:
|
||||
url: jdbc:h2:mem:restemailbridge;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
||||
driver-class-name: org.h2.Driver
|
||||
username: sa
|
||||
password:
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: create-drop
|
||||
show-sql: true
|
||||
|
||||
server:
|
||||
port: 0
|
||||
servlet:
|
||||
context-path: /api
|
||||
|
||||
app:
|
||||
encryption:
|
||||
secret: 0123456789ABCDEF0123456789ABCDEF
|
||||
|
||||
gmail:
|
||||
oauth2:
|
||||
clientId: dummy
|
||||
clientSecret: dummy
|
||||
redirectUri: http://localhost:8888/Callback
|
||||
Reference in New Issue
Block a user