Skip to content

Commit 103ca61

Browse files
Testing Scenario 3
1 parent 6d42be2 commit 103ca61

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
namespace ServiceControl.AcceptanceTests.Recoverability.ExternalIntegration
2+
{
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
using AcceptanceTesting;
7+
using AcceptanceTesting.EndpointTemplates;
8+
using Contracts;
9+
using NServiceBus;
10+
using NServiceBus.AcceptanceTesting;
11+
using NUnit.Framework;
12+
using ServiceControl.MessageFailures;
13+
using ServiceControl.MessageFailures.Api;
14+
using JsonSerializer = System.Text.Json.JsonSerializer;
15+
16+
class When_a_reedit_solves_a_failed_msg : AcceptanceTest
17+
{
18+
[Test]
19+
public async Task Should_publish_notification()
20+
{
21+
var context = await Define<EditMessageResolutionContext>()
22+
.WithEndpoint<MessageReceiver>(b => b.When(async (bus, c) =>
23+
{
24+
await bus.Subscribe<MessageFailureResolvedByRetry>();
25+
}).When(c => c.SendLocal(new EditResolutionMessage() { MessageAttempt = 0 }))
26+
.DoNotFailOnErrorMessages())
27+
.Done(async ctx =>
28+
{
29+
if (!ctx.OriginalMessageHandled)
30+
{
31+
return false;
32+
}
33+
34+
if (!ctx.FirstEdit)
35+
{
36+
var failedMessagedId = await this.GetOnlyFailedUnresolvedMessageId();
37+
if (failedMessagedId == null)
38+
{
39+
return false;
40+
}
41+
42+
ctx.OriginalMessageFailureId = failedMessagedId;
43+
ctx.FirstEdit = true;
44+
45+
string editedMessage =
46+
JsonSerializer.Serialize(new EditResolutionMessage { MessageAttempt = 1 });
47+
48+
SingleResult<FailedMessage> failedMessage =
49+
await this.TryGet<FailedMessage>($"/api/errors/{ctx.OriginalMessageFailureId}");
50+
51+
var editModel = new EditMessageModel
52+
{
53+
MessageBody = editedMessage,
54+
MessageHeaders = failedMessage.Item.ProcessingAttempts.Last().Headers
55+
};
56+
await this.Post($"/api/edit/{ctx.OriginalMessageFailureId}", editModel);
57+
return false;
58+
}
59+
60+
if (!ctx.SecondEdit)
61+
{
62+
var failedMessagedId = await this.GetOnlyFailedUnresolvedMessageId();
63+
if (failedMessagedId == null)
64+
{
65+
return false;
66+
}
67+
68+
ctx.SecondMessageFailureId = failedMessagedId;
69+
ctx.SecondEdit = true;
70+
71+
string editedMessage =
72+
JsonSerializer.Serialize(new EditResolutionMessage { MessageAttempt = 2 });
73+
74+
SingleResult<FailedMessage> failedMessage =
75+
await this.TryGet<FailedMessage>($"/api/errors/{ctx.SecondMessageFailureId}");
76+
77+
var editModel = new EditMessageModel
78+
{
79+
MessageBody = editedMessage,
80+
MessageHeaders = failedMessage.Item.ProcessingAttempts.Last().Headers
81+
};
82+
await this.Post($"/api/edit/{ctx.SecondMessageFailureId}", editModel);
83+
return false;
84+
}
85+
86+
if (!ctx.EditedMessageHandled)
87+
{
88+
return false;
89+
}
90+
91+
if (!ctx.MessageResolved)
92+
{
93+
return false;
94+
}
95+
96+
return true;
97+
}).Run();
98+
99+
Assert.Multiple(() =>
100+
{
101+
Assert.That(context.ResolvedMessageId, Is.EqualTo(context.SecondMessageFailureId));
102+
Assert.That(context.EditedMessageEditOf1, Is.EqualTo(context.OriginalMessageFailureId));
103+
Assert.That(context.EditedMessageEditOf2, Is.EqualTo(context.SecondMessageFailureId));
104+
});
105+
}
106+
107+
108+
public class EditMessageResolutionContext : ScenarioContext
109+
{
110+
public bool OriginalMessageHandled { get; set; }
111+
public bool EditedMessage { get; set; }
112+
public string OriginalMessageFailureId { get; set; }
113+
public bool EditedMessageHandled { get; set; }
114+
public string ResolvedMessageId { get; set; }
115+
public bool MessageResolved { get; set; }
116+
public bool HasBeenEditedOnce { get; set; }
117+
public bool FirstEdit { get; set; }
118+
public bool SecondEdit { get; set; }
119+
public string SecondMessageFailureId { get; set; }
120+
public string EditedMessageEditOf2 { get; set; }
121+
public string EditedMessageEditOf1 { get; set; }
122+
}
123+
124+
public class MessageReceiver : EndpointConfigurationBuilder
125+
{
126+
public MessageReceiver() => EndpointSetup<DefaultServerWithoutAudit>(c => c.NoRetries());
127+
128+
129+
public class EditMessageResolutionHandler(EditMessageResolutionContext testContext)
130+
: IHandleMessages<EditResolutionMessage>, IHandleMessages<MessageFailureResolvedByRetry>
131+
{
132+
public Task Handle(EditResolutionMessage message, IMessageHandlerContext context)
133+
{
134+
switch (message.MessageAttempt)
135+
{
136+
case 0:
137+
testContext.OriginalMessageHandled = true;
138+
throw new SimulatedException();
139+
case 1:
140+
testContext.HasBeenEditedOnce = true;
141+
testContext.EditedMessageEditOf1 = context.MessageHeaders["ServiceControl.EditOf"];
142+
throw new SimulatedException();
143+
case 2:
144+
testContext.EditedMessageHandled = true;
145+
testContext.EditedMessageEditOf2 = context.MessageHeaders["ServiceControl.EditOf"];
146+
return Task.CompletedTask;
147+
default:
148+
return Task.CompletedTask;
149+
}
150+
}
151+
152+
public Task Handle(MessageFailureResolvedByRetry message, IMessageHandlerContext context)
153+
{
154+
testContext.ResolvedMessageId = message.FailedMessageId;
155+
testContext.MessageResolved = true;
156+
return Task.CompletedTask;
157+
}
158+
}
159+
}
160+
161+
public class EditResolutionMessage : IMessage
162+
{
163+
public int MessageAttempt { get; init; }
164+
}
165+
}
166+
}

0 commit comments

Comments
 (0)