public async Task A_new_message_with_edited_body_is_sent()
        {
            var context = await Define <EditMessageContext>()
                          .WithEndpoint <EditedMessageReceiver>(e => e
                                                                .DoNotFailOnErrorMessages()
                                                                .When(c => c.SendLocal(new EditMessage {
                SomeProperty = "StarTrek rocks"
            })))
                          .Done(async ctx =>
            {
                if (string.IsNullOrWhiteSpace(ctx.UniqueMessageId))
                {
                    return(false);
                }

                if (!ctx.EditedMessage)
                {
                    var failedMessage = await this.TryGet <FailedMessage>($"/api/errors/{ctx.UniqueMessageId}");
                    if (!failedMessage.HasResult)
                    {
                        return(false);
                    }

                    ctx.EditedMessage = true;
                    var editedMessage = JsonConvert.SerializeObject(new EditMessage
                    {
                        SomeProperty = "StarWars rocks"
                    });
                    var editModel = new EditMessageModel
                    {
                        MessageBody    = editedMessage,
                        MessageHeaders = EditMessageHelper.TryRestoreOriginalHeaderKeys(failedMessage.Item.ProcessingAttempts.Last().Headers)
                    };
                    await this.Post($"/api/edit/{ctx.UniqueMessageId}", editModel);
                    return(false);
                }

                if (ctx.EditedMessageProperty == null)
                {
                    return(false);
                }

                ctx.OriginalMessageFailure = (await this.TryGet <FailedMessage>($"/api/errors/{ctx.UniqueMessageId}")).Item;
                return(true);
            })
                          .Run();

            Assert.AreEqual("StarWars rocks", context.EditedMessageProperty);
            Assert.AreNotEqual(context.OriginalMessageId, context.EditedMessageId);
            Assert.AreEqual(FailedMessageStatus.Resolved, context.OriginalMessageFailure.Status);
            CollectionAssert.DoesNotContain(context.EditedMessageHeaders, "NServiceBus.ExceptionInfo.StackTrace");
        }
        public async Task A_new_message_with_edited_headers_is_sent()
        {
            var context = await Define <EditMessageContext>()
                          .WithEndpoint <EditedMessageReceiver>(e => e
                                                                .DoNotFailOnErrorMessages()
                                                                .When(c => c.SendLocal(new EditMessage())))
                          .Done(async ctx =>
            {
                if (string.IsNullOrWhiteSpace(ctx.UniqueMessageId))
                {
                    return(false);
                }

                if (!ctx.EditedMessage)
                {
                    var failedMessage = await this.TryGet <FailedMessage>($"/api/errors/{ctx.UniqueMessageId}");
                    if (!failedMessage.HasResult)
                    {
                        return(false);
                    }

                    ctx.EditedMessage = true;
                    var newHeaders    = EditMessageHelper.TryRestoreOriginalHeaderKeys(failedMessage.Item.ProcessingAttempts.Last().Headers);
                    newHeaders.Add(new KeyValuePair <string, string>("AcceptanceTest.NewHeader", "42"));
                    var editModel = new EditMessageModel
                    {
                        MessageBody    = JsonConvert.SerializeObject(new EditMessage()),
                        MessageHeaders = newHeaders
                    };

                    await this.Post($"/api/edit/{ctx.UniqueMessageId}", editModel);
                    return(false);
                }

                if (ctx.EditedMessageHeaders == null)
                {
                    return(false);
                }

                ctx.OriginalMessageFailure = (await this.TryGet <FailedMessage>($"/api/errors/{ctx.UniqueMessageId}")).Item;
                return(true);
            })
                          .Run();

            Assert.AreNotEqual(context.OriginalMessageId, context.EditedMessageId);
            Assert.AreEqual(FailedMessageStatus.Resolved, context.OriginalMessageFailure.Status);
            CollectionAssert.AreEqual("42", context.EditedMessageHeaders["AcceptanceTest.NewHeader"]);
            CollectionAssert.AreEqual(context.UniqueMessageId, context.EditedMessageHeaders["ServiceControl.EditOf"]);
        }
        public async Task A_new_message_failure_is_created()
        {
            var context = await Define <EditMessageFailureContext>()
                          .WithEndpoint <FailingEditedMessageReceiver>(e => e
                                                                       .When(c => c.SendLocal(new FailingMessage()))
                                                                       .DoNotFailOnErrorMessages())
                          .Done(async ctx =>
            {
                if (ctx.OriginalMessageFailureId == null)
                {
                    return(false);
                }

                if (!ctx.EditedMessage)
                {
                    var failedMessage = await this.TryGet <FailedMessage>($"/api/errors/{ctx.OriginalMessageFailureId}");
                    if (!failedMessage.HasResult)
                    {
                        return(false);
                    }

                    ctx.EditedMessage = true;
                    var editedMessage = JsonConvert.SerializeObject(new FailingMessage
                    {
                        HasBeenEdited = true
                    });
                    var editModel = new EditMessageModel
                    {
                        MessageBody    = editedMessage,
                        MessageHeaders = EditMessageHelper.TryRestoreOriginalHeaderKeys(failedMessage.Item.ProcessingAttempts.Last().Headers)
                    };
                    await this.Post($"/api/edit/{ctx.OriginalMessageFailureId}", editModel);

                    return(false);
                }

                if (ctx.EditedMessageFailureId == null)
                {
                    return(false);
                }

                var failedEditedMessage = await this.TryGet <FailedMessage>($"/api/errors/{ctx.EditedMessageFailureId}");
                if (!failedEditedMessage.HasResult)
                {
                    return(false);
                }

                ctx.OriginalMessageFailure = (await this.TryGet <FailedMessage>($"/api/errors/{ctx.OriginalMessageFailureId}")).Item;
                ctx.EditedMessageFailure   = (await this.TryGet <FailedMessage>($"/api/errors/{ctx.EditedMessageFailureId}")).Item;
                return(true);
            })
                          .Run();

            Assert.AreNotEqual(context.EditedMessageFailure.Id, context.OriginalMessageFailure.Id);
            Assert.AreNotEqual(context.EditedMessageFailure.UniqueMessageId, context.OriginalMessageFailure.UniqueMessageId);
            Assert.AreEqual(FailedMessageStatus.Resolved, context.OriginalMessageFailure.Status);
            Assert.AreEqual(FailedMessageStatus.Unresolved, context.EditedMessageFailure.Status);
            Assert.AreEqual(
                context.OriginalMessageFailure.Id,
                "FailedMessages/" + context.EditedMessageFailure.ProcessingAttempts.Last().Headers["service_control.edit_of"]);
        }