public async Task ScheduleAsync_DeleteSchedulesThatExistButHaveDifferentCronExpressions()
        {
            // Arrange
            var name              = BaseValueGenerator.Word();
            var queueName         = Default.Queue;
            var cron              = Cron.Daily();
            var payload           = Guid.NewGuid().ToByteArray();
            var command           = new BasicCommand();
            var cancellationToken = CancellationToken.None;
            var existingItem      = new ScheduleItem
            {
                Id             = Guid.NewGuid(),
                CronExpression = Cron.Weekly().Expression,
                Name           = name,
                Payload        = Guid.NewGuid().ToByteArray(),
                Queue          = queueName
            };

            _payloadSerializer.SerializeAsync(command, cancellationToken).Returns(Task.FromResult(payload));
            _scheduleProviderFactory.CreateAsync(queueName, cancellationToken).Returns(Task.FromResult(_scheduleProvider));
            _scheduleProvider.LoadByNameAsync(name, cancellationToken).Returns(Task.FromResult(existingItem));

            // Act
            await _sut.ScheduleAsync(name, command, Cron.Daily(), cancellationToken);

            // Assert
            await _scheduleProvider.Received(1).DeleteAsync(existingItem.Id, cancellationToken);

            await _scheduleProvider.Received(1).CreateAsync(Arg.Is <ScheduleItem>(x => x.Queue == queueName && x.CronExpression == cron.Expression), cancellationToken);
        }
        public async Task ScheduleAsync_SkipSchedulesThatAlreadyExists()
        {
            // Arrange
            var name              = BaseValueGenerator.Word();
            var queueName         = Default.Queue;
            var cron              = Cron.Weekly();
            var payload           = Guid.NewGuid().ToByteArray();
            var command           = new BasicCommand();
            var cancellationToken = CancellationToken.None;
            var existingItem      = new ScheduleItem
            {
                CronExpression = cron.Expression,
                Name           = name,
                Payload        = payload,
                Queue          = queueName
            };

            _payloadSerializer.SerializeAsync(command, cancellationToken).Returns(Task.FromResult(payload));
            _payloadProtector.ProtectAsync(payload, cancellationToken).Returns(Task.FromResult(payload));
            _scheduleProviderFactory.CreateAsync(queueName, cancellationToken).Returns(Task.FromResult(_scheduleProvider));
            _scheduleProvider.LoadByNameAsync(name, cancellationToken).Returns(Task.FromResult(existingItem));

            // Act
            await _sut.ScheduleAsync(name, command, cron, cancellationToken);

            // Assert
            await _scheduleProvider.DidNotReceiveWithAnyArgs().CreateAsync(default(ScheduleItem), cancellationToken);
        }
        public async Task PublishAsync_WithDelayAndQueueName()
        {
            // Arrange
            var queueName         = BaseValueGenerator.Word();
            var command           = new BasicCommand();
            var delay             = GenFu.GenFu.Random.Next();
            var cancellationToken = CancellationToken.None;

            _payloadSerializer.SerializeAsync(command, cancellationToken).Returns(Task.FromResult <byte[]>(null));
            _workProviderFactory.CreateAsync(queueName, cancellationToken).Returns(Task.FromResult(_workProvider));

            // Act
            await _sut.PublishAsync(command, queueName, delay, cancellationToken);

            // Assert
            await _workProvider.Received(1).SendAsync(Arg.Is <WorkItem>(x => x.Queue == queueName), delay, cancellationToken);
        }
        public async Task ScheduleAsync_WithQueueNameAttribute()
        {
            // Arrange
            var name              = BaseValueGenerator.Word();
            var queueName         = "custom-queue-name";
            var cron              = Cron.Weekly();
            var command           = new BasicWithAttributeCommand();
            var cancellationToken = CancellationToken.None;

            _payloadSerializer.SerializeAsync(command, cancellationToken).Returns(Task.FromResult <byte[]>(null));
            _scheduleProviderFactory.CreateAsync(queueName, cancellationToken).Returns(Task.FromResult(_scheduleProvider));

            // Act
            await _sut.ScheduleAsync(name, command, cron, cancellationToken);

            // Assert
            await _scheduleProvider.Received(1).CreateAsync(Arg.Is <ScheduleItem>(x => x.Queue == queueName && x.CronExpression == cron.Expression), cancellationToken);
        }