Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(VIST-CPC-1361) See Received emails #1018

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
@@ -1,11 +1,8 @@
package com.petclinic.bffapigateway.domainclientlayer;


import com.petclinic.bffapigateway.dtos.Emailing.DirectEmailModelRequestDTO;
import com.petclinic.bffapigateway.dtos.Emailing.EmailModelResponseDTO;
import com.petclinic.bffapigateway.dtos.Emailing.*;

import com.petclinic.bffapigateway.dtos.Emailing.NotificationEmailModelRequestDTO;
import com.petclinic.bffapigateway.dtos.Emailing.RawEmailModelRequestDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -77,4 +74,12 @@ public Mono<HttpStatus> sendRawEmail(RawEmailModelRequestDTO rawEmailModelReques
return Mono.just((HttpStatus) response.statusCode());
});
}
public Flux<ReceivedEmailResponseDTO> getAllReceivedEmails() {
return webClientBuilder.build()
.get()
.uri(emailingServiceUrl + "/received/all") // Adjust the URI to match your endpoint
.retrieve()
.bodyToFlux(ReceivedEmailResponseDTO.class)
.doOnError(error -> log.error("Error fetching emails: {}", error.getMessage()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.petclinic.bffapigateway.dtos.Emailing;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ReceivedEmailResponseDTO {
public String from ; // The email address of the sender
public String subject ; // The subject line of the email
public Date dateReceived ; // The date and time the email was sent
public String plainTextBody ; // The main text content of the email
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@


import com.petclinic.bffapigateway.domainclientlayer.EmailingServiceClient;
import com.petclinic.bffapigateway.dtos.Emailing.DirectEmailModelRequestDTO;
import com.petclinic.bffapigateway.dtos.Emailing.EmailModelResponseDTO;
import com.petclinic.bffapigateway.dtos.Emailing.NotificationEmailModelRequestDTO;
import com.petclinic.bffapigateway.dtos.Emailing.RawEmailModelRequestDTO;
import com.petclinic.bffapigateway.dtos.Emailing.*;
import com.petclinic.bffapigateway.utils.Security.Annotations.SecuredEndpoint;
import com.petclinic.bffapigateway.utils.Security.Variables.Roles;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -101,5 +98,12 @@ public Mono<ResponseEntity<Object>> sendRawEmail(@RequestBody RawEmailModelReque
return Mono.just(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build()); // Handle errors
});
}
@SecuredEndpoint(allowedRoles = {Roles.ADMIN})
@GetMapping(value = "/received/all", produces = MediaType.APPLICATION_JSON_VALUE) // Endpoint to retrieve all emails
public Flux<ReceivedEmailResponseDTO> getAllEmailsReceived() {
return emailingService.getAllReceivedEmails()
.doOnError(e -> log.error("Error retrieving emails", e)) // Log any errors that occur
.onErrorResume(e -> Flux.empty()); // Return an empty Flux in case of error
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package com.petclinic.bffapigateway.domainclientlayer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.petclinic.bffapigateway.domainclientlayer.EmailingServiceClient;
import com.petclinic.bffapigateway.dtos.Emailing.DirectEmailModelRequestDTO;
import com.petclinic.bffapigateway.dtos.Emailing.EmailModelResponseDTO;
import com.petclinic.bffapigateway.dtos.Emailing.NotificationEmailModelRequestDTO;
import com.petclinic.bffapigateway.dtos.Emailing.RawEmailModelRequestDTO;

import com.petclinic.bffapigateway.dtos.Emailing.*;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.jupiter.api.AfterAll;
Expand All @@ -18,11 +15,15 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import reactor.test.StepVerifier;


import java.io.IOException;

import java.time.Instant;

import java.time.ZoneOffset;
import java.util.Date;
import java.util.List;

public class EmailingServiceClientIntegrationTest {

Expand Down Expand Up @@ -147,4 +148,25 @@ void sendRawEmail() throws Exception {
.expectNext(HttpStatus.OK)
.verifyComplete();
}
@Test
void getAllReceivedEmails() throws Exception {
// Create a sample ReceivedEmailResponseDTO object
ReceivedEmailResponseDTO receivedEmailResponseDTO = new ReceivedEmailResponseDTO(
"[email protected]", "Subject", new Date(), "a body"
);

// Enqueue a mock response from the server
mockWebServer.enqueue(new MockResponse()
.setHeader(org.springframework.http.HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.setBody(objectMapper.writeValueAsString(List.of(receivedEmailResponseDTO))) // Wrap in a list for the Flux response
);

// Call the method to test
Flux<ReceivedEmailResponseDTO> emailFlux = emailingServiceClient.getAllReceivedEmails();

// Verify the response using StepVerifier
StepVerifier.create(emailFlux)
.expectNext(receivedEmailResponseDTO) // Expect the received email response DTO
.verifyComplete();
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package com.petclinic.bffapigateway.presentationlayer.v2.Emailing;

import com.petclinic.bffapigateway.domainclientlayer.EmailingServiceClient;
import com.petclinic.bffapigateway.dtos.Emailing.DirectEmailModelRequestDTO;
import com.petclinic.bffapigateway.dtos.Emailing.EmailModelResponseDTO;
import com.petclinic.bffapigateway.dtos.Emailing.NotificationEmailModelRequestDTO;
import com.petclinic.bffapigateway.dtos.Emailing.RawEmailModelRequestDTO;
import com.petclinic.bffapigateway.dtos.Emailing.*;
import com.petclinic.bffapigateway.presentationlayer.v2.EmailingController;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -134,6 +131,36 @@ void testSendRawEmail() {
.exchange()
.expectStatus().isOk(); // Expect 200 OK
}
@Test
void testGetAllEmailsReceived() {
// Mock the service response
ReceivedEmailResponseDTO receivedEmail1 = new ReceivedEmailResponseDTO(/* initialize fields */);
ReceivedEmailResponseDTO receivedEmail2 = new ReceivedEmailResponseDTO(/* initialize fields */);
when(emailingService.getAllReceivedEmails()).thenReturn(Flux.just(receivedEmail1, receivedEmail2));

// Execute the test
bindToController(emailingController).build()
.get()
.uri("/api/v2/gateway/emailing/received/all")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk() // Check if the status is 200 OK
.expectBodyList(ReceivedEmailResponseDTO.class)
.hasSize(2)
.contains(receivedEmail1, receivedEmail2);
}

@Test
void testGetAllEmailsReceived_NoEmailThenOk() {
when(emailingService.getAllReceivedEmails()).thenReturn(Flux.empty());

// Execute the test
bindToController(emailingController).build()
.get()
.uri("/api/v2/gateway/emailing/received/all")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk(); // Expect 204 No Content
}

// Additional tests can be added to test error handling and other scenarios
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,28 @@ public void registerGetAllEmailsEndpoint() {
.withBody(json(emailResponse))
);
}
public void registerGetAllReceivedEmailsEndpoint() {
String receivedEmailResponse = "[" +
"{" +
"\"from\": \"\\\"Xilef992\\\" <[email protected]>\"," +
"\"subject\": \"yeah ok\"," +
"\"dateReceived\": \"2024-10-20T21:52:40.000+00:00\"," +
"\"plainTextBody\": \"You are done!\\n\"" +
"}" +
"]";

mockServerClient_EmailingService
.when(
request()
.withMethod("GET")
.withPath("/received/all")
)
.respond(
response()
.withStatusCode(200)
.withBody(json(receivedEmailResponse))
);
}

// Mock for addHtmlTemplate endpoint
public void registerAddHtmlTemplateEndpoint() {
Expand Down Expand Up @@ -86,6 +108,7 @@ public void registerSendEmailNotificationEndpoint() {
);
}


// Stop the mock server
public void stopMockServer() {
if (clientAndServer != null) {
Expand Down
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ services:
build:
context: ./emailing-service
dockerfile: emailing-service/Dockerfile
#ports:
# - "5000:5115" # Used for testing without gateway
ports:
- "5000:5115" # Used for testing without gateway
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this port still open and accessible when upping the system? If so, it should be closed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes you are right! I will fix that!

environment:
- ASPNETCORE_ENVIRONMENT=Development
- DEFAULT_CONNECTION=Server=emailing-service-mysql-db;Port=3306;Database=MyAppDb;User=root;Password=Your_password123;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
using emailing_service.Models;
using emailing_service.Models.Database;
using emailing_service.Models.EmailType;
using emailing_service.Models.SMTP.Model;
using emailing_service.Utils;
using emailing_service.Utils.Exception;
using MailKit;
using MailKit.Net.Imap;
using MailKit.Search;
using MimeKit;
using Moq;

namespace emailing_service_test.BuisnessLayer;

Expand All @@ -15,6 +21,8 @@ namespace emailing_service_test.BuisnessLayer;
[TestFixture]
public class EmailServiceImplTest
{
private Mock<ImapClient> _imapClientMock;
private Mock<IMailFolder> _inboxMock;
private IEmailService _controller;
private readonly string _pathOfDefaultHtml;
public EmailServiceImplTest()
Expand All @@ -26,6 +34,20 @@ public EmailServiceImplTest()
[OneTimeSetUp]
public Task SetUp()
{
var mockEmail1 = new MimeMessage();
mockEmail1.From.Add(new MailboxAddress("Sender One", "[email protected]"));
mockEmail1.Subject = "Test Email 1";
mockEmail1.Date = DateTimeOffset.Now;
mockEmail1.Body = new TextPart("plain") { Text = "Hello from sender 1" };

var mockEmail2 = new MimeMessage();
mockEmail2.From.Add(new MailboxAddress("Sender Two", "[email protected]"));
mockEmail2.Subject = "Test Email 2";
mockEmail2.Date = DateTimeOffset.Now;
mockEmail2.Body = new TextPart("plain") { Text = "Hello from sender 2" };
_imapClientMock = new Mock<ImapClient>();
_inboxMock = new Mock<IMailFolder>(); // Mock IMailFolder for inbox
_imapClientMock.Setup(client => client.Inbox).Returns(_inboxMock.Object); // Return mocked inbox
EmailUtils.emailConnectionString = new ConnectionEmailServer(
"Mock",
000,
Expand All @@ -36,6 +58,7 @@ public Task SetUp()
);
_controller = new EmailServiceImpl();
_controller.SetDatabaseHelper(new TestDbContext());
_controller.SetImapServer(_imapClientMock.Object);
return Task.CompletedTask;
}
/*[Test]
Expand Down Expand Up @@ -685,6 +708,28 @@ public void SendEmailNotification_AlreadyPassedDate_AlreadyPassedDate(Notificati
Does.Contain($"The Date for the notification was already passed!"));
}

[Test]
public async Task GetAllEmailsReceivedAsync_ShouldThrowAuthenticationException_WhenInvalidCredentials()
{
// Act & Assert
var ex = Assert.ThrowsAsync<System.NullReferenceException>(async () =>
{
await foreach (var email in _controller.GetAllEmailsReceivedAsync())
{
// We shouldn't get to this point
}
});

Assert.That(ex.Message, Is.EqualTo("Object reference not set to an instance of an object.")); // Adjust according to your actual exception message
}









[OneTimeTearDown]
public void TearDown()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using emailing_service.Models.SMTP.Model;

namespace emailing_service_test.Models.SMTP.Model;

using NUnit.Framework;
using System;

[TestFixture]
public class EmailReceivedTests
{
[Test]
public void EmailReceived_Constructor_ShouldInitializeProperties()
{
// Arrange
string from = "[email protected]";
string subject = "Test Subject";
DateTime dateReceived = DateTime.Now;
string plainTextBody = "This is a test email body.";

// Act
var emailReceived = new EmailReceived(from, subject, dateReceived, plainTextBody);

// Assert
Assert.AreEqual(from, emailReceived.From);
Assert.AreEqual(subject, emailReceived.Subject);
Assert.AreEqual(dateReceived, emailReceived.DateReceived);
Assert.AreEqual(plainTextBody, emailReceived.PlainTextBody);
}

[Test]
public void EmailReceived_SetAndGetProperties_ShouldWorkCorrectly()
{
// Arrange
var emailReceived = new EmailReceived("[email protected]", "Initial Subject", DateTime.Now, "Initial Body");

// Act
emailReceived.From = "[email protected]";
emailReceived.Subject = "Updated Subject";
emailReceived.DateReceived = DateTime.Now.AddDays(-1);
emailReceived.PlainTextBody = "Updated Body";

// Assert
Assert.AreEqual("[email protected]", emailReceived.From);
Assert.AreEqual("Updated Subject", emailReceived.Subject);
Assert.IsTrue(emailReceived.DateReceived < DateTime.Now); // Assuming you want to check if the date is before now
Assert.AreEqual("Updated Body", emailReceived.PlainTextBody);
}

[Test]
public void EmailReceived_EmptyConstructor_ShouldNotThrowException()
{
// Arrange & Act
var emailReceived = new EmailReceived(string.Empty, string.Empty, DateTime.MinValue, string.Empty);

// Assert
Assert.IsNotNull(emailReceived);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1261,9 +1261,6 @@ public async Task SendRawEmail_EmailBodyIsInvalid_BadRequest(RawEmailModel email
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}




[TearDown]
public void AllTimeTearDown()
{
Expand Down
Loading
Loading