示例#1
0
    public async Task ShouldProjectImported()
    {
        var evt    = DomainFixture.CreateImportBooking();
        var stream = StreamName.For <Booking>(evt.BookingId);

        var append = await Instance.EventStore.AppendEvents(
            stream,
            ExpectedStreamVersion.Any,
            new[] {
            new StreamEvent(Guid.NewGuid(), evt, new Metadata(), "application/json", 0)
        },
            CancellationToken.None
            );

        await Task.Delay(500);

        var expected = new BookingDocument(evt.BookingId)
        {
            RoomId       = evt.RoomId,
            CheckInDate  = evt.CheckIn,
            CheckOutDate = evt.CheckOut,
            Position     = append.GlobalPosition
        };

        var actual = await Instance.Mongo.LoadDocument <BookingDocument>(evt.BookingId);

        actual.Should().Be(expected);
    }
    public async Task StreamSubscriptionGetsDeletedEvents()
    {
        var service = new BookingService(Instance.AggregateStore);

        var categoryStream = new StreamName("$ce-Booking");

        ulong?startPosition = null;

        try {
            var last = await Instance.Client.ReadStreamAsync(
                Direction.Backwards,
                categoryStream,
                StreamPosition.End,
                1
                ).ToArrayAsync();

            startPosition = last[0].OriginalEventNumber;
        }
        catch (StreamNotFound) { }

        const int produceCount = 20;
        const int deleteCount  = 5;

        var commands = Enumerable.Range(0, produceCount)
                       .Select(_ => DomainFixture.CreateImportBooking())
                       .ToArray();

        await Task.WhenAll(
            commands.Select(x => service.Handle(x, CancellationToken.None))
            );

        var delete = Enumerable.Range(5, deleteCount).Select(x => commands[x]).ToList();

        await Task.WhenAll(
            delete
            .Select(
                x => Instance.EventStore.DeleteStream(
                    StreamName.For <Booking>(x.BookingId),
                    ExpectedStreamVersion.Any,
                    CancellationToken.None
                    )
                )
            );

        var handler = new TestHandler();

        const string subscriptionId = "TestSub";

        var subscription = new StreamSubscription(
            Instance.Client,
            new StreamSubscriptionOptions {
            StreamName     = categoryStream,
            SubscriptionId = subscriptionId,
            ResolveLinkTos = true,
            ThrowOnError   = true
        },
            new NoOpCheckpointStore(startPosition),
            new ConsumePipe()
            .AddFilterLast(new MessageFilter(x => !x.MessageType.StartsWith("$")))
            .AddDefaultConsumer(handler)
            );

        var log = _loggerFactory.CreateLogger("Test");

        await subscription.SubscribeWithLog(log);

        var cts = new CancellationTokenSource(TimeSpan.FromSeconds(200));

        while (handler.Count < produceCount - deleteCount && !cts.IsCancellationRequested)
        {
            await Task.Delay(100);
        }

        await subscription.UnsubscribeWithLog(log);

        log.LogInformation("Received {Count} events", handler.Count);

        var actual = handler.Processed
                     .Select(x => (x.Message as BookingEvents.BookingImported) !.BookingId)
                     .ToList();

        log.LogInformation("Actual contains {Count} events", actual.Count);

        actual
        .Should()
        .BeEquivalentTo(commands.Except(delete).Select(x => x.BookingId));
    }