Skip to content

Commit 7fb0e9b

Browse files
committed
more test coverage
1 parent b847dd5 commit 7fb0e9b

1 file changed

Lines changed: 364 additions & 0 deletions

File tree

Lines changed: 364 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
using System;
17+
using System.Collections.Generic;
18+
using System.Text.Json.Serialization;
19+
using System.Threading;
20+
using System.Threading.Tasks;
21+
using Amazon.Lambda.Core;
22+
using Amazon.Lambda.SQSEvents;
23+
using AWS.Lambda.Powertools.BatchProcessing.Sqs;
24+
using NSubstitute;
25+
using Xunit;
26+
27+
namespace AWS.Lambda.Powertools.BatchProcessing.Tests;
28+
29+
/// <summary>
30+
/// Tests for BatchProcessorAttribute validation and error handling scenarios.
31+
/// </summary>
32+
[Collection("BatchProcessorTests")]
33+
public partial class BatchProcessorAttributeValidationTests
34+
{
35+
public class TestData
36+
{
37+
public string Id { get; set; }
38+
public string Name { get; set; }
39+
}
40+
41+
public class ValidHandler : ITypedRecordHandler<TestData>
42+
{
43+
public async Task<RecordHandlerResult> HandleAsync(TestData data, CancellationToken cancellationToken)
44+
{
45+
return await Task.FromResult(RecordHandlerResult.None);
46+
}
47+
}
48+
49+
public class ValidHandlerWithContext : ITypedRecordHandlerWithContext<TestData>
50+
{
51+
public async Task<RecordHandlerResult> HandleAsync(TestData data, ILambdaContext context, CancellationToken cancellationToken)
52+
{
53+
return await Task.FromResult(RecordHandlerResult.None);
54+
}
55+
}
56+
57+
public class InvalidHandler
58+
{
59+
// Does not implement any batch processing interface
60+
}
61+
62+
public class ValidHandlerProvider : ITypedRecordHandlerProvider<TestData>
63+
{
64+
public ITypedRecordHandler<TestData> Create()
65+
{
66+
return new ValidHandler();
67+
}
68+
}
69+
70+
public class InvalidHandlerProvider
71+
{
72+
// Missing Create method
73+
}
74+
75+
public class ValidHandlerWithContextProvider : ITypedRecordHandlerWithContextProvider<TestData>
76+
{
77+
public ITypedRecordHandlerWithContext<TestData> Create()
78+
{
79+
return new ValidHandlerWithContext();
80+
}
81+
}
82+
83+
public class InvalidHandlerWithContextProvider
84+
{
85+
// Missing Create method
86+
}
87+
88+
[JsonSerializable(typeof(TestData))]
89+
public partial class TestJsonContext : JsonSerializerContext
90+
{
91+
}
92+
93+
public class InvalidJsonContext
94+
{
95+
// Does not inherit from JsonSerializerContext
96+
}
97+
98+
public class TestFunctions
99+
{
100+
[BatchProcessor(TypedRecordHandler = typeof(ValidHandler), TypedRecordHandlerWithContext = typeof(ValidHandlerWithContext))]
101+
public BatchItemFailuresResponse ProcessWithMultipleHandlers(SQSEvent sqsEvent)
102+
{
103+
return TypedSqsBatchProcessor.Result.BatchItemFailuresResponse;
104+
}
105+
106+
[BatchProcessor(JsonSerializerContext = typeof(TestJsonContext), TypedRecordHandler = typeof(ValidHandler))]
107+
public BatchItemFailuresResponse ProcessWithJsonContext(SQSEvent sqsEvent)
108+
{
109+
TypedSqsBatchProcessor.Result?.Clear();
110+
return TypedSqsBatchProcessor.Result.BatchItemFailuresResponse;
111+
}
112+
113+
[BatchProcessor(JsonSerializerContext = typeof(InvalidJsonContext), TypedRecordHandler = typeof(ValidHandler))]
114+
public BatchItemFailuresResponse ProcessWithInvalidJsonContext(SQSEvent sqsEvent)
115+
{
116+
return TypedSqsBatchProcessor.Result.BatchItemFailuresResponse;
117+
}
118+
119+
[BatchProcessor(TypedRecordHandlerProvider = typeof(ValidHandlerProvider))]
120+
public BatchItemFailuresResponse ProcessWithValidProvider(SQSEvent sqsEvent)
121+
{
122+
TypedSqsBatchProcessor.Result?.Clear();
123+
return TypedSqsBatchProcessor.Result.BatchItemFailuresResponse;
124+
}
125+
126+
[BatchProcessor(TypedRecordHandlerProvider = typeof(InvalidHandlerProvider))]
127+
public BatchItemFailuresResponse ProcessWithInvalidProvider(SQSEvent sqsEvent)
128+
{
129+
return TypedSqsBatchProcessor.Result.BatchItemFailuresResponse;
130+
}
131+
132+
[BatchProcessor(TypedRecordHandlerWithContextProvider = typeof(ValidHandlerWithContextProvider))]
133+
public BatchItemFailuresResponse ProcessWithValidContextProvider(SQSEvent sqsEvent, ILambdaContext context)
134+
{
135+
TypedSqsBatchProcessor.Result?.Clear();
136+
return TypedSqsBatchProcessor.Result.BatchItemFailuresResponse;
137+
}
138+
139+
[BatchProcessor(TypedRecordHandlerWithContextProvider = typeof(InvalidHandlerWithContextProvider))]
140+
public BatchItemFailuresResponse ProcessWithInvalidContextProvider(SQSEvent sqsEvent, ILambdaContext context)
141+
{
142+
return TypedSqsBatchProcessor.Result.BatchItemFailuresResponse;
143+
}
144+
145+
public BatchItemFailuresResponse ProcessWithoutAttribute(SQSEvent sqsEvent)
146+
{
147+
return new BatchItemFailuresResponse();
148+
}
149+
}
150+
151+
[Fact]
152+
public void BatchProcessorAttribute_WithMultipleHandlers_ThrowsInvalidOperationException()
153+
{
154+
// Arrange
155+
var sqsEvent = new SQSEvent
156+
{
157+
Records = new List<SQSEvent.SQSMessage>
158+
{
159+
new SQSEvent.SQSMessage
160+
{
161+
MessageId = "1",
162+
Body = "{\"Id\":\"test-1\",\"Name\":\"Test Data\"}",
163+
EventSourceArn = "arn:aws:sqs:us-east-1:123456789012:test-queue"
164+
}
165+
}
166+
};
167+
168+
var function = new TestFunctions();
169+
170+
// Act & Assert
171+
Assert.Throws<InvalidOperationException>(() => function.ProcessWithMultipleHandlers(sqsEvent));
172+
}
173+
174+
[Fact]
175+
public void BatchProcessorAttribute_WithJsonContext_ProcessesSuccessfully()
176+
{
177+
// Arrange
178+
var sqsEvent = new SQSEvent
179+
{
180+
Records = new List<SQSEvent.SQSMessage>
181+
{
182+
new SQSEvent.SQSMessage
183+
{
184+
MessageId = "1",
185+
Body = "{\"Id\":\"test-1\",\"Name\":\"Test Data\"}",
186+
EventSourceArn = "arn:aws:sqs:us-east-1:123456789012:test-queue"
187+
}
188+
}
189+
};
190+
191+
var function = new TestFunctions();
192+
193+
// Act
194+
var result = function.ProcessWithJsonContext(sqsEvent);
195+
196+
// Assert
197+
Assert.NotNull(result);
198+
Assert.Empty(result.BatchItemFailures);
199+
}
200+
201+
[Fact]
202+
public void BatchProcessorAttribute_WithInvalidJsonContext_ThrowsInvalidOperationException()
203+
{
204+
// Arrange
205+
var sqsEvent = new SQSEvent
206+
{
207+
Records = new List<SQSEvent.SQSMessage>
208+
{
209+
new SQSEvent.SQSMessage
210+
{
211+
MessageId = "1",
212+
Body = "{\"Id\":\"test-1\",\"Name\":\"Test Data\"}",
213+
EventSourceArn = "arn:aws:sqs:us-east-1:123456789012:test-queue"
214+
}
215+
}
216+
};
217+
218+
var function = new TestFunctions();
219+
220+
// Act & Assert
221+
Assert.Throws<InvalidOperationException>(() => function.ProcessWithInvalidJsonContext(sqsEvent));
222+
}
223+
224+
[Fact]
225+
public void BatchProcessorAttribute_WithValidProvider_ProcessesSuccessfully()
226+
{
227+
// Arrange
228+
var sqsEvent = new SQSEvent
229+
{
230+
Records = new List<SQSEvent.SQSMessage>
231+
{
232+
new SQSEvent.SQSMessage
233+
{
234+
MessageId = "1",
235+
Body = "{\"Id\":\"test-1\",\"Name\":\"Test Data\"}",
236+
EventSourceArn = "arn:aws:sqs:us-east-1:123456789012:test-queue"
237+
}
238+
}
239+
};
240+
241+
var function = new TestFunctions();
242+
243+
// Act
244+
var result = function.ProcessWithValidProvider(sqsEvent);
245+
246+
// Assert
247+
Assert.NotNull(result);
248+
Assert.Empty(result.BatchItemFailures);
249+
}
250+
251+
[Fact]
252+
public void BatchProcessorAttribute_WithInvalidProvider_ThrowsInvalidOperationException()
253+
{
254+
// Arrange
255+
var sqsEvent = new SQSEvent
256+
{
257+
Records = new List<SQSEvent.SQSMessage>
258+
{
259+
new SQSEvent.SQSMessage
260+
{
261+
MessageId = "1",
262+
Body = "{\"Id\":\"test-1\",\"Name\":\"Test Data\"}",
263+
EventSourceArn = "arn:aws:sqs:us-east-1:123456789012:test-queue"
264+
}
265+
}
266+
};
267+
268+
var function = new TestFunctions();
269+
270+
// Act & Assert
271+
Assert.Throws<InvalidOperationException>(() => function.ProcessWithInvalidProvider(sqsEvent));
272+
}
273+
274+
[Fact]
275+
public void BatchProcessorAttribute_WithValidContextProvider_ProcessesSuccessfully()
276+
{
277+
// Arrange
278+
var sqsEvent = new SQSEvent
279+
{
280+
Records = new List<SQSEvent.SQSMessage>
281+
{
282+
new SQSEvent.SQSMessage
283+
{
284+
MessageId = "1",
285+
Body = "{\"Id\":\"test-1\",\"Name\":\"Test Data\"}",
286+
EventSourceArn = "arn:aws:sqs:us-east-1:123456789012:test-queue"
287+
}
288+
}
289+
};
290+
291+
var mockContext = Substitute.For<ILambdaContext>();
292+
var function = new TestFunctions();
293+
294+
// Act
295+
var result = function.ProcessWithValidContextProvider(sqsEvent, mockContext);
296+
297+
// Assert
298+
Assert.NotNull(result);
299+
Assert.Empty(result.BatchItemFailures);
300+
}
301+
302+
[Fact]
303+
public void BatchProcessorAttribute_WithInvalidContextProvider_ThrowsInvalidOperationException()
304+
{
305+
// Arrange
306+
var sqsEvent = new SQSEvent
307+
{
308+
Records = new List<SQSEvent.SQSMessage>
309+
{
310+
new SQSEvent.SQSMessage
311+
{
312+
MessageId = "1",
313+
Body = "{\"Id\":\"test-1\",\"Name\":\"Test Data\"}",
314+
EventSourceArn = "arn:aws:sqs:us-east-1:123456789012:test-queue"
315+
}
316+
}
317+
};
318+
319+
var mockContext = Substitute.For<ILambdaContext>();
320+
var function = new TestFunctions();
321+
322+
// Act & Assert
323+
Assert.Throws<InvalidOperationException>(() => function.ProcessWithInvalidContextProvider(sqsEvent, mockContext));
324+
}
325+
326+
[Fact]
327+
public void BatchProcessorAttribute_CreateAspectHandler_WithNullArgs_ThrowsArgumentException()
328+
{
329+
// Arrange
330+
var attribute = new BatchProcessorAttribute
331+
{
332+
TypedRecordHandler = typeof(ValidHandler)
333+
};
334+
335+
// Act & Assert
336+
Assert.Throws<ArgumentException>(() => attribute.CreateAspectHandler(null));
337+
}
338+
339+
[Fact]
340+
public void BatchProcessorAttribute_CreateAspectHandler_WithEmptyArgs_ThrowsArgumentException()
341+
{
342+
// Arrange
343+
var attribute = new BatchProcessorAttribute
344+
{
345+
TypedRecordHandler = typeof(ValidHandler)
346+
};
347+
348+
// Act & Assert
349+
Assert.Throws<ArgumentException>(() => attribute.CreateAspectHandler(new object[0]));
350+
}
351+
352+
[Fact]
353+
public void BatchProcessorAttribute_CreateAspectHandler_WithInvalidEventType_ThrowsArgumentException()
354+
{
355+
// Arrange
356+
var attribute = new BatchProcessorAttribute
357+
{
358+
TypedRecordHandler = typeof(ValidHandler)
359+
};
360+
361+
// Act & Assert
362+
Assert.Throws<ArgumentException>(() => attribute.CreateAspectHandler(new object[] { "invalid event" }));
363+
}
364+
}

0 commit comments

Comments
 (0)