public async Task DeleteAsyncWithWhereClauseSuccessTestAsync()
        {
            //Given
            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                var repository    = new EfCoreAsyncAccountRepository(_databaseFactory);
                var listOfItems   = AccountEntityHelper.CreateEfCoreTestAccounts(3);
                var originalItems = await repository.GetAllAsync().ConfigureAwait(true);

                await repository.AddRangeAsync(listOfItems).ConfigureAwait(true);

                var allNewItems = await repository.GetAllAsync().ConfigureAwait(true);

                var newItems   = allNewItems as IList <Account> ?? allNewItems.ToList();
                var itemsAdded = newItems.Except(originalItems).ToList();

                //When
                var idsToDeleteAsync = itemsAdded.Select(x => x.AccountId);
                await repository.DeleteAsync(x => idsToDeleteAsync.Contains(x.AccountId)).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                var allItems = await repository.GetAllAsync().ConfigureAwait(true);

                //Then
                Assert.AreEqual(0, allItems.Except(newItems).Count(), "The items have not been DeleteAsyncd.");
            }
        }
        public async Task UpdateFailItemTestAsync()
        {
            //Given
            Account testAccount;
            var     repository = new EfCoreAsyncAccountRepository(_databaseFactory);

            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                testAccount = await repository.SaveAsync(AccountEntityHelper.CreateEfTestAccount()).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(false);
            }

            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                //When
                testAccount.CompanyName = null;
                await repository.SaveAsync(testAccount).ConfigureAwait(true);

                // ReSharper disable once AccessToDisposedClosure
                AsyncTestDelegate testDelegate = async() => await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                Assert.ThrowsAsync <DbUpdateException>(testDelegate);
            }

            //Then
            //GetAsync fresh database factory
            var finalDatabaseFactory = new EfCoreDatabaseFactoryBase <SharedLibraryContext>("SharedLibraryContext");
            var finalRepo            = new EfCoreAsyncAccountRepository(finalDatabaseFactory);
            var itemToCheck          = await finalRepo.GetAllAsync().ConfigureAwait(true);

            Assert.AreEqual(testAccount.CompanyName, itemToCheck.FirstOrDefault()?.CompanyName, "The compAnyAsync name was updated when it should not have been");
        }
        public async Task UpdateSuccessItemTestAsync()
        {
            //Given

            Account testAccount;
            var     repository = new EfCoreAsyncAccountRepository(_databaseFactory);

            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                testAccount = await repository.SaveAsync(AccountEntityHelper.CreateEfTestAccount()).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                //When
                testAccount.CompanyName = "Updated account";
                await repository.SaveAsync(testAccount).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);
            }

            //Then
            var finalRepo   = new EfCoreAsyncAccountRepository(_databaseFactory);
            var itemToCheck = await finalRepo.GetByIdAsync(testAccount.AccountId).ConfigureAwait(true);

            EqualityHelper.PropertyValuesAreEqual(itemToCheck, testAccount, new[] { "LastModified", "Contact" });
        }
        public async Task GetAsyncItemsViaStoredProcedureWithNoParameterButNoAccountsExistNotParameterisedTestAsync()
        {
            //Given
            //When
            var repository = new EfCoreAsyncAccountRepository(_databaseFactory);
            var items      = await repository.ExecuteQueryAsync <Account>("exec GetAccounts").ConfigureAwait(true);

            //Then
            Assert.AreEqual(0, items.ToList().Count, "Some items were returned where None should have been");
        }
        public async Task GetAsyncNoneAsyncSuccessTestAsync()
        {
            //Given
            var repository = new EfCoreAsyncAccountRepository(_databaseFactory);

            //When
            var hasNoneAsync = await repository.NoneAsync(x => false).ConfigureAwait(true);

            //Then
            Assert.IsTrue(hasNoneAsync, "No items should have been found.");
        }
        public async Task GetAsyncMAnyAsyncWithWhereClauseButNoneAsyncMatchSuccessTestAsync()
        {
            //Given
            var repository = new EfCoreAsyncAccountRepository(_databaseFactory);

            //When
            var shouldBeEmpty = await repository.GetManyAsync(x => false).ConfigureAwait(true);

            //Then
            Assert.IsFalse(shouldBeEmpty.Any(), "No item should have been found.");
        }
        public async Task GetAsyncAutocompleteItemsButNoneExistTestAsync()
        {
            //Given
            var repository = new EfCoreAsyncAccountRepository(_databaseFactory);

            //When
            var shouldBeEmpty = await repository.GetAutoCompleteItemsAsync(x => false, 1).ConfigureAwait(true);

            //Then
            Assert.IsFalse(shouldBeEmpty.Any(), "No item should have been found.");
        }
        public async Task ExecuteStoredProcedureWithIncorrectQueryTestAsync()
        {
            //Given
            var repository = new EfCoreAsyncAccountRepository(_databaseFactory);

            //When
            AsyncTestDelegate testDelegate = async() => await repository.ExecuteQueryAsync("exec GetAccountsFake").ConfigureAwait(true);

            //Then
            Assert.ThrowsAsync <SqlException>(testDelegate, "The expected exception was not thrown.");
        }
        public async Task GetAsyncByIdAsyncExceptionTestAsync()
        {
            //Given
            var repository = new EfCoreAsyncAccountRepository(_databaseFactory);

            //When
            var shouldBeNull = await repository.GetByIdAsync(-1).ConfigureAwait(true);

            //Then
            Assert.IsNull(shouldBeNull, "The item was found when it should have never existed.");
        }
        public void ExecuteStoredProcedureAsActionWithBrokenSyntaxTestAsync()
        {
            //Given
            var repository = new EfCoreAsyncAccountRepository(_databaseFactory);

            //When
            AsyncTestDelegate testDelegate = async() => await repository.ExecuteQueryAsActionAsync("exec DeleteAsyncAllAccountsFake").ConfigureAwait(true);

            //Then
            Assert.ThrowsAsync <SqlException>(testDelegate);
        }
        public async Task GetAllAsyncButNoneAsyncExistTestAsync()
        {
            //Given
            var repository = new EfCoreAsyncAccountRepository(_databaseFactory);

            //When
            var allItems = await repository.GetAllAsync().ConfigureAwait(true);

            //Then
            Assert.AreEqual(0, allItems.Count(), "Some items were returned where NoneAsync should have been");
        }
        public void AddListOfItemsFailsValidationTestAsync()
        {
            //Given
            var repository  = new EfCoreAsyncAccountRepository(_databaseFactory);
            var listOfItems = AccountEntityHelper.CreateEfCoreTestAccounts(3);

            listOfItems[1].CompanyName = null;

            //When
            AsyncTestDelegate asyncTestDelegate = async() => await repository.AddRangeAsync(listOfItems).ConfigureAwait(true);

            //Then
            Assert.ThrowsAsync <DbUpdateException>(
                asyncTestDelegate);
        }
        public async Task RetrieveItemByIdTestAsync()
        {
            //Given
            var repository = new EfCoreAsyncAccountRepository(_databaseFactory);

            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                var addedAccount = await repository.SaveAsync(AccountEntityHelper.CreateEfTestAccount()).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                //When
                var retrievedItem = await repository.GetByIdAsync(addedAccount.AccountId).ConfigureAwait(true);

                //Then
                EqualityHelper.PropertyValuesAreEqual(retrievedItem, addedAccount);
            }
        }
        public async Task AddListOfItemsTestAsync()
        {
            //Given
            var repository    = new EfCoreAsyncAccountRepository(_databaseFactory);
            var listOfItems   = AccountEntityHelper.CreateEfCoreTestAccounts(3);
            var originalItems = await repository.GetAllAsync().ConfigureAwait(true);

            //When
            await repository.AddRangeAsync(listOfItems).ConfigureAwait(true);

            //Then
            var allNewItems = await repository.GetAllAsync().ConfigureAwait(true);

            var itemsAdded = allNewItems.Except(originalItems).ToList();

            EqualityHelper.AssertListsAreEqual(itemsAdded, listOfItems,
                                               new[] { "AccountID", "LastModified", "Contacts" });
        }
        public async Task AddItemTestAsync()
        {
            //Given
            var repository = new EfCoreAsyncAccountRepository(_databaseFactory);

            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                //When
                var testAccount  = AccountEntityHelper.CreateEfTestAccount();
                var addedAccount = await repository.SaveAsync(testAccount).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                //Then
                Assert.AreNotEqual(addedAccount.AccountId, 0, "The account ID was not updated.");
                EqualityHelper.PropertyValuesAreEqual(addedAccount, testAccount, new[] { "AccountID" });
            }
        }
        public async Task GetAsyncItemsViaStoredProcedureWithNoParameterNotParameterisedTestAsync()
        {
            //Given
            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                var repository  = new EfCoreAsyncAccountRepository(_databaseFactory);
                var listOfItems = AccountEntityHelper.CreateEfCoreTestAccounts(3);
                await repository.AddRangeAsync(listOfItems).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                //When
                var items = await repository.ExecuteQueryAsync <Account>("exec GetAccounts").ConfigureAwait(true);

                //Then
                EqualityHelper.AssertListsAreEqual(items.OrderBy(x => x.CompanyName).ToList(), listOfItems.OrderBy(x => x.CompanyName).ToList(), new[] { "AccountID", "LastModified", "LastModifiedBy", "Contacts" });
            }
        }
        public async Task AddItemFailsValidationTestAsync()
        {
            //Given
            var repository  = new EfCoreAsyncAccountRepository(_databaseFactory);
            var testAccount = AccountEntityHelper.CreateEfTestAccount();

            testAccount.CompanyName = null;
            await repository.SaveAsync(testAccount).ConfigureAwait(true);

            //when
            AsyncTestDelegate asyncTestDelegate = async() =>
                                                  await new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory).CommitAsync()
                                                  .ConfigureAwait(true);

            //Then
            Assert.ThrowsAsync <DbUpdateException>(
                asyncTestDelegate);
        }
        public async Task GetAsyncNoneAsyncButSomeExistTestAsync()
        {
            //Given
            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                var repository  = new EfCoreAsyncAccountRepository(_databaseFactory);
                var listOfItems = AccountEntityHelper.CreateEfCoreTestAccounts(3);
                listOfItems[2].CompanyName = "TestReferenceOtherValue";
                await repository.AddRangeAsync(listOfItems).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                //When
                var hasNoneAsync = await repository.NoneAsync(x => x.CompanyName.Contains("TestReference")).ConfigureAwait(true);

                //Then
                Assert.IsFalse(hasNoneAsync, "NoneAsync were found when there should have been some.");
            }
        }
        public async Task GetAsyncAutoCompleteItemsTestAsync()
        {
            //Given
            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                var repository  = new EfCoreAsyncAccountRepository(_databaseFactory);
                var reference   = "TestReference";
                var listOfItems = GetAsyncItemsWithTwoItemsContainingTestReference(reference);
                await repository.AddRangeAsync(listOfItems).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                //When
                var item = await repository.GetAutoCompleteItemsAsync(x => x.CompanyName.Contains(reference), 1).ConfigureAwait(true);

                //Then
                EqualityHelper.PropertyValuesAreEqual(item.First(), listOfItems[0], new[] { "AccountID", "LastModified", "LastModifiedBy", "Contacts" });
            }
        }
        public async Task GetAsyncMAnyAsyncWithWhereClauseSuccessTestAsync()
        {
            //Given
            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                var repository  = new EfCoreAsyncAccountRepository(_databaseFactory);
                var reference   = "TestReference";
                var listOfItems = GetAsyncItemsWithTwoItemsContainingTestReference(reference);
                await repository.AddRangeAsync(listOfItems).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                //When
                var items = await repository.GetManyAsync(x => x.CompanyName.Contains(reference)).ConfigureAwait(true);

                //Then
                EqualityHelper.AssertListsAreEqual(items.OrderBy(x => x.CompanyName).ToList(), listOfItems.OrderBy(x => x.CompanyName).Take(2).ToList(), new[] { "AccountID", "LastModified", "LastModifiedBy", "Contacts" });
            }
        }
        public async Task ExecuteStoredProcedureAsActionTestAsync()
        {
            //Given
            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                var repository  = new EfCoreAsyncAccountRepository(_databaseFactory);
                var listOfItems = AccountEntityHelper.CreateEfCoreTestAccounts(3);
                await repository.AddRangeAsync(listOfItems).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                //When
                await repository.ExecuteQueryAsActionAsync("exec DeleteAllAccounts").ConfigureAwait(true);

                //Then
                var allItems = await repository.GetAllAsync().ConfigureAwait(true);

                Assert.AreEqual(0, allItems.ToList().Count(), "There are still items in the database.");
            }
        }
        public async Task GetAsyncWithWhereClauseSuccessTestAsync()
        {
            //Given
            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                var repository  = new EfCoreAsyncAccountRepository(_databaseFactory);
                var listOfItems = AccountEntityHelper.CreateEfCoreTestAccounts(3);
                listOfItems[2].CompanyName = "TestReferenceOtherValue";
                await repository.AddRangeAsync(listOfItems).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                //When
                var items = await repository.GetAsync(x => x.CompanyName.Contains("TestReference")).ConfigureAwait(true);

                //Then
                EqualityHelper.PropertyValuesAreEqual(items, listOfItems[2],
                                                      new[] { "AccountID", "LastModified", "LastModifiedBy", "Contacts" });
            }
        }
        public async Task DeleteAsyncItemSuccessTestAsync()
        {
            //Given
            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                //Given
                var repository  = new EfCoreAsyncAccountRepository(_databaseFactory);
                var testAccount = await repository.SaveAsync(AccountEntityHelper.CreateEfTestAccount()).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                //When
                await repository.DeleteAsync(testAccount).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                //Then
                var retrievedAccount = await repository.GetByIdAsync(testAccount.AccountId).ConfigureAwait(true);

                Assert.IsNull(retrievedAccount, "The account was not DeleteAsyncd.");
            }
        }
        public async Task GetAsyncItemsViaStoredProcedureWithParameterNotParameterisedTestAsync()
        {
            //Given
            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                var repository  = new EfCoreAsyncAccountRepository(_databaseFactory);
                var reference   = "TestReference";
                var listOfItems = GetAsyncItemsWithTwoItemsContainingTestReference(reference);
                await repository.AddRangeAsync(listOfItems).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                //When
                var filter = new SqlParameter("@CompanyName", SqlDbType.VarChar)
                {
                    Value = $"%{reference}%"
                };
                var items = await repository.ExecuteQueryAsync <Account>("exec GetAccounts @CompanyName", filter).ConfigureAwait(true);

                //Then
                EqualityHelper.AssertListsAreEqual(items.OrderBy(x => x.CompanyName).ToList(), listOfItems.OrderBy(x => x.CompanyName).Take(2).ToList(), new[] { "AccountID", "LastModified", "LastModifiedBy", "Contacts" });
            }
        }
        public async Task GetAllAsyncSuccessTestAsync()
        {
            //Given
            using (var efCoreAsyncUnitOfWork = new EfCoreAsyncUnitOfWork <SharedLibraryContext>(_databaseFactory))
            {
                var repository  = new EfCoreAsyncAccountRepository(_databaseFactory);
                var listOfItems = AccountEntityHelper.CreateEfCoreTestAccounts(3);
                listOfItems[0].CompanyName = "1";
                listOfItems[1].CompanyName = "2";
                listOfItems[2].CompanyName = "3";

                await repository.AddRangeAsync(listOfItems).ConfigureAwait(true);

                await efCoreAsyncUnitOfWork.CommitAsync().ConfigureAwait(true);

                //When
                var allItems = await repository.GetAllAsync().ConfigureAwait(true);

                //Then
                EqualityHelper.AssertListsAreEqual(allItems.OrderBy(x => x.CompanyName).ToList(), listOfItems.OrderBy(x => x.CompanyName).ToList(),
                                                   new[] { "AccountID", "LastModified", "LastModifiedBy", "Contacts" });
            }
        }