public void TestAddReviewToBookNoIncludeOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                context.Database.EnsureCreated();
                context.SeedDatabaseFourBooks();
            }

            using (var context = new EfCoreContext(options))
            {
                //ATTEMPT
                var book = context.Books.First();
                book.AddReview(5, "comment", "user", context);
                context.SaveChanges();

                //VERIFY
                book.Reviews.Count().ShouldEqual(1);
                context.Set <Review>().Count().ShouldEqual(3);
            }
        }
        public void TestMissingIncludeNotSafeOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <Chapter06Context>();

            using var context = new Chapter06Context(options);
            context.Database.EnsureCreated();
            var bookSetup = new BookNotSafe();

            bookSetup.Reviews.Add(new ReviewNotSafe());
            context.Add(bookSetup);
            context.SaveChanges();

            context.ChangeTracker.Clear();

            //ATTEMPT
            var book = context.Books //#A
                                     //... missing Include(x => x.Reviews) //#B
                       .First(x => x.Reviews.Any());

            //VERIFY
            book.Reviews.ShouldNotBeNull();
        }
Esempio n. 3
0
        public void TestCreateAuthorNameGoodNoValidationOk()
        {
            //SETUP
            var unique  = Guid.NewGuid().ToString();
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                context.Database.EnsureCreated();

                var utData  = context.SetupSingleDtoAndEntities <LocalAuthorDto>();
                var service = new CrudServices(context, utData.ConfigAndMapper);

                //ATTEMPT
                var author = new LocalAuthorDto {
                    Name = "Name", Email = unique
                };
                service.CreateAndSave(author);

                //VERIFY
                service.IsValid.ShouldBeTrue(service.GetAllErrors());
            }
        }
        public async Task TestCascadeDeleteCompanyOk()
        {
            //SETUP
            var userId  = Guid.NewGuid();
            var options = SqliteInMemory.CreateOptions <CascadeSoftDelDbContext>();

            using (var context = new CascadeSoftDelDbContext(options, userId))
            {
                context.Database.EnsureCreated();
                var company = Customer.SeedCustomerWithQuotes(context, userId);

                var config  = new ConfigCascadeDeleteWithUserId(context);
                var service = new CascadeSoftDelServiceAsync <ICascadeSoftDelete>(config);

                //ATTEMPT
                var status = await service.SetCascadeSoftDeleteAsync(company);

                //VERIFY
                status.IsValid.ShouldBeTrue(status.GetAllErrors());
                status.Result.ShouldEqual(1 + 4 + 4 + (4 * 4));
                status.Message.ShouldEqual("You have soft deleted an entity and its 24 dependents");
            }
        }
Esempio n. 5
0
        public void AuthorDecodedEntityClass()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                //ATTEMPT
                var decoded = new DecodedEntityClass(typeof(Author), context);

                //VERIFY
                decoded.EntityStyle.ShouldEqual(EntityStyles.Standard);
                decoded.PrimaryKeyProperties.Single().Name.ShouldEqual(nameof(Author.AuthorId));
                decoded.CanBeUpdatedViaMethods.ShouldBeFalse();
                decoded.CanBeUpdatedViaProperties.ShouldBeTrue();
                decoded.CanBeCreatedByCtorOrStaticMethod.ShouldBeFalse();
                decoded.PublicCtors.Length.ShouldEqual(1);
                decoded.PublicStaticCreatorMethods.Length.ShouldEqual(0);
                decoded.PublicSetterMethods.Length.ShouldEqual(0);
                decoded.PropertiesWithPublicSetter.Select(x => x.Name)
                .ShouldEqual(new [] { nameof(Author.AuthorId), nameof(Author.Name), nameof(Author.Email), nameof(Author.BooksLink) });
            }
        }
