﻿using EzApp.Tests.Core.TestClasses;
using EzApp.Validation.Core.Errors;
using EzApp.Validation.Errors;
using Moq;
using NUnit.Framework;

namespace EzApp.Tests.UnitTests.Validation.ErrorTests.EzErrorCollectionCollectionTests
{
    [TestFixture]
    public class EzErrorCollectionCollection_IsValid
    {
        [Test]
        public void IfTEntityFieldErrorCollectionIsEzCommonEntityCreateFieldErrorCollection_AndNameErrorsIsNull_AndDescriptionErrorsIsNull_ShouldReturnTrue()
        {
            PerformTestForEzCommonEntityCreateFieldErrorCollection(null, null, true);
        }

        [Test]
        public void IfTEntityFieldErrorCollectionIsEzCommonEntityCreateFieldErrorCollection_AndNameErrorsIsValid_AndDescriptionErrorsIsNull_ShouldReturnTrue()
        {
            var mockNameErrors = new Mock<IEzErrorCollection>();
            mockNameErrors.Setup(x => x.IsValid).Returns(true);
            
            PerformTestForEzCommonEntityCreateFieldErrorCollection(mockNameErrors.Object, null, true);
        }

        [Test]
        public void IfTEntityFieldErrorCollectionIsEzCommonEntityCreateFieldErrorCollection_AndNameErrorsIsNull_AndDescriptionErrorsIsValid_ShouldReturnTrue()
        {
            var mockDescriptionErrors = new Mock<IEzErrorCollection>();
            mockDescriptionErrors.Setup(x => x.IsValid).Returns(true);
            
            PerformTestForEzCommonEntityCreateFieldErrorCollection(null, mockDescriptionErrors.Object, true);
        }

        [Test]
        public void IfTEntityFieldErrorCollectionIsEzCommonEntityCreateFieldErrorCollection_AndNameErrorsIsValid_AndDescriptionErrorsIsValid_ShouldReturnTrue()
        {
            var mockNameErrors = new Mock<IEzErrorCollection>();
            mockNameErrors.Setup(x => x.IsValid).Returns(true);

            var mockDescriptionErrors = new Mock<IEzErrorCollection>();
            mockDescriptionErrors.Setup(x => x.IsValid).Returns(true);
            
            PerformTestForEzCommonEntityCreateFieldErrorCollection(mockNameErrors.Object, mockDescriptionErrors.Object, true);
        }

        [Test]
        public void IfTEntityFieldErrorCollectionIsEzCommonEntityCreateFieldErrorCollection_AndNameErrorsIsInvalid_AndDescriptionErrorsIsNull_ShouldReturnFalse()
        {
            var mockNameErrors = new Mock<IEzErrorCollection>();
            mockNameErrors.Setup(x => x.IsValid).Returns(false);
            
            PerformTestForEzCommonEntityCreateFieldErrorCollection(mockNameErrors.Object, null, false);
        }

        [Test]
        public void IfTEntityFieldErrorCollectionIsEzCommonEntityCreateFieldErrorCollection_AndNameErrorsIsNull_AndDescriptionErrorsIsInvalid_ShouldReturnFalse()
        {
            var mockDescriptionErrors = new Mock<IEzErrorCollection>();
            mockDescriptionErrors.Setup(x => x.IsValid).Returns(false);
            
            PerformTestForEzCommonEntityCreateFieldErrorCollection(null, mockDescriptionErrors.Object, false);
        }

        [Test]
        public void IfTEntityFieldErrorCollectionIsEzCommonEntityCreateFieldErrorCollection_AndNameErrorsIsInvalid_AndDescriptionErrorsIsInvalid_ShouldReturnFalse()
        {
            var mockNameErrors = new Mock<IEzErrorCollection>();
            mockNameErrors.Setup(x => x.IsValid).Returns(false);

            var mockDescriptionErrors = new Mock<IEzErrorCollection>();
            mockDescriptionErrors.Setup(x => x.IsValid).Returns(false);
            
            PerformTestForEzCommonEntityCreateFieldErrorCollection(mockNameErrors.Object, mockDescriptionErrors.Object, false);
        }

        [Test]
        public void IfTEntityFieldErrorCollectionIsEzCommonEntityCreateFieldErrorCollection_AndNameErrorsIsValid_AndDescriptionErrorsIsInvalid_ShouldReturnFalse()
        {
            var mockNameErrors = new Mock<IEzErrorCollection>();
            mockNameErrors.Setup(x => x.IsValid).Returns(true);

            var mockDescriptionErrors = new Mock<IEzErrorCollection>();
            mockDescriptionErrors.Setup(x => x.IsValid).Returns(false);
            
            PerformTestForEzCommonEntityCreateFieldErrorCollection(mockNameErrors.Object, mockDescriptionErrors.Object, false);
        }

        [Test]
        public void IfTEntityFieldErrorCollectionIsEzCommonEntityCreateFieldErrorCollection_AndNameErrorsIsInvalid_AndDescriptionErrorsIsValid_ShouldReturnFalse()
        {
            var mockNameErrors = new Mock<IEzErrorCollection>();
            mockNameErrors.Setup(x => x.IsValid).Returns(false);

            var mockDescriptionErrors = new Mock<IEzErrorCollection>();
            mockDescriptionErrors.Setup(x => x.IsValid).Returns(true);
            
            PerformTestForEzCommonEntityCreateFieldErrorCollection(mockNameErrors.Object, mockDescriptionErrors.Object, false);
        }

        [Test]
        public void IfTEntityFieldErrorCollectionIsObjectWithNoErrorCollections_ShouldReturnTrue()
        {
            var sut = new EzErrorCollectionCollection<object>();

            var fieldErrors = new object();
            
            sut.Errors = fieldErrors;

            var result = sut.IsValid;

            Assert.That(result);
        }

        private void PerformTestForEzCommonEntityCreateFieldErrorCollection(IEzErrorCollection nameErrorCollection, IEzErrorCollection fieldErrorCollection, bool shoudlBeValid)
        {
            var sut = new EzErrorCollectionCollection<EzCommonEntityCreateFieldErrorCollection>();

            var fieldErrors = new TestCommonEntityCreateFieldErrorCollection();
            
            fieldErrors.Name = nameErrorCollection;
            fieldErrors.Description = fieldErrorCollection;
            sut.Errors = fieldErrors;

            var result = sut.IsValid;

            Assert.That(result == shoudlBeValid);
        }
    }
}
