public async Task SaveChangesAsync_Commit_Changes_To_Database()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context, autoSave: false);

                repo.Add(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });
                repo.Add(new TestProduct()
                {
                    Id = 2, Name = "Test Product 02", Price = 20
                });

                await repo.SaveChangesAsync();
            }

            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context, autoSave: false);

                Assert.AreEqual(2, repo.FindAll().Count());
            }
        }
        public void Delete_Without_AutoSave_Does_Not_Commit_to_Database()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                repo.Add(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });
                repo.Add(new TestProduct()
                {
                    Id = 2, Name = "Test Product 02", Price = 20
                });
            }

            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context, autoSave: false);

                var product = repo.FindById(1);
                repo.Delete(product);
            }

            using (var context = new TestProductContext(options))
            {
                var repo     = new TestProductRepository(context, autoSave: false);
                var products = repo.FindAll();

                Assert.AreEqual(2, repo.FindAll().Count());
            }
        }
        public void Update_Without_AutoSave_Does_not_Save_to_database()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                repo.Add(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });
                repo.Add(new TestProduct()
                {
                    Id = 2, Name = "Test Product 02", Price = 20
                });
            }

            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context, autoSave: false);

                var product = repo.FindById(1);
                product.Name = "Modified Product";
                repo.Update(product);
            }

            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                var product = repo.FindById(1);

                Assert.AreEqual("Test Product 01", product.Name);
            }
        }
        public async Task DeleteAsync_Removes_Entity_From_Database()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                repo.Add(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });
                repo.Add(new TestProduct()
                {
                    Id = 2, Name = "Test Product 02", Price = 20
                });
            }

            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                var product = repo.FindById(1);
                await repo.DeleteAsync(product);

                Assert.AreEqual(1, repo.FindAll().Count());
            }
        }
        public void Update_Returns_Updated_Entity()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                repo.Add(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });
                repo.Add(new TestProduct()
                {
                    Id = 2, Name = "Test Product 02", Price = 20
                });
            }

            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                var product = repo.FindById(1);
                product.Name = "Modified Product";
                product      = repo.Update(product);

                Assert.AreEqual("Modified Product", product.Name);
            }
        }
        public async Task FindAllAsync_With_Paging_Detail_Skips_Records()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                repo.Add(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });
                repo.Add(new TestProduct()
                {
                    Id = 2, Name = "Test Product 02", Price = 20
                });
                repo.Add(new TestProduct()
                {
                    Id = 3, Name = "Test Product 03", Price = 10
                });
                repo.Add(new TestProduct()
                {
                    Id = 4, Name = "Test Product 04", Price = 20
                });
            }

            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                var pagingDetail = new PagingDetail(pageSize: 2, pageNumber: 1);

                var products = await repo.FindAllAsync(pagingDetail);

                Assert.AreEqual(2, products.Count());
            }
        }
        public void Filter_Returns_Filtered_Entities()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                repo.Add(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });
                repo.Add(new TestProduct()
                {
                    Id = 2, Name = "Test Product 02", Price = 30
                });
                repo.Add(new TestProduct()
                {
                    Id = 3, Name = "Test Product 03", Price = 15
                });
                repo.Add(new TestProduct()
                {
                    Id = 4, Name = "Test Product 04", Price = 50
                });
            }

            using (var context = new TestProductContext(options))
            {
                var repo     = new TestProductRepository(context);
                var products = repo.Filter(prod => prod.Price > 20).ToList();

                Assert.AreEqual(2, products.Count());
                Assert.AreEqual(2, products.ElementAt(0).Id);
                Assert.AreEqual(4, products.ElementAt(1).Id);
            }
        }
        public async Task FindByIdAsync_returns_entity()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                repo.Add(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });
                repo.Add(new TestProduct()
                {
                    Id = 2, Name = "Test Product 02", Price = 20
                });
            }

            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                var product = await repo.FindByIdAsync(1);

                Assert.AreEqual("Test Product 01", product.Name);
            }
        }
        public void Cleanup()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                foreach (var product in repo.FindAll().ToList())
                {
                    repo.Delete(product);
                }
            }
        }
        public void Add_Creates_A_New_Entry()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                repo.Add(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });
            }

            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);
                Assert.AreEqual(1, repo.FindAll().Count());
            }
        }
        public void Add_Without_Autosave_does_not_apply_changes_to_database()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context, false);

                repo.Add(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });
                repo.Add(new TestProduct()
                {
                    Id = 2, Name = "Test Product 02", Price = 20
                });
            }

            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);
                Assert.AreEqual(0, repo.FindAll().Count());
            }
        }
        public async Task AddAsync_Creates_New_Entry()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                await repo.AddAsync(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });

                await repo.AddAsync(new TestProduct()
                {
                    Id = 2, Name = "Test Product 02", Price = 20
                });
            }

            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);
                Assert.AreEqual(2, repo.FindAll().Count());
            }
        }
        public void FindAll_With_Negative_PageNumber_Returns_Empty_List()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                repo.Add(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });
            }

            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                var pagingDetail = new PagingDetail(pageSize: 1, pageNumber: -1);

                var products = repo.FindAll(pagingDetail);

                Assert.AreEqual(0, products.Count());
            }
        }
        public async Task FindAllAsync_Returns_Entities()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                repo.Add(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });
                repo.Add(new TestProduct()
                {
                    Id = 2, Name = "Test Product 02", Price = 20
                });
            }

            using (var context = new TestProductContext(options))
            {
                var repo     = new TestProductRepository(context);
                var products = await repo.FindAllAsync();

                Assert.AreEqual(2, products.Count());
            }
        }
        public void FindAll_With_Paging_Detail_Skips_Records()
        {
            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                repo.Add(new TestProduct()
                {
                    Id = 1, Name = "Test Product 01", Price = 10
                });
                repo.Add(new TestProduct()
                {
                    Id = 2, Name = "Test Product 02", Price = 20
                });
                repo.Add(new TestProduct()
                {
                    Id = 3, Name = "Test Product 03", Price = 10
                });
                repo.Add(new TestProduct()
                {
                    Id = 4, Name = "Test Product 04", Price = 20
                });
            }

            using (var context = new TestProductContext(options))
            {
                var repo = new TestProductRepository(context);

                var pagingDetail = new PagingDetail(pageSize: 2, pageNumber: 2);

                var products = repo.FindAll(pagingDetail);

                Assert.AreEqual(2, products.Count());
                Assert.AreEqual("Test Product 04", products.ElementAt(1).Name);
            }
        }