Esempio n. 6
0
        public void TestCorrectVersionOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <BookDbContext>();

            using var context = new BookDbContext(options);
            context.Database.EnsureCreated();

            var bookId = AddBookWithTwoReviewsToDatabase(context);

            context.ChangeTracker.Clear();

            //ATTEMPT
            var readBook = context.Books
                           .Include(x => x.Reviews)
                           .Single(x => x.BookId == bookId);
            var numReviews = readBook.Reviews.Count;

            //update the book based on the reviews count

            //VERIFY
            _output.WriteLine($"Book has {numReviews} reviews");
        }
        public async Task TestGetSoftDeletedEntriesEmployeeSoftDeletedOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <CascadeSoftDelDbContext>();

            using (var context = new CascadeSoftDelDbContext(options))
            {
                context.Database.EnsureCreated();
                var ceo = Employee.SeedEmployeeSoftDel(context);

                var config  = new ConfigCascadeDeleteWithUserId(context);
                var service = new CascadeSoftDelServiceAsync <ICascadeSoftDelete>(config);
                (await service.SetCascadeSoftDeleteAsync(ceo.WorksFromMe.First())).IsValid.ShouldBeTrue();

                //ATTEMPT
                var softDeleted = await service.GetSoftDeletedEntries <Employee>().ToListAsync();

                //VERIFY
                context.ChangeTracker.Clear();
                softDeleted.Count.ShouldEqual(1);
                softDeleted.Single().Name.ShouldEqual(ceo.WorksFromMe.First().Name);
            }
        }
        public void TestExtractCompanyId()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <CompanyDbContext>();

            using (var context = new CompanyDbContext(options, new FakeGetClaimsProvider("123*")))
            {
                context.Database.EnsureCreated();
                var rootCompanies = context.AddCompanyAndChildrenInDatabase();

                //ATTEMPT
                //                   -- West Coast --|--- San Fran ---
                var sfDress4U = rootCompanies.First().Children.Single().Children.First().Children.First();
                //                  -- West Coast --|------ LA ------
                var la = rootCompanies.First().Children.Single().Children.Last();


                //VERIFY
                rootCompanies.First().ExtractCompanyId().ShouldEqual(1);
                sfDress4U.ExtractCompanyId().ShouldEqual(1);
                la.ExtractCompanyId().ShouldEqual(1);
            }
        }
        public void TestNoBeforeSaveChangesMethodProvided()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <TestDbContext>();

            using (var context = new TestDbContext(options))
            {
                context.Database.EnsureCreated();

                //ATTEMPT
                context.Add(new UniqueEntity {
                    UniqueString = "bad word"
                });
                var status = context.SaveChangesWithValidation();

                //VERIFY
                status.HasErrors.ShouldBeFalse(status.GetAllErrors());
            }
            using (var context = new TestDbContext(options))
            {
                context.UniqueEntities.Count().ShouldEqual(1);
            }
        }
Esempio n. 10
0
        public void TestProjectBookTitleManyWithConfigOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                context.Database.EnsureCreated();
                context.SeedDatabaseFourBooks();

                var utData  = context.SetupSingleDtoAndEntities <BookTitleAndCount>();
                var service = new CrudServices(context, utData.ConfigAndMapper, new CreateNewDBContextHelper(() => new EfCoreContext(options)));

                //ATTEMPT
                var list = service.ReadManyNoTracked <BookTitleAndCount>().ToList();

                //VERIFY
                service.IsValid.ShouldBeTrue(service.GetAllErrors());
                list.Count.ShouldEqual(4);
                list.Select(x => x.Title).ShouldEqual(new[] { "Refactoring", "Patterns of Enterprise Application Architecture", "Domain-Driven Design", "Quantum Networking" });
                list.Select(x => x.ReviewsCount).ShouldEqual(new [] { 0, 0, 0, 2 });
            }
        }
        public void UpdateAuthorBadId()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                context.Database.EnsureCreated();
                context.SeedDatabaseFourBooks();

                //ATTEMPT
                var author = new Author
                {
                    AuthorId = 999999,
                    Name     = "Future Person 2"
                };
                context.Authors.Update(author);
                var ex = Assert.Throws <DbUpdateConcurrencyException>(() => context.SaveChanges());

                //VERIFY
                ex.Message.StartsWith("Database operation expected to affect 1 row(s) but actually affected 0 row(s).").ShouldBeTrue();
            }
        }
