public async void MultipleConcurrentRequestsAddedUnderCapacity()
        {
            // Given
            const string ClientId = "tester";

            var configuration = new ConcurrentRequestLimiterConfiguration();
            var loggerMock    = new Mock <ILogger <InMemoryConcurrentRequestsManager> >();
            var manager       = new InMemoryConcurrentRequestsManager(configuration, loggerMock.Object);

            // When multiple requests are added
            var tasks = new List <Task <AddConcurrentRequestResult> >();

            tasks.Add(manager.AddAsync(ClientId, Guid.NewGuid().ToString(), DateTimeOffset.UtcNow.ToUnixTimeSeconds()));
            tasks.Add(manager.AddAsync(ClientId, Guid.NewGuid().ToString(), DateTimeOffset.UtcNow.ToUnixTimeSeconds()));
            var results = await Task.WhenAll(tasks);

            // Then the manager should allow first request
            results[0].IsAllowed.Should().BeTrue();
            results[0].Limit.Should().Be(configuration.Capacity);
            results[0].Remaining.Should().Be(configuration.Capacity - 1);

            // And the manager should allow second request
            results[1].IsAllowed.Should().BeTrue();
            results[1].Limit.Should().Be(configuration.Capacity);
            results[1].Remaining.Should().Be(configuration.Capacity - 2);
        }
        public async void RemovingARequestWhichWasNeverAdded()
        {
            // Given
            const string ClientId = "tester";

            var configuration = new ConcurrentRequestLimiterConfiguration();
            var loggerMock    = new Mock <ILogger <InMemoryConcurrentRequestsManager> >();
            var manager       = new InMemoryConcurrentRequestsManager(configuration, loggerMock.Object);

            // When a request is removed
            var result = await manager.RemoveAsync(ClientId, Guid.NewGuid().ToString());

            // Then the manager should not remove anything
            result.Should().BeFalse();
        }
        public async void APreviouslyAddedRequestIsRemoved()
        {
            // Given
            const string ClientId  = "tester";
            const string RequestId = "123";

            var configuration = new ConcurrentRequestLimiterConfiguration();
            var loggerMock    = new Mock <ILogger <InMemoryConcurrentRequestsManager> >();
            var manager       = new InMemoryConcurrentRequestsManager(configuration, loggerMock.Object);

            await manager.AddAsync(ClientId, RequestId, DateTimeOffset.UtcNow.ToUnixTimeSeconds());

            // When a request is removed
            var result = await manager.RemoveAsync(ClientId, RequestId);

            // Then the manager should remove the request
            result.Should().BeTrue();
        }
        public async void ARequestIsAddedOverCapacity()
        {
            // Given
            const string ClientId = "tester";

            var configuration = new ConcurrentRequestLimiterConfiguration();
            var loggerMock    = new Mock <ILogger <InMemoryConcurrentRequestsManager> >();
            var manager       = new InMemoryConcurrentRequestsManager(configuration, loggerMock.Object);

            for (var i = 0; i < configuration.Capacity; i++)
            {
                await manager.AddAsync(ClientId, Guid.NewGuid().ToString(), DateTimeOffset.UtcNow.ToUnixTimeSeconds());
            }

            // When a request is added over capacity
            var result = await manager.AddAsync(ClientId, Guid.NewGuid().ToString(), DateTimeOffset.UtcNow.ToUnixTimeSeconds());

            // Then the manager should not allow the request
            result.IsAllowed.Should().BeFalse();
            result.Limit.Should().Be(configuration.Capacity);
            result.Remaining.Should().Be(0);
        }