using System;

using Domain;
using Services;
using RepositoryInterfaces;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using Moq;

namespace ServiceTests
{
    [TestClass]
    public class AccountServiceTests
    {
        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CannotCreateAccountServiceWithNullAccountRepository()
        {
            // Przygotuj.    

            // Wykonaj.
            new AccountService(null);

            // Zweryfikuj.
        }

        [TestMethod]
        public void AddingTransactionToAccountDelegatesToAccountInstance()
        {
            // Przygotuj.
            mockAccount.Setup(a => a.AddTransaction(200m)).Verifiable();
            mockRepository.Setup(r => r.GetByName("Konto firmowe")).Returns(mockAccount.Object);
            
            // Wykonaj.
            sut.AddTransactionToAccount("Konto firmowe", 200m);

            // Zweryfikuj.
            mockAccount.Verify();
        }

        [TestMethod]
        public void DoNotThrowWhenAccountIsNotFound()
        {
            // Wykonaj.
            sut.AddTransactionToAccount("Konto firmowe", 100m);

            // Zweryfikuj.
        }

        [TestMethod]
        public void AccountExceptionsAreWrappedInThrowServiceException()
        {
            // Przygotuj.
            mockAccount.Setup(a => a.AddTransaction(100m)).Throws<DomainException>();
            mockRepository.Setup(r => r.GetByName("Konto firmowe")).Returns(mockAccount.Object);

            // Wykonaj.
            try
            {
                sut.AddTransactionToAccount("Konto firmowe", 100m);
            }
            catch(ServiceException serviceException)
            {
                // Zweryfikuj.
                Assert.IsInstanceOfType(serviceException.InnerException, typeof(DomainException));
            }
        }
    
        [TestInitialize]
        public void Setup()
        {
            mockAccount = new Mock<Account>();
            mockRepository = new Mock<IAccountRepository>();
            sut = new AccountService(mockRepository.Object);
        }

        private Mock<Account> mockAccount;
        private Mock<IAccountRepository> mockRepository;
        private AccountService sut;
    }
}
