public async Task ValidationCacheService_AddValidNonPresentKeyAndValidValue_ShouldWork()
        {
            // Arrange
            string key       = "some key";
            var    valueMock = new Mock <IValidationCacheServiceModel>();

            var repositoryMock = new Mock <IValidationCacheDataRepository>();

            repositoryMock
            .Setup(r => r.Add(key, It.IsAny <IValidationCacheEntity>()))
            .Returns(Task.FromResult <object>(true));

            var dateTimeProviderMock = new Mock <IDateTimeProvider>();

            var service = new ValidationCacheService(repositoryMock.Object, dateTimeProviderMock.Object);

            // Act
            var result = await service.Add(key, valueMock.Object);

            // Asset
            Assert.That(result, Is.EqualTo(true));

            repositoryMock.Verify(r => r.Add(key, It.IsAny <IValidationCacheEntity>()), Times.Once);
            dateTimeProviderMock.VerifyGet(p => p.Now, Times.Once);
        }
        public async Task ValidationCacheService_GetValidKeyWithListWithSingleValue_ShouldReturnANewCopyIt()
        {
            // Arrange
            string key       = "some key";
            var    valueMock = new Mock <IValidationCacheEntity>();
            var    value     = valueMock.Object;
            var    list      = new IValidationCacheEntity[] { value };

            var repositoryMock = new Mock <IValidationCacheDataRepository>();

            repositoryMock
            .Setup(r => r.GetAll(key))
            .Returns(list);

            var dateTimeProviderMock = new Mock <IDateTimeProvider>();

            var service = new ValidationCacheService(repositoryMock.Object, dateTimeProviderMock.Object);

            // Act
            var result = await service.Get(key);

            // Asset
            Assert.IsNotNull(result);
            Assert.AreNotSame(value, result);

            Assert.AreEqual(value.Content, result.Content);
            Assert.AreEqual(value.LastUpdate, result.LastUpdate);
            Assert.AreEqual(value.Status, result.Status);

            repositoryMock.Verify(r => r.GetAll(key), Times.Once);
            dateTimeProviderMock.VerifyGet(p => p.Now, Times.Never);
        }
        public async Task ValidationCacheService_GetAllValidKeyWithEmptyList_ShouldReturnEmptyIEnumerable()
        {
            // Arrange
            string key = "some key";

            var list = new List <IValidationCacheEntity>();

            var repositoryMock = new Mock <IValidationCacheDataRepository>();

            repositoryMock
            .Setup(r => r.GetAll(key))
            .Returns(list);

            var dateTimeProviderMock = new Mock <IDateTimeProvider>();

            var service = new ValidationCacheService(repositoryMock.Object, dateTimeProviderMock.Object);

            // Act
            var result = await service.Get(key);

            // Asset
            Assert.IsNull(result);

            repositoryMock.Verify(r => r.GetAll(key), Times.Once);
            dateTimeProviderMock.VerifyGet(p => p.Now, Times.Never);
        }
        public void ValidationCacheService_AddWithInvalidKeyAndNullValue_ShouldThrowArgumentNullException(string key)
        {
            // Arrange
            var repositoryMock       = new Mock <IValidationCacheDataRepository>();
            var dateTimeProviderMock = new Mock <IDateTimeProvider>();
            var service = new ValidationCacheService(repositoryMock.Object, dateTimeProviderMock.Object);

            // Act + Assert
            Assert.ThrowsAsync <ArgumentNullException>(() =>
            {
                return(service.Add(key, null));
            });

            repositoryMock.Verify(p => p.Add(It.IsAny <string>(), It.IsAny <IValidationCacheEntity>()), Times.Never);
            dateTimeProviderMock.VerifyGet(p => p.Now, Times.Never);
        }
        public async Task ValidationCacheService_GetValidKeyWithListWithTwoValues_ShouldReturnANewCopyOfTheLastUpdatedOne()
        {
            // Arrange
            string key = "some key";
            var    now = DateTime.Now;

            var value1Mock = new Mock <IValidationCacheEntity>();

            value1Mock
            .SetupGet(v => v.LastUpdate)
            .Returns(now);

            var value2Mock = new Mock <IValidationCacheEntity>();

            value2Mock
            .SetupGet(v => v.LastUpdate)
            .Returns(now + TimeSpan.FromHours(1));

            var expectedValue = value2Mock.Object;

            var list = new IValidationCacheEntity[] { value1Mock.Object, value2Mock.Object };

            var repositoryMock = new Mock <IValidationCacheDataRepository>();

            repositoryMock
            .Setup(r => r.GetAll(key))
            .Returns(list);

            var dateTimeProviderMock = new Mock <IDateTimeProvider>();

            var service = new ValidationCacheService(repositoryMock.Object, dateTimeProviderMock.Object);

            // Act
            var result = await service.Get(key);

            // Asset
            Assert.IsNotNull(result);
            Assert.AreNotSame(value1Mock.Object, result);
            Assert.AreNotSame(value2Mock.Object, result);

            Assert.AreEqual(expectedValue.Content, result.Content);
            Assert.AreEqual(expectedValue.LastUpdate, result.LastUpdate);
            Assert.AreEqual(expectedValue.Status, result.Status);

            repositoryMock.Verify(r => r.GetAll(key), Times.Once);
            dateTimeProviderMock.VerifyGet(p => p.Now, Times.Never);
        }
        public void ValidationCacheService_GetAllWithInvalidKey_ShouldThrowArgumentNullExceptionWithCorrectParamName(string key)
        {
            // Arrange
            var repositoryMock       = new Mock <IValidationCacheDataRepository>();
            var dateTimeProviderMock = new Mock <IDateTimeProvider>();
            var service = new ValidationCacheService(repositoryMock.Object, dateTimeProviderMock.Object);

            // Act + Assert
            var exception = Assert.ThrowsAsync <ArgumentNullException>(() =>
            {
                return(service.Get(key));
            });

            Assert.AreEqual(Constants.KeyParamName, exception.ParamName);

            repositoryMock.Verify(r => r.GetAll(key), Times.Never);
            dateTimeProviderMock.VerifyGet(p => p.Now, Times.Never);
        }
        public void ValidationCacheService_AddWithValidKeyAndNullValue_ShouldThrowArgumentNullExceptionWithCorrectParamName()
        {
            // Arrange
            string key                  = "some key";
            var    repositoryMock       = new Mock <IValidationCacheDataRepository>();
            var    dateTimeProviderMock = new Mock <IDateTimeProvider>();
            var    service              = new ValidationCacheService(repositoryMock.Object, dateTimeProviderMock.Object);

            // Act + Assert
            var exception = Assert.ThrowsAsync <ArgumentNullException>(() =>
            {
                return(service.Add(key, null));
            });

            Assert.AreEqual(Constants.ValueParamName, exception.ParamName);

            repositoryMock.Verify(p => p.Add(It.IsAny <string>(), It.IsAny <IValidationCacheEntity>()), Times.Never);
            dateTimeProviderMock.VerifyGet(p => p.Now, Times.Never);
        }
        public void ValidationCacheService_WithValidParametersInConstructor_ShouldBeInitializedCorrectly()
        {
            // Arrange
            var repositoryMock = new Mock <IValidationCacheDataRepository>();
            var repository     = repositoryMock.Object;

            var dateTimeProviderMock = new Mock <IDateTimeProvider>();
            var dateTimeProvider     = dateTimeProviderMock.Object;

            // Act
            var service = new ValidationCacheService(repository, dateTimeProvider);

            // Assert
            Assert.IsNotNull(service);

            var repositoryFieldValue = PrivateField.GetInstanceField <ValidationCacheService>(service, Constants.RepositoryParamName);

            Assert.AreSame(repository, repositoryFieldValue, "Repository field should be set correctly.");

            var dateTimeProviderFieldValue = PrivateField.GetInstanceField <ValidationCacheService>(service, Constants.DateTimeProviderParamName);

            Assert.AreEqual(dateTimeProvider, dateTimeProviderFieldValue, "DateTimeProvider field should be set correctly.");
        }