Esempio n. 12
0
        public void TestIncludeThenTwoLevelManuallyLoad()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                context.Database.EnsureCreated();
                context.SeedDatabaseFourBooks();

                var includeStrings = typeof(AddNewAuthorToBookUsingIncludesDto)
                                     .GetCustomAttributes(typeof(IncludeThenAttribute), true).Cast <IncludeThenAttribute>()
                                     .Select(x => x.IncludeNames).ToList();

                //ATTEMPT
                var query = ApplyAnyIncludeStringsAtDbSetLevel <AddReviewWithIncludeDto>(context.Books);
                var books = query.ToList();

                //VERIFY
                var names = books.SelectMany(x => x.AuthorsLink.Select(y => y.Author.Name)).ToArray();
                names.ShouldEqual(new String[] { "Martin Fowler", "Martin Fowler", "Eric Evans", "Future Person" });
            }
        }
        public void TestBookCountAuthorsOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                context.Database.EnsureCreated();
                context.SeedDatabaseFourBooks();
            }
            using (var context = new EfCoreContext(options))
            {
                //ATTEMPT
                var books = context.Books
                            .Include(book => book.AuthorsLink)
                            .ThenInclude(bookAuthor => bookAuthor.Author)
                            .ToList();

                //VERIFY
                books.Count.ShouldEqual(4);
                books.SelectMany(x => x.AuthorsLink.Select(y => y.Author)).Distinct().Count().ShouldEqual(3);
            }
        }
        public void TestRemoveReviewBookOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                context.Database.EnsureCreated();
                context.SeedDatabaseFourBooks();
            }

            using (var context = new EfCoreContext(options))
            {
                //ATTEMPT
                var book = context.Books.Include(x => x.Reviews).Single(x => x.Reviews.Count() == 2);
                book.RemoveReview(book.Reviews.LastOrDefault());
                context.SaveChanges();

                //VERIFY
                book.Reviews.Count().ShouldEqual(1);
                context.Set <Review>().Count().ShouldEqual(1);
            }
        }
        public void TestCreateValidDatabaseOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <MultiTenantDbContext>();

            using (var context = new MultiTenantDbContext(options, new MockGetClaimsProvider("user-id", 0, null)))
            {
                context.Database.EnsureCreated();

                //ATTEMPT
                var shop1 = new Shop {
                    Name = "Test1"
                };
                var shop2 = new Shop {
                    Name = "Test2"
                };
                context.AddRange(shop1, shop2);
                context.SaveChanges();

                //VERIFY
                context.Shops.IgnoreQueryFilters().Count().ShouldEqual(2);
            }
        }
        public async Task TestStopOnFirstBeforeHandlerThatHasAnError(bool stopOnFirst)
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <ExampleDbContext>();
            var config  = new GenericEventRunnerConfig
            {
                StopOnFirstBeforeHandlerThatHasAnError = stopOnFirst
            };
            var context = options.CreateAndSeedDbWithDiForHandlers <OrderCreatedHandler>(config: config);
            {
                var tax = new TaxRate(DateTime.Now, 6);
                context.Add(tax);

                //ATTEMPT
                tax.AddEvent(new EventTestBeforeReturnError());
                tax.AddEvent(new EventTestBeforeReturnError());
                var ex = await Assert.ThrowsAsync <GenericEventRunnerStatusException>(async() => await context.SaveChangesAsync());

                //VERIFY
                context.StatusFromLastSaveChanges.IsValid.ShouldBeFalse();
                context.StatusFromLastSaveChanges.Errors.Count.ShouldEqual(stopOnFirst ? 1 : 2);
            }
        }
Esempio n. 17
0
        public void TestCreateBookAndReadBackBeforeChangeTrackerClearOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <BookDbContext>();

            options.StopNextDispose();
            int bookId;

            using (var context = new BookDbContext(options))
            {
                context.Database.EnsureCreated();
                bookId = AddBookWithTwoReviewsToDatabase(context);
            }

            //ATTEMPT
            using (var context = new BookDbContext(options))
            {
                var readBook = context.Books.Single(x => x.BookId == bookId);

                //VERIFY
                _output.WriteLine($"Book has {readBook.Reviews?.Count.ToString() ?? "null"} reviews");
            }
        }
