Skip to content
This repository was archived by the owner on Jul 28, 2025. It is now read-only.

Commit 0d3a21d

Browse files
committed
feat: adding unit tests for file Extract function
1 parent da5d59b commit 0d3a21d

File tree

2 files changed

+154
-2
lines changed

2 files changed

+154
-2
lines changed

src/ServiceLayer.Mesh/Functions/FileExtractFunction.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ public async Task Run([QueueTrigger("file-extract")] FileExtractQueueMessage mes
5454
// TODO - approx after this point we'll need to wrap everything in a try-catch. On failure we should
5555
// update the meshfile to FailedExtract, and move the message to the poison queue
5656

57-
var mailboxId = Environment.GetEnvironmentVariable("MeshMailboxId")
58-
?? throw new InvalidOperationException($"Environment variable 'MeshMailboxId' is not set or is empty.");
57+
var mailboxId = Environment.GetEnvironmentVariable("NBSSMailBoxId")
58+
?? throw new InvalidOperationException($"Environment variable 'NBSSMailBoxId' is not set or is empty.");
5959

6060
var meshResponse = await meshInboxService.GetMessageByIdAsync(mailboxId, file.FileId);
6161
if (!meshResponse.IsSuccessful)
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,158 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.Extensions.Logging;
3+
using Moq;
4+
using NHS.MESH.Client.Contracts.Services;
5+
using NHS.MESH.Client.Models;
6+
using ServiceLayer.Mesh.Data;
7+
using ServiceLayer.Mesh.Functions;
8+
using ServiceLayer.Mesh.Messaging;
9+
using ServiceLayer.Mesh.Models;
10+
using ServiceLayer.Mesh.Storage;
11+
112
namespace ServiceLayer.Mesh.Tests.Functions;
213

314
public class FileExtractFunctionTests
415
{
16+
private readonly Mock<ILogger<FileExtractFunction>> _loggerMock;
17+
private readonly Mock<IMeshInboxService> _meshInboxServiceMock;
18+
private readonly Mock<IFileTransformQueueClient> _queueClientMock;
19+
private readonly Mock<IMeshFilesBlobStore> _blobStoreMock;
20+
private readonly ServiceLayerDbContext _dbContext;
21+
private readonly FileExtractFunction _function;
22+
23+
public FileExtractFunctionTests()
24+
{
25+
_loggerMock = new Mock<ILogger<FileExtractFunction>>();
26+
_meshInboxServiceMock = new Mock<IMeshInboxService>();
27+
_queueClientMock = new Mock<IFileTransformQueueClient>();
28+
_blobStoreMock = new Mock<IMeshFilesBlobStore>();
29+
30+
var options = new DbContextOptionsBuilder<ServiceLayerDbContext>()
31+
.UseInMemoryDatabase(Guid.NewGuid().ToString())
32+
.ConfigureWarnings(warnings =>
33+
warnings.Ignore(Microsoft.EntityFrameworkCore.Diagnostics.InMemoryEventId.TransactionIgnoredWarning))
34+
.Options;
35+
36+
_dbContext = new ServiceLayerDbContext(options);
37+
38+
Environment.SetEnvironmentVariable("NBSSMailBoxId", "test-mailbox");
39+
40+
_function = new FileExtractFunction(
41+
_loggerMock.Object,
42+
_meshInboxServiceMock.Object,
43+
_dbContext,
44+
_queueClientMock.Object,
45+
_blobStoreMock.Object
46+
);
47+
}
48+
49+
[Fact]
50+
public async Task Run_FileNotFound_ExitsSilently()
51+
{
52+
var message = new FileExtractQueueMessage { FileId = "nonexistent-file" };
53+
54+
var exception = await Assert.ThrowsAsync<InvalidOperationException>(() => _function.Run(message));
55+
Assert.Equal("File not found", exception.Message);
56+
}
57+
58+
[Fact]
59+
public async Task Run_FileInInvalidStatus_ExitsSilently()
60+
{
61+
var file = new MeshFile
62+
{
63+
FileType = MeshFileType.NbssAppointmentEvents,
64+
MailboxId = "test-mailbox",
65+
FileId = "file-1",
66+
Status = MeshFileStatus.Transforming, // Not eligible
67+
LastUpdatedUtc = DateTime.UtcNow
68+
};
69+
_dbContext.MeshFiles.Add(file);
70+
await _dbContext.SaveChangesAsync();
71+
72+
var message = new FileExtractQueueMessage { FileId = "file-1" };
73+
74+
var exception = await Assert.ThrowsAsync<InvalidOperationException>(() => _function.Run(message));
75+
Assert.Equal("File is not in expected status", exception.Message);
76+
}
77+
78+
[Fact]
79+
public async Task Run_FileExtractingButNotTimedOut_ExitsSilently()
80+
{
81+
var file = new MeshFile
82+
{
83+
FileType = MeshFileType.NbssAppointmentEvents,
84+
MailboxId = "test-mailbox",
85+
FileId = "file-2",
86+
Status = MeshFileStatus.Extracting,
87+
LastUpdatedUtc = DateTime.UtcNow // Not timed out
88+
};
89+
_dbContext.MeshFiles.Add(file);
90+
await _dbContext.SaveChangesAsync();
91+
92+
var message = new FileExtractQueueMessage { FileId = "file-2" };
93+
94+
var exception = await Assert.ThrowsAsync<InvalidOperationException>(() => _function.Run(message));
95+
Assert.Equal("File is not in expected status", exception.Message);
96+
}
97+
98+
[Fact]
99+
public async Task Run_FileExtractSuccess_UploadsBlob()
100+
{
101+
var fileId = "file-3";
102+
var file = new MeshFile
103+
{
104+
FileType = MeshFileType.NbssAppointmentEvents,
105+
MailboxId = "test-mailbox",
106+
FileId = fileId,
107+
Status = MeshFileStatus.Discovered,
108+
LastUpdatedUtc = DateTime.UtcNow.AddHours(-1)
109+
};
110+
_dbContext.MeshFiles.Add(file);
111+
await _dbContext.SaveChangesAsync();
112+
113+
var content = new byte[] { 1, 2, 3 };
114+
115+
_meshInboxServiceMock.Setup(s => s.GetMessageByIdAsync("test-mailbox", fileId))
116+
.ReturnsAsync(new MeshResponse<GetMessageResponse>
117+
{
118+
IsSuccessful = true,
119+
Response = new GetMessageResponse
120+
{
121+
FileAttachment = new FileAttachment { Content = content }
122+
}
123+
});
124+
125+
var message = new FileExtractQueueMessage { FileId = fileId };
126+
127+
await _function.Run(message);
128+
129+
_blobStoreMock.Verify(b => b.UploadAsync(It.Is<MeshFile>(f => f.FileId == fileId), content), Times.Once);
130+
}
131+
132+
[Fact]
133+
public async Task Run_MeshResponseFails_Throws()
134+
{
135+
var fileId = "file-4";
136+
var file = new MeshFile
137+
{
138+
FileType = MeshFileType.NbssAppointmentEvents,
139+
MailboxId = "test-mailbox",
140+
FileId = fileId,
141+
Status = MeshFileStatus.Discovered,
142+
LastUpdatedUtc = DateTime.UtcNow.AddHours(-2)
143+
};
144+
_dbContext.MeshFiles.Add(file);
145+
await _dbContext.SaveChangesAsync();
146+
147+
_meshInboxServiceMock.Setup(s => s.GetMessageByIdAsync("test-mailbox", fileId))
148+
.ReturnsAsync(new MeshResponse<GetMessageResponse>
149+
{
150+
IsSuccessful = false,
151+
});
152+
153+
var message = new FileExtractQueueMessage { FileId = fileId };
5154

155+
var exception = await Assert.ThrowsAsync<InvalidOperationException>(() => _function.Run(message));
156+
Assert.Contains("Mesh extraction failed", exception.Message);
157+
}
6158
}

0 commit comments

Comments
 (0)