async Task <TransactionWatch <Rule> > CreateWatch(Rule rule, uint256 startBlock, uint256 tx)
        {
            var watch = new TransactionWatch <Rule>(rule, startBlock, tx);

            await this.watchRepository.AddAsync(watch, CancellationToken.None);

            return(watch);
        }
        public Task ExecuteAsync_ConfirmationUpdateAsyncReturnTrue_ShouldRemoveThatWatch(BlockEventType eventType)
        {
            return(AsynchronousTesting.WithCancellationTokenAsync(async cancellationToken =>
            {
                // Arrange.
                var watch1 = new TransactionWatch <object>(null, TestBlock.Regtest0.GetHash(), uint256.One);
                var watch2 = new TransactionWatch <object>(null, TestBlock.Regtest1.GetHash(), uint256.One);
                var watches = new[] { watch1, watch2 };

                var confirmationType = FakeConfirmationWatcher.GetConfirmationType(eventType);

                this.handler.Setup(h => h.GetCurrentWatchesAsync(It.IsAny <CancellationToken>()))
                .Returns(Task.FromResult <IEnumerable <TransactionWatch <object> > >(watches));

                this.handler.Setup(h => h.ConfirmationUpdateAsync(watch1, 2, confirmationType, It.IsAny <CancellationToken>()))
                .Returns(Task.FromResult(false));
                this.handler.Setup(h => h.ConfirmationUpdateAsync(watch2, 1, confirmationType, It.IsAny <CancellationToken>()))
                .Returns(Task.FromResult(true));

                this.blocks.Setup(b => b.GetAsync(TestBlock.Regtest0.GetHash(), It.IsAny <CancellationToken>()))
                .Returns(Task.FromResult((TestBlock.Regtest0, 0)));
                this.blocks.Setup(b => b.GetAsync(TestBlock.Regtest1.GetHash(), It.IsAny <CancellationToken>()))
                .Returns(Task.FromResult((TestBlock.Regtest1, 1)));

                // Act.
                await this.subject.ExecuteAsync(TestBlock.Regtest1, 1, eventType, cancellationToken);

                // Assert.
                this.handler.Verify(
                    h => h.ConfirmationUpdateAsync(
                        watch1,
                        2,
                        confirmationType,
                        CancellationToken.None
                        ),
                    Times.Once()
                    );

                this.handler.Verify(
                    h => h.ConfirmationUpdateAsync(
                        watch2,
                        1,
                        confirmationType,
                        CancellationToken.None
                        ),
                    Times.Once()
                    );

                this.handler.Verify(
                    h => h.RemoveCompletedWatchesAsync(
                        new[] { watch2 },
                        CancellationToken.None
                        ),
                    Times.Once()
                    );
            }));
        }
        public void TransactionId_WhenConstructed_ShouldSameAsConstructorArg()
        {
            var subject1 = new TransactionWatch <object>(null, uint256.One, uint256.One);
            var subject2 = new TransactionWatch <object>(null, uint256.One, uint256.One, DateTime.Now);
            var subject3 = new TransactionWatch <object>(null, uint256.One, uint256.One, DateTime.Now, Guid.NewGuid());

            Assert.Equal(uint256.One, subject1.TransactionId);
            Assert.Equal(uint256.One, subject2.TransactionId);
            Assert.Equal(uint256.One, subject3.TransactionId);
        }
        public async Task RemoveUncompletedWatchesAsync_TimerShouldbeResume()
        {
            // Arrange.
            var builder = new WatchArgsBuilder(this.callbackRepository);

            builder.Timeout       = TimeSpan.FromMilliseconds(500);
            builder.Confirmations = 10;

            var rule = await builder.Call(this.subject.AddTransactionAsync);

            var watches = new List <TransactionWatch <Rule> >();
            var watch   = new TransactionWatch <Rule>(rule, uint256.Zero, builder.Transaction);

            watches.Add(watch);

            await this.handler.AddWatchesAsync(watches, CancellationToken.None);

            // Act.
            await this.handler.RemoveUncompletedWatchesAsync(uint256.Zero, CancellationToken.None);

            Thread.Sleep(TimeSpan.FromMilliseconds(1000));

            // Assert.
            _ = this.callbackExecuter.Received(1).ExecuteAsync
                (
                rule.Callback.Id,
                rule.Callback.Url,
                Arg.Is <CallbackResult>
                (
                    result => result.Status == CallbackResult.StatusError
                ),
                Arg.Any <CancellationToken>()
                );

            _ = this.ruleRepository.Received(1).UpdateCurrentWatchAsync(
                Arg.Is <Guid>(id => id == rule.Id), Arg.Is <Guid?>(id => id == null), Arg.Any <CancellationToken>());
        }