Esempio n. 18
0
        public void TestAverageDirectOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <BookDbContext>();

            using var context = new BookDbContext(options);
            context.Database.EnsureCreated();
            context.SeedDatabaseFourBooks();
            context.ChangeTracker.Clear();

            //ATTEMPT
            var query = context.Books.Select(p =>
                                             !p.Reviews.Any()
                    ? null
                    : (decimal?)p.Reviews.Select(q => q.NumStars).Average());

            _output.WriteLine(query.ToQueryString());
            var averages = query.ToList();

            //VERIFY
            averages.Count(x => x == null).ShouldEqual(3);
            averages.Count(x => x != null).ShouldEqual(1);
        }
        public async Task TestProjectBookTitleManyOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                context.Database.EnsureCreated();
                context.SeedDatabaseFourBooks();

                var utData  = context.SetupSingleDtoAndEntities <BookTitle>();
                var service = new CrudServicesAsync(context, utData.ConfigAndMapper);

                //ATTEMPT
                var list = await service.ReadManyWithPreQueryNoTracked <Book, BookTitle>(books =>
                                                                                         books.Where(x => x.AuthorsLink.Select(y => y.Author.Name).Contains("Martin Fowler"))).ToListAsync();

                //VERIFY
                service.IsValid.ShouldBeTrue(service.GetAllErrors());
                list.Count.ShouldEqual(2);
                list.Select(x => x.Title).ShouldEqual(new [] { "Refactoring", "Patterns of Enterprise Application Architecture" });
            }
        }
        public void TestSoftDeleteServiceSetSoftDeleteViaKeysNotFoundReturnsZero()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <SingleSoftDelDbContext>();

            using (var context = new SingleSoftDelDbContext(options))
            {
                context.Database.EnsureCreated();

                var config = new ConfigSoftDeleteWithUserId(context)
                {
                    NotFoundIsNotAnError = true
                };
                var service = new SingleSoftDeleteService <ISingleSoftDelete>(config);

                //ATTEMPT
                var status = service.SetSoftDeleteViaKeys <Book>(123);

                //VERIFY
                status.IsValid.ShouldBeTrue(status.GetAllErrors());
                status.Result.ShouldEqual(0);
            }
        }
        public async Task TestSeedCompanyWithQuotesQueryIgnoreOnIncludeOk()
        {
            //SETUP
            var userId  = Guid.NewGuid();
            var options = SqliteInMemory.CreateOptions <CascadeSoftDelDbContext>();

            using (var context = new CascadeSoftDelDbContext(options, userId))
            {
                context.Database.EnsureCreated();
                Customer.SeedCustomerWithQuotes(context, userId);
                Customer.SeedCustomerWithQuotes(context, userId, "company2");

                //ATTEMPT
                var companies   = context.Companies.ToList();
                var quotesQuery = context.Quotes.IgnoreQueryFilters()
                                  .Where(quote => companies.Select(company => company.Id).Contains(quote.Id));
                var quotes = quotesQuery.ToList();

                //VERIFY
                _output.WriteLine(quotesQuery.ToQueryString());
                companies.All(x => x.Quotes.Count == 4).ShouldBeTrue();
            }
        }
        public void TestSoftDeleteServiceSetSoftDeleteOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <SingleSoftDelDbContext>();

            using var context = new SingleSoftDelDbContext(options);
            context.Database.EnsureCreated();
            var book = context.AddBookWithReviewToDb();

            var config  = new ConfigSoftDeleteWithUserId(context);
            var service = new SingleSoftDeleteService <ISingleSoftDelete>(config);

            //ATTEMPT
            var status = service.SetSoftDelete(book);

            //VERIFY
            context.ChangeTracker.Clear();

            status.IsValid.ShouldBeTrue(status.GetAllErrors());
            status.Result.ShouldEqual(1);
            context.Books.Count().ShouldEqual(0);
            context.Books.IgnoreQueryFilters().Count().ShouldEqual(1);
        }
        public async Task TestGetSoftDeletedEntriesCompanyOk()
        {
            //SETUP
            var userId  = Guid.NewGuid();
            var options = SqliteInMemory.CreateOptions <CascadeSoftDelDbContext>();

            using (var context = new CascadeSoftDelDbContext(options, userId))
            {
                context.Database.EnsureCreated();
                var company = Customer.SeedCustomerWithQuotes(context, userId);

                var config  = new ConfigCascadeDeleteWithUserId(context);
                var service = new CascadeSoftDelServiceAsync <ICascadeSoftDelete>(config);
                var status  = await service.SetCascadeSoftDeleteAsync(company);

                //ATTEMPT
                var softDeleted = await service.GetSoftDeletedEntries <Customer>().ToListAsync();

                //VERIFY
                softDeleted.Count.ShouldEqual(1);
                softDeleted.Single().CompanyName.ShouldEqual(company.CompanyName);
            }
        }
        public void TestBookWithRelatedLinksWithoutIncludes()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using var context = new EfCoreContext(options);
            context.Database.EnsureCreated();
            context.SeedDatabaseFourBooks();

            //ATTEMPT
            var book = context.Books
                       .Single(p => p.Title
                               == "Quantum Networking");

            context.Books.Remove(book);
            context.SaveChanges();

            //VERIFY
            context.Books.Count().ShouldEqual(3);
            context.PriceOffers.Count().ShouldEqual(0);        //Quantum Networking is the only book with a priceOffer and reviews
            context.Set <Review>().Count().ShouldEqual(0);
            context.Set <BookAuthor>().Count().ShouldEqual(3); //three books left, each with a one author
        }
        public void TestCheckoutListBookWithPromotion()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                context.Database.EnsureCreated();
                context.SeedDatabaseFourBooks();

                //I select the last book, which has a promotion
                var mockCookieRequests = new MockHttpCookieAccess(BasketCookie.BasketCookieName, $"{Guid.NewGuid()},4,1");

                //ATTEMPT

                var service = new CheckoutListService(context, mockCookieRequests.CookiesIn);
                var list    = service.GetCheckoutList();

                //VERIFY
                list.Count.ShouldEqual(1);
                list.First().BookPrice.ShouldEqual(219);
            }
        }
        public void TestLoadOnlyBookAndDelete()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using var context = new EfCoreContext(options);
            context.Database.EnsureCreated();
            context.SeedDatabaseFourBooks();

            context.ChangeTracker.Clear();

            //ATTEMPT
            var book = context.Books
                       .Single(p => p.Title == "Quantum Networking");

            context.Remove(book);
            context.SaveChanges();

            //VERIFY
            context.Books.Count().ShouldEqual(3);
            context.Set <BookAuthor>().Count().ShouldEqual(3);
            context.Set <Review>().Count().ShouldEqual(0);
        }
        public async Task TestUpdateViaStatedMethodBad()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                context.Database.EnsureCreated();
                context.SeedDatabaseFourBooks();

                var utData  = context.SetupSingleDtoAndEntities <Dtos.ChangePubDateDto>();
                var service = new CrudServicesAsync(context, utData.ConfigAndMapper);

                //ATTEMPT
                var dto = new Dtos.ChangePubDateDto {
                    BookId = 4, PublishedOn = new DateTime(2000, 1, 1)
                };
                var ex = await Assert.ThrowsAsync <InvalidOperationException>(() => service.UpdateAndSaveAsync(dto, nameof(Book.AddReview)));

                //VERIFY
                ex.Message.ShouldStartWith("Could not find a method of name AddReview. The method that fit the properties in the DTO/VM are:");
            }
        }
