public async Task Test_CreateSubtask_Empty_TaskId_Should_noop()
        {
            // arrange
            var job = new JobFaker().Generate();

            await using var dbContext = DbContextFactory.Instance.CreateDbContext <PortAuthorityDbContext>();
            await dbContext.Setup(x => x.Jobs, job);

            var message = new TestCreateSubtaskMessage()
            {
                JobId  = job.JobId,
                TaskId = Guid.Empty,
                Name   = "test-create-subtask-empty-taskid"
            };

            // act
            await _consumer.Consume(new TestConsumeContext <CreateSubtask>(message));

            // assert
            var actual = DbContextFactory.Instance
                         .CreateDbContext <PortAuthorityDbContext>()
                         .Tasks.ToList();

            actual.Should().BeNullOrEmpty("no tasks created without a valid parent job id");
        }
        public async Task Test_CreateSubtask_Should_PersistNewJob()
        {
            // arrange
            var job = new JobFaker().Generate();

            await using var dbContext = DbContextFactory.Instance.CreateDbContext <PortAuthorityDbContext>();
            await dbContext.Setup(x => x.Jobs, job);

            var message = new TestCreateSubtaskMessage()
            {
                JobId  = job.JobId,
                TaskId = NewId.NextGuid(),
                Name   = "test-create-subtask",
                Meta   = new Dictionary <string, object>()
                {
                    { "foo", "bar" },
                    { "baz", 1 },
                    { "zap", DateTime.UtcNow }
                }
            };

            // act
            await _consumer.Consume(new TestConsumeContext <CreateSubtask>(message));

            // assert
            var actual = DbContextFactory.Instance
                         .CreateDbContext <PortAuthorityDbContext>()
                         .Tasks.SingleOrDefault(t => t.TaskId == message.TaskId);

            actual.Should().NotBeNull();
            actual.TaskId.Should().Be(message.TaskId);
            actual.Name.Should().Be(message.Name);
            actual.Meta.Should().BeEquivalentTo(message.Meta);
        }
        public async Task Test_CreateSubtaskConsumer_Should_ConsumeMessage_And_CreateJob()
        {
            // arrange
            var consumerHarness = Consumer <CreateSubtaskConsumer>();

            var job = new JobFaker().Generate("default,InProgress");

            await using var dbContext = GetDbContext();
            await dbContext.Setup(x => x.Jobs, job);

            var message = new TestCreateSubtaskMessage()
            {
                JobId  = job.JobId,
                TaskId = NewId.NextGuid(),
                Name   = "test-create-subtask",
                Meta   = new Dictionary <string, object>()
                {
                    { "foo", "bar" },
                    { "baz", 1 },
                    { "zap", DateTime.UtcNow }
                }
            };

            await Harness.Start();

            try
            {
                // act
                await Harness.InputQueueSendEndpoint.Send <CreateSubtask>(message);

                // assert
                Assert.That(await Harness.Consumed.Any <CreateSubtask>(), "endpoint consumed message");
                Assert.That(await consumerHarness.Consumed.Any <CreateSubtask>(), "actual consumer consumed the message");
                Assert.That(await Harness.Published.Any <Fault <CreateSubtask> >(), Is.False, "message handled without fault");

                var actual = GetDbContext().Tasks.SingleOrDefault(t => t.TaskId == message.TaskId);

                actual.Should().NotBeNull();
                actual.TaskId.Should().Be(message.TaskId);
                actual.Name.Should().Be(message.Name);
                actual.Meta.Should().BeEquivalentTo(message.Meta);
            }
            finally
            {
                await Harness.Stop();
            }
        }
        public async Task Test_CreateSubtask_Invalid_ParentJobId_Should_Throw_InvalidOperationException()
        {
            // arrange
            var job = new JobFaker().Generate();

            await using var dbContext = DbContextFactory.Instance.CreateDbContext <PortAuthorityDbContext>();
            await dbContext.Setup(x => x.Jobs, job);

            var message = new TestCreateSubtaskMessage()
            {
                JobId  = Guid.NewGuid(),
                TaskId = NewId.NextGuid(),
                Name   = "test-create-subtask-invalid-jobid"
            };

            // act
            Func <Task> act = async() => { await _consumer.Consume(new TestConsumeContext <CreateSubtask>(message)); };

            // assert
            await act.Should().ThrowAsync <InvalidOperationException>();
        }