public async Task GetExpensesAccessTest() { using (var fixture = new GeldAppFixture()) { await fixture.Login("Hans"); await fixture.ExpectGetAsync("/api/account/Hans/export/tsv", HttpStatusCode.OK); await fixture.ExpectGetAsync("/api/account/Shared/export/tsv", HttpStatusCode.OK); await fixture.ExpectGetAsync("/api/account/Petra/expenses", HttpStatusCode.Unauthorized); await fixture.ExpectGetAsync("/api/account/Unknown/expenses", HttpStatusCode.Unauthorized); fixture.Logout(); await fixture.ExpectGetAsync("/api/account/Hans/export/tsv", HttpStatusCode.Unauthorized); await fixture.ExpectGetAsync("/api/account/Shared/export/tsv", HttpStatusCode.Unauthorized); await fixture.ExpectGetAsync("/api/account/Petra/expenses", HttpStatusCode.Unauthorized); await fixture.ExpectGetAsync("/api/account/Unknown/expenses", HttpStatusCode.Unauthorized); } }
public async Task CreateUpdateDeleteExpenseTest() { using (var fixture = new GeldAppFixture()) { await fixture.Login("Hans"); (await fixture.GetExpensesAsync("Hans")).Should().HaveCount(0); // Create. var cmd = new Expense(-100, "Ausgabe", "Essen", "Pizza").AsCommand("Hans"); (await fixture.Client.PostAsync("/api/account/Hans/expenses", cmd.AsContent())).ShouldBeOk(); var exp = (await fixture.GetExpensesAsync("Hans")).Single(); exp.Amount.Should().Be(-100); // Edit. exp.Amount = -200; (await fixture.Client.PutAsync($"/api/account/Hans/expense/{exp.Id}", exp.AsContent())).ShouldBeOk(); exp = (await fixture.GetExpensesAsync("Hans")).Single(); exp.Amount.Should().Be(-200); exp.Details.Should().Be("pidser", "PipelineBehaviors should be enabled :)"); // Get Single. exp = await fixture.GetExpenseAsync("Hans", exp.Id); exp.Amount.Should().Be(-200); // Delete. (await fixture.Client.DeleteAsync($"/api/account/Hans/expense/{exp.Id}")).ShouldBeOk(); (await fixture.GetExpensesAsync("Hans")).Should().HaveCount(0); } }
public async Task UsersShouldNotHaveAccessToForeignAccountsTest() { using (var fixture = new GeldAppFixture()) { await fixture.Login("Hans"); (await fixture.GetExpensesAsync("Hans")).Should().HaveCount(0); // Create. var cmd = new Expense(-100, "Ausgabe", "Essen", "Pizza").AsCommand("Hans"); (await fixture.Client.PostAsync("/api/account/Hans/expenses", cmd.AsContent())).ShouldBeOk(); var exp = (await fixture.GetExpensesAsync("Hans")).Single(); // Switch user. fixture.Logout(); await fixture.Login("Petra"); // Check foreign user actions. (await fixture.GetExpensesAsync("Petra")).Should().HaveCount(0); (await fixture.Client.GetAsync("/api/account/Hans/expenses")).StatusCode.Should().Be(HttpStatusCode.Unauthorized); (await fixture.Client.GetAsync($"/api/account/Hans/expense/{exp.Id}")).IsUnauthorized(); (await fixture.Client.PostAsync($"/api/account/Hans/expenses", exp.AsContent())).IsUnauthorized(); (await fixture.Client.PutAsync($"/api/account/Hans/expense/{exp.Id}", exp.AsContent())).IsUnauthorized(); (await fixture.Client.DeleteAsync($"/api/account/Hans/expense/{exp.Id}")).IsUnauthorized(); } }
public async Task HandleByCreatingExpenseTest() { using (var fixture = new GeldAppFixture()) { await fixture.Login("Hans"); // Import. var csv = File.ReadAllBytes("Import/dkb-import-test.csv"); await fixture.PostFileAsync("/api/account/Hans/import/csv", "csvFile", "file.csv", csv); // Check imported stuff. var imported = await fixture.GetAsync <ImportedExpense[]>("/api/account/Hans/imports/unhandled"); var importedExpense = imported.Single(); // No expenses yet. (await fixture.GetExpensesAsync("Hans")).Should().HaveCount(0); // Handle expense by creating new expense. await fixture.AddExpenseAsync("Hans", 10, "Cat", "Sub", modCmd : cmd => cmd.HandlesImportedExpenseId = importedExpense.Id); (await fixture.GetExpensesAsync("Hans")).Should().HaveCount(1); // No more unhandled imported expenses expected. imported = await fixture.GetAsync <ImportedExpense[]>("/api/account/Hans/imports/unhandled"); imported.Should().HaveCount(0); } }
public async Task ExpensePredictionTest() { using (var fixture = new GeldAppFixture()) { await fixture.Login("Hans"); for (var n = 0; n < CategoryPredictionService.MinimumNumberOfExpensesForPrediction; n++) { await fixture.AddExpenseAsync("Hans", -100, "Essen", "Pizza"); } for (var n = 0; n < CategoryPredictionService.MinimumNumberOfExpensesForPrediction; n++) { await fixture.AddExpenseAsync("Hans", -200, "Einkaufen", "Pizza"); } // Learn. var categoryPredictionService = fixture.GetService <ICategoryPredictionService>(); await categoryPredictionService.LearnCategoriesAsync(); // Verify. (await fixture.GetAsync <CategoryPredictionResult>("/api/account/Hans/categories/predict?amount=-100&created=2019-01-01&expenseDate=2019-01-01")) .Category.Should().Be("Essen"); (await fixture.GetAsync <CategoryPredictionResult>("/api/account/Hans/categories/predict?amount=-200&created=2019-01-01&expenseDate=2019-01-01")) .Category.Should().Be("Einkaufen"); } }
public async Task FullTest() { using (var fixture = new GeldAppFixture()) { await fixture.Login("Hans"); // Verify db is empty. var imported = await fixture.GetAsync <ImportedExpense[]>("/api/account/Hans/imports/unhandled"); imported.Length.Should().Be(0); // Import. var csv = File.ReadAllBytes("Import/dkb-import-test.csv"); await fixture.PostFileAsync("/api/account/Hans/import/csv", "csvFile", "file.csv", csv); // Check imported stuff. imported = await fixture.GetAsync <ImportedExpense[]>("/api/account/Hans/imports/unhandled"); var importedExpense = imported.Single(); importedExpense.Amount.Should().Be(-12.34M); importedExpense.BookingDay.Should().Be(DateTime.Parse("2019-10-25")); // Add some expenses. await fixture.AddExpenseAsync("Hans", -12.34M, "Wrong", "Subcategory", ex => ex.Date = importedExpense.BookingDay.AddDays(-100).Date); await fixture.AddExpenseAsync("Hans", -12.34M, "Wrong", "Subcategory", ex => ex.Date = importedExpense.BookingDay.AddDays(+100).Date); await fixture.AddExpenseAsync("Hans", -12, "Wrong", "Subcategory", ex => ex.Date = importedExpense.BookingDay.AddDays(-2).Date); await fixture.AddExpenseAsync("Hans", -12.34M, "Correct", "Subcategory", ex => ex.Date = importedExpense.BookingDay.AddDays(-2).Date); (await fixture.GetExpensesAsync("Hans")).Should().HaveCount(4); // Get related expenses. var relatedExpenses = await fixture.GetAsync <ExpenseViewModel[]>("/api/account/Hans/expenses?relatedToImportedExpense=" + importedExpense.Id); relatedExpenses.Should().HaveCount(1); var relatedExpense = relatedExpenses.Single(); relatedExpense.CategoryName.Should().Be("Correct"); // Handle expense by linking it. await fixture.ExpectPostAsync($"/api/account/Hans/import/link?importedExpenseId={importedExpense.Id}&relatedExpenseId={relatedExpense.Id}", HttpStatusCode.OK); (await fixture.GetExpensesAsync("Hans")).Should().HaveCount(4); imported = await fixture.GetAsync <ImportedExpense[]>("/api/account/Hans/imports/unhandled"); imported.Should().HaveCount(0); // Check link. var modifiedImportedExpense = fixture.QueryDb(db => db.ImportedExpenses.Include(ex => ex.Expense).Where(ex => ex.Expense != null).Single()); modifiedImportedExpense.Expense.Id.Should().Be(relatedExpense.Id); } }
public async Task GetSummaryTest() { using (var fixture = new GeldAppFixture()) { await fixture.Login("Admin"); var users = await fixture.GetAsync <UserSummary[]>("/api/users"); users.Should().HaveCount(3); users[0].Name.Should().Be("Hans"); users[1].Name.Should().Be("Petra"); users[2].Name.Should().Be("Admin"); } }
public async Task CsvExportTest() { using (var fixture = new GeldAppFixture()) { await fixture.Login("Hans"); var resp = await fixture.Client.GetAsync("/api/account/Hans/export/tsv"); resp.Content.Headers.ContentType.ToString().Should().Be("text/tab-separated-values"); resp.ShouldBeOk(); var content = await resp.Content.ReadAsStringAsync(); content.Should().StartWith("Id\tAccountId\tCategory"); } }
public async Task AuthorizationTests() { using (var fixture = new GeldAppFixture()) { await fixture.Login("Admin"); (await fixture.Client.GetAsync("/api/users")).ShouldBeOk(); fixture.Logout(); await fixture.Login("Hans"); (await fixture.Client.GetAsync("/api/users")).ShouldBeForbidden(); fixture.Logout(); } }
public async Task EnsureThatExpensesFromOtherAccountsDoNotLeak() { using (var fixture = new GeldAppFixture()) { await fixture.Login("Hans"); // Import. var csv = File.ReadAllBytes("Import/dkb-import-test.csv"); await fixture.PostFileAsync("/api/account/Hans/import/csv", "csvFile", "file.csv", csv); var hansImportedExpense = (await fixture.GetAsync <ImportedExpense[]>("/api/account/Hans/imports/unhandled")).Single(); // Add some expenses. await fixture.AddExpenseAsync("Hans", -12.34M, "Correct", "Subcategory", ex => ex.Date = hansImportedExpense.BookingDay.AddDays(-2).Date); // Get related expenses. var relatedExpenses = await fixture.GetAsync <ExpenseViewModel[]>("/api/account/Hans/expenses?relatedToImportedExpense=" + hansImportedExpense.Id); relatedExpenses.Should().HaveCount(1); relatedExpenses.Single().CategoryName.Should().Be("Correct"); // Login as different user. fixture.Logout(); await fixture.Login("Petra"); // Simple leak. await fixture.ExpectGetAsync("/api/account/Hans/expenses?relatedToImportedExpense=" + hansImportedExpense.Id, HttpStatusCode.Unauthorized); // Leak via related expenses. await fixture.PostFileAsync("/api/account/Petra/import/csv", "csvFile", "file.csv", csv); var petraImportedExpense = (await fixture.GetAsync <ImportedExpense[]>("/api/account/Petra/imports/unhandled")).Single(); var petraRelatedExpenses = await fixture.GetAsync <ExpenseViewModel[]>("/api/account/Petra/expenses?relatedToImportedExpense=" + petraImportedExpense.Id); petraRelatedExpenses.Should().BeEmpty(); // Leak via linking. await fixture.ExpectPostAsync($"/api/account/Hans/import/link?importedExpenseId={hansImportedExpense.Id}&relatedExpenseId={relatedExpenses.Single().Id}", HttpStatusCode.Unauthorized); await fixture.ExpectPostAsync($"/api/account/Petra/import/link?importedExpenseId={hansImportedExpense.Id}&relatedExpenseId={relatedExpenses.Single().Id}", HttpStatusCode.NotFound); // Leak via creating. await fixture.ExpectAddExpenseAsync("Hans", 10, "Cat", "Sub", modCmd : cmd => cmd.HandlesImportedExpenseId = hansImportedExpense.Id, expectedStatus : HttpStatusCode.Unauthorized); await fixture.ExpectAddExpenseAsync("Petra", 10, "Cat", "Sub", modCmd : cmd => cmd.HandlesImportedExpenseId = hansImportedExpense.Id, expectedStatus : HttpStatusCode.NotFound); } }
public async Task GetExpensesAccessTest() { using (var fixture = new GeldAppFixture()) { await fixture.Login("Hans"); await fixture.ExpectGetAsync("/api/account/Hans/imports/unhandled", HttpStatusCode.OK); fixture.Logout(); await fixture.ExpectGetAsync("/api/account/Hans/imports/unhandled", HttpStatusCode.Unauthorized); await fixture.Login("Petra"); await fixture.ExpectGetAsync("/api/account/Hans/imports/unhandled", HttpStatusCode.Unauthorized); } }
public async Task CreateDeleteCategoryTest() { using (var fixture = new GeldAppFixture()) { await fixture.Login("Hans"); var categories = await fixture.GetCategoriesAsync("Hans"); categories.Single().Name.Should().Be("Ausgaben"); // Create var cmd = new CreateCategoryCommand("Hans", "Einnahmen"); (await fixture.Client.PostAsync("/api/account/Hans/categories", cmd.AsContent())).ShouldBeOk(); categories = await fixture.GetCategoriesAsync("Hans"); categories.Skip(1).Single().Name.Should().Be("Einnahmen"); // Create sub (await fixture.Client.PutAsync("/api/account/Hans/category/Einnahmen/Aktien", null)).ShouldBeOk(); categories = await fixture.GetCategoriesAsync("Hans"); categories.Skip(1).Single().Subcategories.Single().Should().Be("Aktien"); // Predict (await fixture.Client.GetAsync("/api/account/Hans/categories/predict")).StatusCode.Should().Be(HttpStatusCode.NoContent); // Delete sub (await fixture.Client.DeleteAsync("/api/account/Hans/category/Einnahmen/Aktien")).ShouldBeOk(); categories = await fixture.GetCategoriesAsync("Hans"); categories.Skip(1).Single().Subcategories.Should().HaveCount(0); // Delete main (await fixture.Client.DeleteAsync("/api/account/Hans/category/Einnahmen")).ShouldBeOk(); categories = await fixture.GetCategoriesAsync("Hans"); categories.Should().HaveCount(1); } }
public async Task PostUserText(string user, string newUserName, bool shouldBeAllowed, bool shouldSucceed, bool createDefaultAccount) { using (var fixture = new GeldAppFixture()) { await fixture.Login(user); var result = await fixture.Client.PostAsync("/api/users", new CreateUserCommand(newUserName, "password", createDefaultAccount).AsContent()); if (!shouldBeAllowed) { result.ShouldBeForbidden(); return; } if (!shouldSucceed) { result.ShouldClientFail(); return; } var users = await fixture.GetAsync <UserSummary[]>("/api/users"); users.Should().HaveCount(4); users[0].Name.Should().Be("Hans"); users[1].Name.Should().Be("Petra"); users[2].Name.Should().Be("Admin"); users[3].Name.Should().Be("Neu"); if (createDefaultAccount) { users[3].Accounts.Single().Should().Be("Neu"); } else { users[3].Accounts.Should().BeEmpty(); } } }
public async Task EnsureAccessIsVerifiedTest() { using (var fixture = new GeldAppFixture()) { var testCmd = new CreateCategoryCommand("Hans", "Einnahmen"); // Test authenticated. await fixture.Login("Petra"); await fixture.ExpectGetAsync("/api/account/Hans/categories", HttpStatusCode.Unauthorized); await fixture.ExpectGetAsync("/api/account/Hans/categories/predict", HttpStatusCode.Unauthorized); (await fixture.Client.PostAsync("/api/account/Hans/categories", testCmd.AsContent())).IsUnauthorized(); (await fixture.Client.PostAsync("/api/account/Teal'C/categories", testCmd.AsContent())).IsUnauthorized(); (await fixture.Client.PutAsync("/api/account/Hans/category/Einnahmen/Aktien", null)).IsUnauthorized(); (await fixture.Client.PutAsync("/api/account/SamCarter/category/Einnahmen/Aktien", null)).IsUnauthorized(); (await fixture.Client.DeleteAsync("/api/account/Hans/category/Einnahmen/Aktien")).IsUnauthorized(); (await fixture.Client.DeleteAsync("/api/account/Hans/category/Einnahmen")).IsUnauthorized(); (await fixture.Client.DeleteAsync("/api/account/Hans/category/Schwarzgeld")).IsUnauthorized(); (await fixture.Client.DeleteAsync("/api/account/JackONeil/category/Schwarzgeld")).IsUnauthorized(); // Test unauthenticated. fixture.Logout(); await fixture.ExpectGetAsync("/api/account/Hans/categories", HttpStatusCode.Unauthorized); await fixture.ExpectGetAsync("/api/account/Hans/categories/predict", HttpStatusCode.Unauthorized); (await fixture.Client.PostAsync("/api/account/Hans/categories", testCmd.AsContent())).IsUnauthorized(); (await fixture.Client.PostAsync("/api/account/Teal'C/categories", testCmd.AsContent())).IsUnauthorized(); (await fixture.Client.PutAsync("/api/account/Hans/category/Einnahmen/Aktien", null)).IsUnauthorized(); (await fixture.Client.PutAsync("/api/account/SamCarter/category/Einnahmen/Aktien", null)).IsUnauthorized(); (await fixture.Client.DeleteAsync("/api/account/Hans/category/Einnahmen/Aktien")).IsUnauthorized(); (await fixture.Client.DeleteAsync("/api/account/Hans/category/Einnahmen")).IsUnauthorized(); (await fixture.Client.DeleteAsync("/api/account/Hans/category/Schwarzgeld")).IsUnauthorized(); (await fixture.Client.DeleteAsync("/api/account/JackONeil/category/Schwarzgeld")).IsUnauthorized(); } }
public async Task EnsureAccessIsVerifiedTest() { using (var fixture = new GeldAppFixture()) { await fixture.ExpectGetAsync("/api/account/Hans/charts/month-by-category", HttpStatusCode.Unauthorized); await fixture.ExpectGetAsync("/api/account/Hans/charts/expense-history", HttpStatusCode.Unauthorized); await fixture.ExpectGetAsync("/api/account/Hans/charts/revenue-history", HttpStatusCode.Unauthorized); await fixture.ExpectPostAsync("/api/account/Hans/charts/compare-category", new GetCompareCategoryChartQuery().AsContent(), HttpStatusCode.Unauthorized); await fixture.Login("Hans"); await fixture.ExpectGetAsync("/api/account/Hans/charts/month-by-category", HttpStatusCode.OK); await fixture.ExpectGetAsync("/api/account/Hans/charts/expense-history", HttpStatusCode.OK); await fixture.ExpectGetAsync("/api/account/Hans/charts/revenue-history", HttpStatusCode.OK); await fixture.ExpectPostAsync("/api/account/Hans/charts/compare-category", new GetCompareCategoryChartQuery().AsContent(), HttpStatusCode.OK); fixture.Logout(); await fixture.Login("Petra"); await fixture.ExpectGetAsync("/api/account/Hans/charts/month-by-category", HttpStatusCode.Unauthorized); await fixture.ExpectGetAsync("/api/account/Hans/charts/expense-history", HttpStatusCode.Unauthorized); await fixture.ExpectGetAsync("/api/account/Hans/charts/revenue-history", HttpStatusCode.Unauthorized); await fixture.ExpectGetAsync("/api/account/ColonelHogan/charts/revenue-history", HttpStatusCode.Unauthorized); await fixture.ExpectPostAsync("/api/account/Hans/charts/compare-category", new GetCompareCategoryChartQuery().AsContent(), HttpStatusCode.Unauthorized); } }
public async Task HandleTest() { using (var fixture = new GeldAppFixture()) { await fixture.Login("Hans"); // Import. var csv = File.ReadAllBytes("Import/dkb-import-test.csv"); await fixture.PostFileAsync("/api/account/Hans/import/csv", "csvFile", "file.csv", csv); // Check imported stuff. var imported = await fixture.GetAsync <ImportedExpense[]>("/api/account/Hans/imports/unhandled"); var importedExpense = imported.Single(); // Handle expense by linking it. await fixture.ExpectPostAsync($"/api/account/Hans/imports/{importedExpense.Id}/handle", HttpStatusCode.OK); // No more unhandled imported expenses expected. imported = await fixture.GetAsync <ImportedExpense[]>("/api/account/Hans/imports/unhandled"); imported.Should().HaveCount(0); } }