Esempio n. 28
0
        public void TestIQueryableSelectBookListDtoOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                context.Database.EnsureCreated();
                context.SeedDatabaseFourBooks();

                //ATTEMPT
                var dtos = context.Books.MapBookToDto().OrderByDescending(x => x.BookId).ToList();

                //VERIFY
                dtos.First().BookId.ShouldNotEqual(0);
                dtos.First().Title.ShouldNotBeNull();
                dtos.First().Price.ShouldNotEqual(0);
                dtos.First().ActualPrice.ShouldNotEqual(dtos.Last().Price);
                dtos.First().AuthorsOrdered.Length.ShouldBeInRange(1, 100);
                dtos.First().ReviewsCount.ShouldEqual(2);
                dtos.First().ReviewsAverageVotes.ShouldEqual(5);
            }
        }
Esempio n. 29
0
        public void TestCreateAuthorNameNullNoValidationOk()
        {
            //SETUP
            var unique  = Guid.NewGuid().ToString();
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                context.Database.EnsureCreated();

                var utData  = context.SetupSingleDtoAndEntities <LocalAuthorDto>();
                var service = new CrudServices(context, utData.ConfigAndMapper);

                //ATTEMPT
                var author = new LocalAuthorDto {
                    Name = null, Email = unique
                };
                var ex = Assert.Throws <Microsoft.EntityFrameworkCore.DbUpdateException> (() => service.CreateAndSave(author));

                //VERIFY
                ex.InnerException?.Message.ShouldEqual("SQLite Error 19: 'NOT NULL constraint failed: Authors.Name'.");
            }
        }
        public void TestAddPromotionBookOk()
        {
            //SETUP
            var options = SqliteInMemory.CreateOptions <EfCoreContext>();

            using (var context = new EfCoreContext(options))
            {
                context.Database.EnsureCreated();
                context.SeedDatabaseFourBooks();
            }

            using (var context = new EfCoreContext(options))
            {
                //ATTEMPT
                var book   = context.Books.First();
                var status = book.AddPromotion(book.OrgPrice / 2, "Half price today");
                context.SaveChanges();

                //VERIFY
                status.HasErrors.ShouldBeFalse();
                book.ActualPrice.ShouldEqual(book.OrgPrice / 2);
            }
        }