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(); }
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"); } }
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) }); } }
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); } }
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(); } }
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); } }
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"); } }
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:"); } }
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); } }
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); } }