Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow typing comma separator for projected budget #523

Merged
merged 4 commits into from
Oct 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

- Fixed a bug where the email field dissappears in the user profile [#551](https://github.com/openkfw/TruBudget/issues/551)
- Fixed a bug where opening the user profile resulted in an error [#549](https://github.com/openkfw/TruBudget/issues/549)
- Allow typing a comma separator when editing a projected budget [#517](https://github.com/openkfw/TruBudget/issues/517)
- Projected budgets are shown in the language specific format [#559](https://github.com/openkfw/TruBudget/issues/559)
- Fixed a bug where the workflowitem budget changes its value unexpectly [#563](https://github.com/openkfw/TruBudget/issues/563)

# [1.13.0] - 2020-09-16

Expand Down
4 changes: 2 additions & 2 deletions api/src/service/domain/workflow/money.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ describe("An amount of money", () => {
assert.isTrue(isAmountOfMoney("- 123.45"));
});

it("must not contain a comma.", async () => {
it("match english notation.", async () => {
assert.isFalse(isAmountOfMoney("123,45"));
assert.isFalse(isAmountOfMoney("1,234.56"));
assert.isTrue(isAmountOfMoney("1,234.56"));
assert.isFalse(isAmountOfMoney("1.234,56"));
});

Expand Down
2 changes: 1 addition & 1 deletion api/src/service/domain/workflow/money.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Joi = require("joi");

export type MoneyAmount = string;
export const moneyAmountSchema = Joi.string().regex(/^-?\s?[0-9]+(\.[0-9]+)?$/, "amount of money");
export const moneyAmountSchema = Joi.string().regex(/^-?\s?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/, "amount of money");

export function isAmountOfMoney(value: string): boolean {
const { error } = Joi.validate(value, moneyAmountSchema);
Expand Down
194 changes: 190 additions & 4 deletions e2e-test/cypress/integration/project_budget_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,27 @@ describe("Project budget test", function() {
const organization1 = "Organization 1";
const organization2 = "Organization 2";
const amount = "1234";
const unformattedBudget = "1200";
const formattedBudgetEnglish = "1,200.00";
const wrongformattedBudgetEnglish = ["1.200,0", "1.", "1.1.1", "1,11.11"];
const formattedBudgetGerman = "1.200,00";
const wrongformattedBudgetGerman = ["1,200.0", "1,", "1.1.1", "1,11.11"];

const projectedBudgets = [
{
organization: organization1,
currencyCode: "EUR",
value: "111"
value: "1111"
},
{
organization: organization1,
currencyCode: "USD",
value: "222"
value: "2222"
},
{
organization: organization2,
currencyCode: "BRL",
value: "333"
value: "3333"
}
];
before(() => {
Expand All @@ -29,8 +35,8 @@ describe("Project budget test", function() {
cy.login();
cy.visit("/projects");
cy.server();
cy.route("GET", apiRoute + "/project.viewDetails*").as("viewDetails");
cy.route("GET", apiRoute + "/project.list*").as("listProjects");
cy.route("GET", apiRoute + "/project.viewDetails*").as("viewDetailsProject");
cy.route("POST", apiRoute + "/global.createProject").as("createProject");
cy.route("POST", apiRoute + "/project.createSubproject").as("createSubproject");
cy.route("POST", apiRoute + "/project.budget.deleteProjected").as("deleteBudget");
Expand Down Expand Up @@ -247,6 +253,186 @@ describe("Project budget test", function() {
});
});

it("Check language specific number format in projected budget table", function() {
cy.createProject("project budget test project", "project budget test", projectedBudgets).then(({ id }) => {
projectId = id;
cy.login("mstein", "test", { language: "de" });
cy.visit(`/projects/${projectId}`).wait("@viewDetailsProject");
cy.get("[data-test=project-projected-budget] tr").then(projectedBudgets => {
expect(projectedBudgets[1]).to.contain("1.111,00");
});
cy.login("mstein", "test", { language: "en" });
cy.visit(`/projects/${projectId}`).wait("@viewDetailsProject");
cy.get("[data-test=project-projected-budget] tr").then(projectedBudgets => {
expect(projectedBudgets[1]).to.contain("1,111.00");
});
});
});

it("The budget cannot be added if the input format is invalid [english format]", function() {
// Test with english format
cy.login("mstein", "test", { language: "en" });
cy.visit(`/projects`).wait("@listProjects");
cy.get("[data-test=create-project-button]").click();
cy.get("[data-test=organization-input]").type(organization1);
cy.get("[data-test=dropdown-currencies]").click();
cy.get("[data-value=EUR]").click();
// Type in a budgetamount
cy.get("[data-test=projected-budget] input")
.clear()
.type(unformattedBudget);
cy.get("[data-test=projected-budget]").should("not.contain", "Invalid format");
cy.get("[data-test=projected-budget] input")
.clear()
.type(formattedBudgetEnglish);
cy.get("[data-test=projected-budget]").should("not.contain", "Invalid format");
wrongformattedBudgetEnglish.forEach(b => {
cy.get("[data-test=projected-budget] input")
.clear()
.type(b);
cy.get("[data-test=projected-budget]").should("contain", "Invalid format");
});
});

it("The budget cannot be added if the input format is invalid [german format]", function() {
// Test with german format
cy.login("mstein", "test", { language: "de" });
cy.visit(`/projects`).wait("@listProjects");
cy.get("[data-test=create-project-button]").click();
cy.get("[data-test=organization-input]").type(organization1);
cy.get("[data-test=dropdown-currencies]").click();
cy.get("[data-value=EUR]").click();
// Type in a budgetamount
cy.get("[data-test=projected-budget] input")
.clear()
.type(unformattedBudget);
cy.get("[data-test=projected-budget]").should("not.contain", "Ungültiges Format");
cy.get("[data-test=projected-budget] input")
.clear()
.type(formattedBudgetGerman);
cy.get("[data-test=projected-budget]").should("not.contain", "Ungültiges Format");
wrongformattedBudgetGerman.forEach(b => {
cy.get("[data-test=projected-budget] input")
.clear()
.type(b);
cy.get("[data-test=projected-budget]").should("contain", "Ungültiges Format");
});
});

it("The inputfield to edit budgetamount shows an error if the input is invalid [english format]", function() {
cy.createProject("project budget test project", "project budget test", projectedBudgets).then(() => {
cy.login("mstein", "test", { language: "en" });
cy.visit(`/projects`).wait("@listProjects");
// Edit projected budgetamount
cy.get(`[data-test=pe-button]`)
.last()
.click();
cy.get("[data-test=edit-projected-budget]")
.first()
.click();
cy.get("[data-test=edit-projected-budget-amount] input")
.clear()
.type(unformattedBudget);
cy.get("[data-test=edit-projected-budget-amount]").should("not.contain", "Invalid format");
cy.get("[data-test=edit-projected-budget-amount] input")
.clear()
.type(formattedBudgetEnglish);
cy.get("[data-test=edit-projected-budget-amount]").should("not.contain", "Invalid format");
wrongformattedBudgetEnglish.forEach(b => {
cy.get("[data-test=edit-projected-budget-amount] input")
.clear()
.type(b);
cy.get("[data-test=edit-projected-budget-amount]").should("contain", "Invalid format");
});
});
});

it("The inputfield to edit budgetamount shows an error if the input is invalid [german format]", function() {
cy.createProject("project budget test project", "project budget test", projectedBudgets).then(() => {
cy.login("mstein", "test", { language: "de" });
cy.visit(`/projects`).wait("@listProjects");
// Edit projected budgetamount
cy.get(`[data-test=pe-button]`)
.last()
.click();
cy.get("[data-test=edit-projected-budget]")
.first()
.click();
cy.get("[data-test=edit-projected-budget-amount] input")
.clear()
.type(unformattedBudget);
cy.get("[data-test=edit-projected-budget-amount]").should("not.contain", "Ungültiges Format");
cy.get("[data-test=edit-projected-budget-amount] input")
.clear()
.type(formattedBudgetGerman);
cy.get("[data-test=edit-projected-budget-amount]").should("not.contain", "Ungültiges Format");
wrongformattedBudgetGerman.forEach(b => {
cy.get("[data-test=edit-projected-budget-amount] input")
.clear()
.type(b);
cy.get("[data-test=edit-projected-budget-amount]").should("contain", "Ungültiges Format");
});
});
});

it("The budget cannot be edited if the input format is invalid [english format]", function() {
cy.createProject("project budget test project", "project budget test", projectedBudgets).then(() => {
cy.login("mstein", "test", { language: "en" });
cy.visit(`/projects`).wait("@listProjects");
// Edit projected budgetamount
cy.get(`[data-test=pe-button]`)
.last()
.click();
cy.get("[data-test=edit-projected-budget]")
.first()
.click();
wrongformattedBudgetEnglish.forEach(b => {
cy.get("[data-test=edit-projected-budget-amount] input")
.clear()
.type(b);
cy.get("[data-test=edit-projected-budget-amount-done]").should("be.disabled");
});
cy.get("[data-test=edit-projected-budget-amount] input")
.clear()
.type(unformattedBudget);
cy.get("[data-test=edit-projected-budget-amount-done]")
.should("be.enabled")
.click();
cy.get("[data-test=saved-projected-budget-amount]")
.first()
.should("contain", formattedBudgetEnglish);
});
});

it("The budget cannot be edited if the input format is invalid [german format]", function() {
cy.createProject("project budget test project", "project budget test", projectedBudgets).then(() => {
cy.login("mstein", "test", { language: "de" });
cy.visit(`/projects`).wait("@listProjects");
// Edit projected budgetamount
cy.get(`[data-test=pe-button]`)
.last()
.click();
cy.get("[data-test=edit-projected-budget]")
.first()
.click();
wrongformattedBudgetGerman.forEach(b => {
cy.get("[data-test=edit-projected-budget-amount] input")
.clear()
.type(b);
cy.get("[data-test=edit-projected-budget-amount-done]").should("be.disabled");
});
cy.get("[data-test=edit-projected-budget-amount] input")
.clear()
.type(unformattedBudget);
cy.get("[data-test=edit-projected-budget-amount-done]")
.should("be.enabled")
.click();
cy.get("[data-test=saved-projected-budget-amount]")
.first()
.should("contain", formattedBudgetGerman);
});
});

it("Check if adding, editing and deleting projected budgets works together", function() {
const editedAmount = "522";
cy.get("[data-test=create-project-button]").click();
Expand Down
Loading