e9937accd8
Gmail and Graph request explicit send consent and classify provider rejection separately from uncertain transport failure. IMAP remains read-only; no send API is exposed.
96 lines
4.1 KiB
C#
96 lines
4.1 KiB
C#
using JobTrackerApi.Services;
|
|
using JobTrackerApi.Services.EmailProviders;
|
|
using Moq;
|
|
using Xunit;
|
|
|
|
namespace JobTrackerApi.Tests;
|
|
|
|
public sealed class MicrosoftGraphProviderTests
|
|
{
|
|
[Fact]
|
|
public void ProviderKey_is_microsoft()
|
|
{
|
|
var provider = new MicrosoftGraphProvider(Mock.Of<IMicrosoftGraphOAuthService>());
|
|
Assert.Equal("microsoft", provider.ProviderKey);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetConnectionAsync_maps_mail_address_onto_neutral_shape()
|
|
{
|
|
var graph = new Mock<IMicrosoftGraphOAuthService>();
|
|
graph.Setup(service => service.GetConnectionAsync("user-1", It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(new JobTrackerApi.Models.MicrosoftGraphConnection { OwnerUserId = "user-1", MailAddress = "user@outlook.test" });
|
|
|
|
var provider = new MicrosoftGraphProvider(graph.Object);
|
|
var connection = await provider.GetConnectionAsync("user-1", CancellationToken.None);
|
|
|
|
Assert.NotNull(connection);
|
|
Assert.Equal("microsoft", connection!.ProviderKey);
|
|
Assert.Equal("user@outlook.test", connection.Address);
|
|
Assert.False(connection.CanSend);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetConnectionAsync_reports_send_only_after_mail_send_consent()
|
|
{
|
|
var graph = new Mock<IMicrosoftGraphOAuthService>();
|
|
graph.Setup(service => service.GetConnectionAsync("user-1", It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(new JobTrackerApi.Models.MicrosoftGraphConnection { OwnerUserId = "user-1", MailAddress = "user@outlook.test", Scope = "Mail.Read Mail.Send" });
|
|
|
|
var connection = await new MicrosoftGraphProvider(graph.Object).GetConnectionAsync("user-1", default);
|
|
|
|
Assert.True(connection!.CanSend);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetConnectionAsync_returns_null_when_not_connected()
|
|
{
|
|
var graph = new Mock<IMicrosoftGraphOAuthService>();
|
|
graph.Setup(service => service.GetConnectionAsync("user-1", It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync((JobTrackerApi.Models.MicrosoftGraphConnection?)null);
|
|
|
|
var provider = new MicrosoftGraphProvider(graph.Object);
|
|
var connection = await provider.GetConnectionAsync("user-1", CancellationToken.None);
|
|
|
|
Assert.Null(connection);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SearchAsync_maps_conversation_id_onto_neutral_thread_id()
|
|
{
|
|
var graph = new Mock<IMicrosoftGraphOAuthService>();
|
|
graph.Setup(service => service.ListMessagesAsync("user-1", "recruiter", 10, It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(new List<MicrosoftGraphMessageSummary>
|
|
{
|
|
new("msg-1", "conv-1", "Interview", "them@company.test", "me@outlook.test", DateTimeOffset.UtcNow, "snippet")
|
|
});
|
|
|
|
var provider = new MicrosoftGraphProvider(graph.Object);
|
|
var results = await provider.SearchAsync("user-1", "recruiter", 10, CancellationToken.None);
|
|
|
|
var summary = Assert.Single(results);
|
|
Assert.Equal("msg-1", summary.Id);
|
|
Assert.Equal("conv-1", summary.ThreadId);
|
|
Assert.Equal("Interview", summary.Subject);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetMessageAsync_maps_attachment_id_onto_neutral_external_attachment_id()
|
|
{
|
|
var graph = new Mock<IMicrosoftGraphOAuthService>();
|
|
graph.Setup(service => service.GetMessageAsync("user-1", "msg-1", It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(new MicrosoftGraphMessageDetail(
|
|
"msg-1", "conv-1", "Offer", "them@company.test", "me@outlook.test", DateTimeOffset.UtcNow, "snippet",
|
|
"body text", "<p>body</p>", new List<string> { "Inbox" },
|
|
new List<MicrosoftGraphMessageAttachment> { new("resume.pdf", "application/pdf", 1024, "graph-att-1", false) }));
|
|
|
|
var provider = new MicrosoftGraphProvider(graph.Object);
|
|
var detail = await provider.GetMessageAsync("user-1", "msg-1", CancellationToken.None);
|
|
|
|
Assert.Equal("conv-1", detail.ThreadId);
|
|
var attachment = Assert.Single(detail.Attachments);
|
|
Assert.Equal("resume.pdf", attachment.FileName);
|
|
Assert.Equal("graph-att-1", attachment.ExternalAttachmentId);
|
|
}
|
|
}
|